Download PDF Parts List View on YouTube Download Code

Sensors are how our robots and other intelligent devices navigate. Whether you are building a self-driving rover or an intelligent quadcopter, knowing “which way is up” and “which way is North” is useful, sometimes even essential.

Today, we are looking at the Adafruit LSM303AGR, a 6-DOF (Six Degrees of Freedom) module that combines an accelerometer and magnetometer. We will hook it up to a microcontroller, learn to calibrate it correctly with the MotionCal tool, and finally build a compass with an OLED display.

Introduction

The Adafruit LSM303AGR is a compact, low-power multifunction MEMS sensor that combines a 3‑axis accelerometer and a 3‑axis magnetometer on a single breakout. It’s ideal for orientation, tilt, motion detection, and compass projects for makers, robots, drones, and wearables.

Today, we’ll explore how accelerometers and magnetometers work, wire up the sensor to a Seeeduino XIAO ESP32-S3 microcontroller, run through all the example sketches, perform proper magnetometer calibration, and build a complete digital compass with an OLED display. By the end, you’ll have the knowledge and practical experience to incorporate this powerful sensor into your own projects.

The LSM303AGR Multifunction Sensor

The LSM303AGR is a versatile motion-sensing module that combines two essential sensors in one compact package: a 3-axis accelerometer and a 3-axis magnetometer. This powerful combination makes it ideal for applications requiring orientation detection, navigation, and motion tracking.

The LSM303AGR represents the latest iteration in STMicroelectronics’ popular LSM303 series, which has been widely used in consumer electronics, IoT devices, and industrial applications. This updated version offers improved performance, lower power consumption, and enhanced features compared to its predecessors, like the LSM303DLHC.

The LSM303AGR is the modern replacement for older LSM303 variants, such as the LSM303DLHC. It pairs a MEMS (Micro-Electro-Mechanical Systems) capacitive accelerometer with a magnetometer optimized for low noise and low power.

It communicates over I²C or SPI and is available on an Adafruit breakout board with STEMMA QT / Qwiic connectors for easy I²C hookup.

Understanding the Sensor Components

Let’s take a look at the two sensors that are combined within the LSM303AGR module:

What is an Accelerometer?

An accelerometer measures acceleration forces in three perpendicular axes (X, Y, and Z). Importantly, it measures both dynamic acceleration (motion) and static acceleration (gravity). When sitting still on a table, an accelerometer primarily detects Earth’s gravity—approximately 9.8 m/s² or 1g. This constant gravitational reference allows accelerometers to determine orientation. Tilt the sensor, and the gravity vector distributes differently across the three axes, revealing the sensor’s angle relative to the ground.

The LSM303AGR uses MEMS (Micro-Electro-Mechanical Systems) capacitive sensing technology. Inside the chip, microscopic mechanical structures etched from silicon act as tiny spring-mass systems.

When acceleration occurs, a proof mass moves, changing the capacitance between fixed and moving plates. This capacitance change is measured and converted into acceleration values.

What is a Magnetometer?

A magnetometer measures the strength and direction of magnetic fields in three axes. In navigation applications, magnetometers detect Earth’s magnetic field, which ranges from 25 to 65 microTesla (µT) depending on your location. By determining which way the magnetic field points, we can find magnetic north—the fundamental principle behind all compasses, from ancient lodestones to modern digital versions.

The LSM303AGR’s magnetometer (the LIS2MDL component) uses magnetoresistive sensing technology. Certain materials change their electrical resistance when exposed to magnetic fields. By measuring these resistance changes in three perpendicular directions, the sensor can determine both the magnitude and direction of the magnetic field.

Combining the two sensors

When you combine an accelerometer and a magnetometer, you get a complete orientation sensing system. The accelerometer tells you which way is down (via gravity), and the magnetometer tells you which way is north. Together, they provide full 3D orientation awareness—perfect for navigation, augmented reality, robotics, and countless other applications.

Adafruit LSM303AGR Module

The Adafruit LSM303AGR module is probably the easiest way to experiment with this sensor.  The module incorporates the STMicroelectronics LSM303AGR sensor, a voltage regulator, and some support circuitry. It exposes the I²C connections (SDA and SCL) and several interrupts for both the accelerometer and magnetometer.

The module can operate with either 3.3 or 5-volt logic devices.

Here is the pinout of the module:

Note that the module includes orientation arrows indicating the directions of the X and Y axes. This is important to know when using the module.

Let’s see how we can use this sensor module with a microcontroller.

Hooking up the Sensor

The LSM303AGR is very easy to use with just about any microcontroller, as it is compatible with both 3.3-volt and 5-volt logic. For these experiments, I have chosen a Seeeduino XIAO ESP32-S3, but there is nothing in particular about the GSI microcontroller that makes it uniquely suitable for the LSM303AGR. You could easily substitute another microcontroller. If you do, you may have to alter the code to accommodate any different pinouts; otherwise, the code and hookup are identical.

Here is how I hooked up my Seeeduino XIAO ESP32-S3 to the LSM303AGR:

Now that we have it hooked up, we can begin to experiment with the two internal sensors. We will start with the accelerometer.

Using the Accelerometer

Let’s explore the accelerometer functionality. We’ll start by installing the necessary libraries, then run the example sketch to see the accelerometer in action.

Open the Arduino IDE and navigate to the Library Manager. Look for the Adafruit_LSM303_Accel library and install it. You will be prompted to install additional libraries, such as the Adafruit Unified Sensor library (which you may already have installed). Click to install all the required libraries.

Before diving into code, let’s understand what the accelerometer actually measures.

When an accelerometer sits motionless on a table, it’s not measuring zero acceleration—it’s measuring Earth’s gravity! The downward-facing axis reads approximately 9.8 m/s² (or 1g in convenient units). This might seem counterintuitive, but remember: an object at rest on Earth’s surface is being constantly accelerated upward by the table pushing against gravity.

If the accelerometer sits flat with the Z-axis pointing up:

  • X-axis: ~0 m/s² (no gravity component in horizontal plane)
  • Y-axis: ~0 m/s² (no gravity component in horizontal plane)
  • Z-axis: +9.8 m/s² (full gravity force pointing up through the sensor)

Tilt the sensor 45 degrees forward, and the gravity vector distributes:

  • X-axis: ~6.9 m/s² (gravity component pulling forward)
  • Y-axis: ~0 m/s²
  • Z-axis: ~6.9 m/s² (gravity component still pointing up)

The total magnitude remains constant: √(6.9² + 6.9²) ≈ 9.8 m/s²

When you move the sensor, you’ll see readings change as motion-induced acceleration adds to or subtracts from the gravitational constant. This is why accelerometers are perfect for detecting both orientation (via gravity) and motion (via changes in acceleration).

Accelerometer Code

A simple way to test the accelerometer is to use the sample sketch included with the Adafruit library. You will find it at: File → Examples → Adafruit LSM303 Accel → accelsensor.ino

Note that this code has been modified from the provided example; I have removed the lines that made it work only on an ESP8266.

Accelerometer Demo

Load the code to the XIAO and open the serial monitor. You should observe the acceleration in the X, Y, and Z axes.

Note that the Z-axis acceleration value is the acceleration of gravity.

Using the Magnetometer

Now we will turn our attention to the magnetometer in the LSM303AGR. While accelerometers are relatively forgiving, magnetometers require careful calibration to achieve accurate results. Let’s explore how the magnetometer works and how to use it effectively.

How Magnetometers Work (and why they need calibration)

Our planet acts like a giant bar magnet with field lines emerging from the magnetic south pole (near geographic north) and entering the magnetic north pole (near geographic south). This field is relatively weak—typically 25 to 65 microTesla (µT) depending on your location.

The magnetometer measures magnetic field strength in three perpendicular directions (X, Y, Z). By analyzing these three components, we can determine:

  • The direction to magnetic north
  • The strength of the local magnetic field
  • The presence of nearby magnets or ferromagnetic materials

Unlike gravity (which is remarkably constant), Earth’s magnetic field is easily overwhelmed by local magnetic sources:

  • Permanent magnets: Speakers, motors, magnetic clasps
  • Ferromagnetic materials: Iron, steel, nickel (distort the field without being magnetic themselves)
  • Electromagnetic interference: Power supplies, transformers, current-carrying wires

This sensitivity makes magnetometer calibration essential for accurate compass readings.

Note that the magnetic North and South poles are not the same as the geographical ones. To obtain the true direction, you will need to add a “deviation factor” to your compass readings. Here are a few examples:

  • New York: ~13° West
  •  San Francisco: ~14° East
  • London: ~0°
  • Sydney: ~12° East

This applies to both electronic and standard compasses.

Adafruit LIS2MDL Library

To work with the magnetometer in the LSM303AGR, we will use another Adafruit library, the Adafruit LIS2MDL library. As with the accelerometer library, you can install it using the Library Manager in the Arduino IDE.

This library also depends upon other libraries, which will be installed at the same time.

Magnetometer Calibration

To get useful data, we must calibrate the sensor to remove:

  • Hard Iron distortions: Permanent magnetic offsets (like magnetized screws or the sensor package itself).
  • Soft Iron distortions: Warping of the magnetic field caused by nearby ferrous metals.

We will use the MotionCal tool by Paul Stoffregen. To use it, we need to send raw data in a specific format to our computer. I have written a custom sketch for this.

Step 1: Upload the Calibration Sketch

Copy the code below (or use the ZIP file with all of the code) and upload it to your XIAO.

This sketch initializes the accelerometer and magnetometer, sets the magnetometer data rate to 100Hz for smoother readings, and streams data in the Raw:ax,ay,az,gx,gy,gz,mx,my,mz format. Since the LSM303AGR has no gyroscope, we send zeros for the middle three values.

Step 2: Run MotionCal

  • Close the Arduino Serial Monitor (MotionCal needs the port).
  • Open the MotionCal application on your PC.
  • Select your XIAO’s COM port.

You should see the sensor data visually represented as points in 3D space.

Rotate the sensor in all directions. A “figure-8” motion works best. Your goal is to fill the sphere with red dots.

Once the fit error is low (typically < 3%), look at the Magnetic Offset (Hard Iron) values on the screen. Write these down! You will need them for the compass.

Here is an example of a calibration that I did on my workbench, which is probably not a great place to do it, as there are several ferromagnetic sources nearby.

It took me about 15 minutes to complete the calibration.

Testing the Magnetometer

The Adafruit LIS2MDL library comes with a few example sketches. A good one to start with is the magsensor.ino sketch, which outputs values from all three magnetometer axes. You can find it at File → Examples → Adafruit LIS2MDL → magsensor.ino

This sketch reads the magnetometer and displays the field strength in microTesla.

A good way to see how the sensor works is to observe the output on the serial monitor and place a magnet near the sensor, as I have done in the illustration above. You will see the sensor respond instantly to the magnet’s magnetic field.

Simple Compass Function

Now that we understand both sensors and have calibrated the magnetometer, let’s create a basic compass. The fundamental principle is simple: Earth’s magnetic field points north, and by measuring this field in the horizontal plane, we can calculate heading.

Simple Compass Code

When we installed the Adafruit LIS2MDL library, four example sketches were added to the Arduino IDE. We have already looked at one of them; now we’ll use another to create a compass that displays in the serial monitor.

The example sketch is compass.ino. It can be found at File → Examples → Adafruit LIS2MDL → compass.ino.

Make sure to apply the magnetic offset values from the calibration procedure; this will improve the compass’s accuracy.

Simple Compass Demo

Load the sketch to the XIAO and observe the output on the serial monitor.

Move the board around, and you should see the direction indicated on the serial monitor.

This sketch can serve as the basis for a navigation system for robotics and other applications.

OLED Compass

We will expand upon the previous sketch and create a compass with the traditional circular display.  To keep it simple, we will use a small OLED display. For a more practical project, you could try substituting a larger display.

OLED Compass Hookup

The OLED hookup is straightforward. We will expand the circuit we have been working with and add an SSD1306 OLED display using its I²C bus connections.

Here is the final hookup:

Note that it is also possible to power the OLED using the 5-volt output from the Seeeduino XIAO ESP32-S3 board.

OLED Compass Code

Here is the code we will use for our OLED compass.  Note that you will need to add the Adafruit GFX and SSD1306 libraries to your Arduino IDE; they are available in the Library Manager.

Once again, remember to apply the offset values you obtained during calibration. You’ll see the three variables at the beginning of the code.

OLED Compass Demo

Load the code to your XIAO and reset the board. The display should prompt you to calibrate the compass by moving the sensor in a figure 8 pattern.

After that, the compass will display a circle with directional text.

Experiment by moving the compass around. Remember, in the arrangement I have with the solderless breadboard, the sensor is beside the display, so the movement will be erratic. In a permanent version, you would design it so the sensor was beneath the display and centered.

It’s a cute project, and with a larger display, it could be a practical instrument.

Conclusion

The LSM303AGR is a remarkably capable sensor that opens up numerous possibilities for motion-sensing and orientation-detection projects. By combining accelerometer and magnetometer data, you can create sophisticated applications that understand both linear movement and directional orientation.

The Adafruit module makes experimenting with this sensor very easy. Once you wrap your head around the fact that the LSM303AGR is really two distinct sensors in the same package, you’ll find that you can quickly create advanced projects, beyond a simple compass. Here are a few possibilities:

  • Tilt-Compensated Compass: Combine accelerometer and magnetometer data for accurate heading at any orientation
  • Motion-Activated Security: Detect movement and direction of approach
  • Robotic Navigation: Provide orientation feedback for autonomous robots
  • Camera Stabilization: Use accelerometer data for image stabilization algorithms
  • Gesture Recognition: Interpret specific motion patterns as commands
  • Structural Monitoring: Detect vibrations and orientation changes in structures
  • Wearable Devices: Create fitness trackers or smart clothing with motion sensing

Whatever you decide to build with this, I hope this article will be a valuable resource in your work with the LSM303AGR.

Parts List

Here are some components that you might need to complete the experiments in this article. Please note that some of these links may be affiliate links, and the DroneBot Workshop may receive a commission on your purchases. This does not increase the cost to you and is a method of supporting this ad-free website.

Adafruit LSM303AGR              Adafruit             Mouser

 

Resources

Code for this Article – All the code in one handy ZIP file

PDF Version – PDF Version of the article, packed in a ZIP file

MotionCal  – The MotionCal calibration utility by Paul Stoffregen

LSM303AGR Datasheet – STMicroElectronics datasheet for LSM303AGR

 

Find Your Way with the LSM303AGR Multifunction Sensor
Summary
Find Your Way with the LSM303AGR Multifunction Sensor
Article Name
Find Your Way with the LSM303AGR Multifunction Sensor
Description
Learn to use the LSM303AGR multifunction sensor from Adafruit. This tiny module combines an accelerometer and magnetometer, so you always know what direction you are heading in.
Author
Publisher Name
DroneBot Workshop
Publisher Logo

1 Comment
Oldest
Newest
Inline Feedbacks
View all comments
Bob Vines
18 hours ago

Bill

The link to download the PDF of the article is broken. Please fix it when you get a chance.

Thanks,

Bob