# How to Fuse Motion Sensor Data into AHRS Orientation (Euler/Quaternions)

## Overview

https://www.youtube.com/watch?v=Z0IpAMcecHE

[AHRS](http://en.wikipedia.org/wiki/Attitude_and_heading_reference_system) is an acronym for _ **Attitude and Heading Reference System** _, a system generally used for aircraft of any sort to determine _heading, pitch, roll_, _altitude_ etc.  
  
A basic IMU (Intertial Measurement Unit) generally provides raw sensor data, whereas an AHRS takes this data one step further, converting it into heading or direction in degrees.  
  
To help you get started designing your own AHRS system, or just to help convert raw sensor data into useful numbers that you can relate to the real world, we've created an Arduino library that lets you 'fuse' a range of common accelerometer/gyroscope/magnetometer sensor sets using a few different algorithms such as **Mahony** , **Madgwick** and **NXP Sensor Fusion**.

We recommend a Cortex M0 or faster/greater chipset - there's a lot of math and memory required so 4KB+ or RAM and 32 MHz+ speed helps for the fancier algorithms. That said, you _can_ do some basic fusion with an ATmega328p (Arduino UNO compatible). The data is output on the serial port for easy integration.

1. We'll start by verifying you can store calibrations on your chipset, and then calibrating your sensors.
2. Then we'll compile the AHRS library for your desired sensors and algorithm/
3. Finally we'll visualize the motion using a Web Serial API 3D model.

![](https://cdn-learn.adafruit.com/assets/assets/000/088/497/medium800thumb/sensors_Rabbit10DOF.jpg?1581966922)

# How to Fuse Motion Sensor Data into AHRS Orientation (Euler/Quaternions)

## Storing Calibrations

Every sensor will vary and need calibration. Some sensors have a 'range' for their error output, that helps us know if the sensor is functioning - but we still need to calibrate every sensor/board. One of the challenges with per-device-calibration is how to store that calibration

We could put the calibrations at the top of the Arduino sketch but we would have to re-compile it for each device, and its also easy to forget or lose the calibration.

So, instead, we try to store the calibration in **non-volatile memory** - that means _either_ EEPROM or external FLASH. We try to use external flash not internal flash, because internal flash can be erased and overwritten when we upload new code.

There's lots of different ways you could save calibrations - but to make things easiest we're going to stick to those two techniques. However, that means our board has to have some sort of NVM available! Here's what you can expect:

# EEPROM Memory (either real or simulated)

Some chips have EEPROM memory, this is a tiny amount of memory, that is separate from FLASH, where you can tuck maybe 256 bytes of data. There's two kinds of EEPROM, 'real' and 'simulated'. Real is, well, real! There's literally a chunk of memory inside the chip itself, and you'll see it mentioned in the datasheet as EEPROM.

The ATmega328 datasheet indicates that you can get up to 1KB of EEPROM (depends on which model of the chip you buy)

![sensors_image.png](https://cdn-learn.adafruit.com/assets/assets/000/088/445/medium640/sensors_image.png?1581725611)

Its not terribly common to see EEPROM in chips as you get to the more expensive models. Partially that's because they tend to have SPI Flash chips, but also cause they aren't that useful with larger chips. Either way, simulated EEPROM is when some internal SPI flash or external memory storage is dual-used as EEPROM. [For example, the ESP8266 uses the very end of the SPI flash chip that holds the program memory for EEPROM](https://github.com/esp8266/Arduino/tree/master/libraries/EEPROM).

Some chips with real EEPROM:

- ATmega328 (Arduino Uno/Metro/compatibles)
- ATmega32u4 (Arduino Leonardo/compatibles)
- ATmega2560 (Arduino Mega/compatibles)

Some chips with simulated EEPROM:

- [ESP8266](https://github.com/esp8266/Arduino/tree/master/libraries/EEPROM)
- [ESP32](https://github.com/espressif/arduino-esp32/tree/master/libraries/EEPROM)

# External SPI or QSPI memory

This is a separate chip used to store files, code, audio, graphics, etc. A lot of Adafruit products have SPI/QSPI memory in order to support CircuitPython. For example:

- All Adafruit nRF52840 boards
- All Adafruit SAMD51 ("M4") boards
- Many SAMD21 ("M0") boards (they'll often have Express in the name)

The reason we prefer external memory is that you can edit the file using any text editor, when CircuitPython (or another mass-storage enabled sketch) is loaded. Also, many of the above do not have EEPROM, so there's often not a choice.

The Feather M0 Express has an 8-SOIC SPI Flash chip highlighted to the left

![sensors_arduino_xtras.jpg](https://cdn-learn.adafruit.com/assets/assets/000/088/444/medium640/sensors_arduino_xtras.jpg?1581725201)

The only thing to watch out for is that the SPI FLASH must be _formatted_ with a filesystem - much like an SD card (altho, these days, SD cards come pre-formatted). A blank SPI Flash chip doesn't have anything on it.

# Manually Setting In Code

The least desirable, but sometimes necessary, option is to simply set the calibration at the top of your sketch/code. It's not something we like to do because its easy to lose the calibration, but it's _always_ an option!

# How to Fuse Motion Sensor Data into AHRS Orientation (Euler/Quaternions)

## Calibration Pre-Check

OK before we continue, we have to check that we are able to store calibration either in the **EEPROM** (ATmega328, 'm32u4, 'm2560, ESP8266, ESP32) or (Q) **SPI Flash** (most Adafruit M0, M4, nRF52840 boards)

# Library Installation

You'll need a few libraries, install them through the library manager!

![](https://cdn-learn.adafruit.com/assets/assets/000/088/450/medium800/sensors_image.png?1581873006)

Search for and install **Adafruit Sensor Calibration**

![](https://cdn-learn.adafruit.com/assets/assets/000/088/451/medium800/sensors_image.png?1581873089)

We strongly recommend using Arduino IDE 1.8.10+ because it will automatically install any dependancy libraries. If you have to install manually, grab **SdFat - Adafruit Fork** , **ArduinoJson** , **Adafruit SPIFlash** , **Adafruit Unified Sensor** as well ([see all dependencies here](https://github.com/adafruit/Adafruit_Sensor_Calibration/blob/master/library.properties))

# Compilation & Upload Check

Load **sensor\_calibration\_read** example - yes even though there is no calibration yet, this will let us verify the basics!

![](https://cdn-learn.adafruit.com/assets/assets/000/088/452/medium800/sensors_image.png?1581873247)

## EEPROM Storage

First we'll try loading it into a chip with EEPROM (an ATmega328-based Metro mini!)

![](https://cdn-learn.adafruit.com/assets/assets/000/088/453/medium800/sensors_image.png?1581873372)

Here's what you should look for:

- At the top you'll see that **Has EEPROM** is **1** - indicating we're using the internal EEPROM
- It's OK to see&nbsp; **No calibration loaded/found** (its a fresh chip!)
- The hex block after the **\*\*WARNING\*\*** is the raw calibration data stored. It's normal to see all 0x00 or 0xFF's if this is the first time running the program.
- Finally you'll see **Calibrations found:**
  - **Magnetic Hard Offset** should default to 0, 0, 0 (no offset)
  - **Magnetic Soft Offset** should default to 1, 0, 0, 0, 1, 0, 0, 0, 1 - note that _isn't_ all zeros! [It's a 3x3 identity matrix.](https://en.wikipedia.org/wiki/Identity_matrix)
  - **Gyro Zero Rate** Offset should default to 0, 0, 0 (no offset)
  - **Accel Zero Rate** Offset should default to 0, 0, 0 (no offset)

If you got this far, you're good! Go to the next page where we try to write calibrations

## Flash Storage

Here's what you can expect if you're using a chip with built in SPI/QSPI storage!

![](https://cdn-learn.adafruit.com/assets/assets/000/088/458/medium800/sensors_image.png?1581874500)

Here's what you should look for:

- At the top you'll see that **Has FLASH** is **1** - indicating we're using the external SPI Flash storage and that it successfully **Mounted Filesystem!**
- It's OK to see **Failed to read file** / **No calibration loaded/found** (we haven't made one yet!)
- Finally you'll see **Calibrations found:**
  - **Magnetic Hard Offset** should default to 0, 0, 0 (no offset)
  - **Magnetic Soft Offset** should default to 1, 0, 0, 0, 1, 0, 0, 0, 1 - note that _isn't_ all zeros! [It's a 3x3 identity matrix.](https://en.wikipedia.org/wiki/Identity_matrix)
  - **Gyro Zero Rate** Offset should default to 0, 0, 0 (no offset)
  - **Accel Zero Rate** Offset should default to 0, 0, 0 (no offset)

If you got this far, you're good! Go to the next page where we try to write calibrations

### Flash Unformatted Error

There's a chance, if you have a totally fresh board, that the flash is unformatted. In this case, when you upload the calibration reader, you'll get that the **JEDEC Chip ID** was read (it may vary), and that the flash size was detected - but `failed to mount newly formatted filesystem!`

![](https://cdn-learn.adafruit.com/assets/assets/000/088/455/medium800/sensors_image.png?1581874070)

If that happens, you have two ways to format the filesystem.

1. [Easiest way (we think) is to install CircuitPython](https://learn.adafruit.com/welcome-to-circuitpython/installing-circuitpython) - that's because you don't have to compile anything - simply enter the bootloader by click/double-clicking, and dragging over a UF2 file which will format the disk for you.
2. Or, you can load the SdFat formatter example in the Adafruit SPIFlash library:

![](https://cdn-learn.adafruit.com/assets/assets/000/088/456/medium800/sensors_image.png?1581874307)

Compile, upload and check the serial monitor for instructions

![](https://cdn-learn.adafruit.com/assets/assets/000/088/457/medium800/sensors_image.png?1581874419)

Now re-upload/re-try the sensor calibration reading demo

# How to Fuse Motion Sensor Data into AHRS Orientation (Euler/Quaternions)

## Calibration Write Check

OK now that we have our calibration storage worked out, lets try writing a calibration to disk!

Load up the other example, **sensor\_calibration\_write**

You'll see that we first load any existing calibration from non-volatile storage with `cal.loadCalibration()`. Then we set the calibrations we want to save with:

```python
// in uTesla
  cal.mag_hardiron[0] = -3.35;
  cal.mag_hardiron[1] = -0.74;
  cal.mag_hardiron[2] = -40.79;

  // in uTesla
  cal.mag_softiron[0] = 0.965;
  cal.mag_softiron[1] = 0.018;
  cal.mag_softiron[2] = 0.010;  
  cal.mag_softiron[3] = 0.018;
  cal.mag_softiron[4] = 0.960;
  cal.mag_softiron[5] = 0.003;  
  cal.mag_softiron[6] = 0.010;
  cal.mag_softiron[7] = 0.003;
  cal.mag_softiron[8] = 1.080;  

  // in Radians/s
  cal.gyro_zerorate[0] = 0.05;
  cal.gyro_zerorate[1] = -0.01;
  cal.gyro_zerorate[2] = -0.01;
```

which only changes the calibrations in temporary memory. Finally we run `cal.saveCalibration()` to write the calibration to permanent storage.

Upload this to your board.

# EEPROM Example

If you use a chip with EEPROM, you'll see similar output from the previous page, this time you will get to see the HEX data stored in EEPROM. We use the same format as [PJRC's NXPMotionSense](https://github.com/PaulStoffregen/NXPMotionSense) library so you will see `0x75, 0x54` as the first two bytes of the data chunk

![](https://cdn-learn.adafruit.com/assets/assets/000/088/460/medium800/sensors_image.png?1581875480)

# External FLASH example

If you use a chip with external flash, you should see similar output from the previous pre-check, but now it will write the calibration and also print out calibration file for you. You can see that it's stored in JSON format for easy parsing in Python or Arduino!

![](https://cdn-learn.adafruit.com/assets/assets/000/088/459/medium800/sensors_image.png?1581875267)

# Reading back calibration

OK no matter which way you calibrated, now you can load the calibration read example to see the saved values loaded up and printed out!

**For EEPROM:**

![](https://cdn-learn.adafruit.com/assets/assets/000/088/462/medium800/sensors_image.png?1581875714)

 **For external FLASH:**

![](https://cdn-learn.adafruit.com/assets/assets/000/088/463/medium800/sensors_image.png?1581875807)

# How to Fuse Motion Sensor Data into AHRS Orientation (Euler/Quaternions)

## Magnetic Calibration with MotionCal

Info: 

Warning: 

[Paul Stoffregen of PJRC](https://www.pjrc.com) wrote a really awesome cross-platform calibration helper that is great for doing both soft and hard iron magnetometer calibration. What's nice about it is you get a 3D visualization of the magnetometer output and it also tosses outliers and tells you how much spherical coverage you got!

# Step 1 - Download MotionCal Software

MotionCal is available for Mac, Windows and Linux, [you can download it from clicking here](https://www.pjrc.com/store/prop_shield.html).

Look for this section in the website:

![](https://cdn-learn.adafruit.com/assets/assets/000/087/416/medium800/sensors_image.png?1579824297)

And click the one that matches your computer the best.

# Step 2 - Configure & Upload the AHRS `calibration` Example

Next we have to tell the microcontroller board to send the magnetometer (and, if there is one, accelerometer and gyroscope) data out over serial in the right format.

Open up the `Adafruit_AHRS->calibration` example

![](https://cdn-learn.adafruit.com/assets/assets/000/088/464/medium800/sensors_image.png?1581886301)

At the top of the sketch you'll see a section where you can #include different sensor sets. Not every sensor-set is defined, but our most popular ones are! (You'll need sensors that are Adafruit\_Sensor compatible.)

Uncomment whichever kit you are using, and comment out the rest

![](https://cdn-learn.adafruit.com/assets/assets/000/088/465/medium800/sensors_image.png?1581886380)

Select your desired board & port from the **Tools** menu then click **Upload**

![sensors_image.png](https://cdn-learn.adafruit.com/assets/assets/000/087/420/medium640/sensors_image.png?1579825411)

Open up the serial console and check that the EEPROM/Filesystem was found. There may already be an existing calibration from prior experiments

![sensors_image.png](https://cdn-learn.adafruit.com/assets/assets/000/088/466/medium640/sensors_image.png?1581886646)

You'll then see a stream of data that looks like:  
`Raw:-58,-815,8362,76,-121,-95,-375,-159,-24`  
`Uni:-0.07,-0.98,10.00,0.0832,-0.1327,-0.1046,-37.50,-15.93,-2.50`

The first three numbers are accelerometer data - if you don't have an accelerometer, they will be 0

The middle three numbers are gyroscope data - if you don't have an gyroscope, they will be 0

The last three numbers are magnetometer, they should _definitely_ not be zeros!

![sensors_image.png](https://cdn-learn.adafruit.com/assets/assets/000/087/424/medium640/sensors_image.png?1579826324)

# Step 3 - Run MotionCal
 **Close the serial port** , and launch MotionCal

![sensors_image.png](https://cdn-learn.adafruit.com/assets/assets/000/087/425/medium640/sensors_image.png?1579826468)

Select the same COM / Serial port you used in Arduino

![sensors_image.png](https://cdn-learn.adafruit.com/assets/assets/000/087/426/medium640/sensors_image.png?1579826562)

Twist the board/sensor around. Make sure its not near any strong magnets (unless that's part of the installation)

![sensors_image.png](https://cdn-learn.adafruit.com/assets/assets/000/087/427/medium640/sensors_image.png?1579826638)

Keep twisting until you get a complete 'sphere' of red dots. At this point you are calibrated!

![sensors_motioncal_mag.png](https://cdn-learn.adafruit.com/assets/assets/000/087/428/medium640/sensors_motioncal_mag.png?1579826684)

In the top right you'll see the hard magnetic offsets at the top, the soft offsets in the middle and the field strength at the bottom.

In this case, the hard iron offsets are `[-31.25, 35.67, -116.44]`

**Take a screenshot of this display, so you can refer to these numbers later!**

MotionCal does not calibrate the accelerometer or gyroscope (yet) - so those offsets will be zero

![sensors_image.png](https://cdn-learn.adafruit.com/assets/assets/000/088/471/medium640/sensors_image.png?1581887169)

Eventually you'll have enough datapoints that the **Send Cal** &nbsp; button will activate (its grayed out by default).

Once you can click the button, try clicking it (we had to try a few times?)

![sensors_sendcal.png](https://cdn-learn.adafruit.com/assets/assets/000/088/468/medium640/sensors_sendcal.png?1581886980)

You'll see a large green checkmark once the calibration is saved and verified!

![sensors_calibrated.png](https://cdn-learn.adafruit.com/assets/assets/000/088/469/medium640/sensors_calibrated.png?1581887031)

# Step 4 - Verify Calibration

Re-load the **sensor\_calibration\_read** sketch to verify the calibration was saved!

![](https://cdn-learn.adafruit.com/assets/assets/000/088/472/medium800/sensors_image.png?1581888485)

# How to Fuse Motion Sensor Data into AHRS Orientation (Euler/Quaternions)

## Sensor Fusion Algorithms

There's 3 algorithms available for sensor fusion. **In general, the better the output desired, the more time and memory the fusion takes!**

Note that no algorithm is perfect - you'll always get some drift and wiggle because these sensors are not that great, but you should be able to get basic orientation data.

In order of complexity, they are:

## Mahony

This basic but effective algorithm will run on smaller chips like the '328p which makes it a great one for any platform.

[The original paper is available here](https://ieeexplore.ieee.org/document/4608934)

## Madgwick

This algorithm is very popular when you have faster Cortex M0, M3, M4 or faster chips. It isn't going to run on an atmega328p

[The original paper is available here](https://x-io.co.uk/open-source-imu-and-ahrs-algorithms/)

## NXP Sensor Fusion

This really nice fusion algorithm was designed by NXP and requires a bit of RAM (so it isnt for a '328p Arduino) but it has great output results.

As described by NXP:

> Sensor fusion is a process by which data from several different sensors are fused to compute something more than could be determined by any one sensor alone. An example is computing the orientation of a device in three-dimensional space. That orientation is then used to alter the perspective presented by a 3D GUI or game.  
>   
> The NXP Sensor Fusion Library for Kinetis MCUs (also referred to as Fusion Library or development kit) provides advanced functions for computation of device orientation, linear acceleration, gyro offset and magnetic interference based on the outputs of NXP inertial and magnetic sensors.  
> Version 7.00 of the development kit has the following features:
> 
> - Full source code for the sensor fusion libraries
> - IDE-independent software based upon the NXP Kinetis Software Development (KSDK).
> - The Fusion Library no longer requires Processor Expert for component configuration.
> - Supports both bare-metal and RTOS-based project development. Library code is now RTOS agnostic.
> - Optional standby mode powers down power-hungry sensors when no motion is detected.
> - 9-axis Kalman filters require significantly less MIPS to execute
> - All options require significantly less memory than those in the Version 5.xx library.
> - Full documentation including user manual and fusion data sheet
> 
> The fusion library is supplied under a liberal BSD open source license, which allows the user to employ this software with NXP MCUs and sensors, or those of our competitors. Support for issues relating to the default distribution running on NXP reference hardware is available via standard NXP support channels. Support for nonstandard platforms and applications is available at https://community.nxp.com/community/sensors/sensorfusion.

# How to Fuse Motion Sensor Data into AHRS Orientation (Euler/Quaternions)

## Let's fuse!

OK now that the sensors are calibrated, and you know what the options are for filters - its time to FUSE THOSE SENSORS! That's what we're here for, right?

Install the [Adafruit AHRS library](https://github.com/adafruit/Adafruit_AHRS) from the library manager. We strongly recommend using Arduino IDE 1.8.10+ because it will automatically install any dependancy libraries. [See all dependencies here](https://github.com/adafruit/Adafruit_AHRS/blob/master/library.properties)

![](https://cdn-learn.adafruit.com/assets/assets/000/088/496/medium800/sensors_image.png?1581966826)

Open up the **calibrated\_orientation** sketch

![](https://cdn-learn.adafruit.com/assets/assets/000/088/473/medium800/sensors_image.png?1581892748)

At the top of the sketch you'll see a section where you can `#include` different sensor sets. Not every sensor-set is defined, but our most popular ones are! (You'll need sensors that are `Adafruit_Sensor` compatible.)

Uncomment whichever kit you are using, and comment out the rest

```python
// uncomment one combo 9-DoF!
#include "LSM6DS_LIS3MDL.h"  // can adjust to LSM6DS33, LSM6DS3U, LSM6DSOX...
//#include "LSM9DS.h"           // LSM9DS1 or LSM9DS0
//#include "NXP_FXOS_FXAS.h"  // NXP 9-DoF breakout
```

Next, you can select which fusion algorithm you want to try:

```python
// pick your filter! slower == better quality output
//Adafruit_NXPSensorFusion filter; // slowest
Adafruit_Madgwick filter;  // faster than NXP
//Adafruit_Mahony filter;  // fastest/smalleset
```

By default we'll be performing a calculation every 10 ms (100Hz) and printing out 1 out of 10 calculations, however you can adjust those numbers up or down in this section as well as adding debug output

```python
#define FILTER_UPDATE_RATE_HZ 100
#define PRINT_EVERY_N_UPDATES 10
//#define AHRS_DEBUG_OUTPUT
```

OK now compile & upload!

Open the serial console and you'll see the sensors detected and then text like this

`Orientation: 180.82 -1.65 2.48`

These are the Euler angle outputs from the fusion algorithm

You'll also see text like

`Quaternion: 0.7545, 0.2937, 0.5858, -0.0356`

These are the quaternion outputs.

&nbsp;

![sensors_quatz.png](https://cdn-learn.adafruit.com/assets/assets/000/088/489/medium640/sensors_quatz.png?1581958931)

# Euler Angles

[Euler angles](http://en.wikipedia.org/wiki/Euler_angles "Link: http://en.wikipedia.org/wiki/Euler\_angles") describe orientation (in degrees) around a single reference point in three-dimensional space.  
  
Various names are employed for the three angles, but the most common terminology with aircraft is Roll (x), Pitch (y) and Yaw (z).  
  
The illustration below from the Wikipedia article on Euler angles should illustrate the concept clearly. You normally have both positive and negative angles (-180° to 180°) depending on the direction the airplane is tilted, with 0° in every direction corresponding to the airplane being perfectly aligned with each axis:

![](https://cdn-learn.adafruit.com/assets/assets/000/088/477/medium800/sensors_Yaw_Axis_Corrected.png?1581900390)

The print out of data is is in **Yaw** (Z) **Pitch** (Y) **Roll&nbsp;** (X) order, So if you get

`Orientation: 163.00 -4.90 33.56`

The yaw is 163 degrees, pitch is -4.90 degrees and roll is about 33.56 degrees. The sketch will keep updating itself with the latest values at whatever speed we've set in the example sketch.

Try twisting the sensor along each axis as printed on the sensor breakout/PCB to see the numbers change from -180~180 for each axis.

![sensors_image.png](https://cdn-learn.adafruit.com/assets/assets/000/088/478/medium640/sensors_image.png?1581900618)

# How to Fuse Motion Sensor Data into AHRS Orientation (Euler/Quaternions)

## WebSerial Visualizer

![](https://cdn-learn.adafruit.com/assets/assets/000/088/487/medium800thumb/sensors_99.jpg?1581956335)

Those three numbers are fine and good but we want to see what they mean in 3D space, right? Traditionally, a Processing sketch would be used to read the serial data and convert it to a 3D rotation - but [thanks to Web Serial API we can use any Chrome browser - a lot easier than installing Processing!](https://www.chromestatus.com/feature/6577673212002304)

## Step 1 - Install Chrome

[Start by installing the Chrome browser if you haven't yet.](https://www.google.com/chrome/)

## Step 2 - Enable Web Serial API if necessary
Info: 

At the time of this tutorial, you'll need to enable the Serial API, which is really easy.

Visit&nbsp; **chrome://flags** from within Chrome. Find and enable the **experimental web platform features**

![](https://cdn-learn.adafruit.com/assets/assets/000/088/479/medium800/sensors_image.png?1581901164)

Restart Chrome

## Step 3 - Visit the Adafruit 3D Model viewer

In Chrome, visit [https://adafruit.github.io/Adafruit\_WebSerial\_3DModelViewer/](https://adafruit.github.io/Adafruit_WebSerial_3DModelViewer/)

Verify you have **115200 Baud** selected (it only really matters for non-native-serial devices but might as well make sure its right)

Click **Connect**

![](https://cdn-learn.adafruit.com/assets/assets/000/088/480/medium800/sensors_image.png?1581901221)

When the security window pops up, pick the matching Serial/COM port for your board running the AHRS sketches. Make sure the serial port isn't open in Arduino or something

![](https://cdn-learn.adafruit.com/assets/assets/000/088/481/medium800/sensors_image.png?1581901272)

You'll see the serial port monitor on the bottom and a 3D bunny on the top. Try rotating and twisting the sensor to see it move!

![](https://cdn-learn.adafruit.com/assets/assets/000/088/488/medium800/sensors_image.png?1581956462)


## Featured Products

### Adafruit LSM6DS33 + LIS3MDL - 9 DoF IMU with Accel / Gyro / Mag

[Adafruit LSM6DS33 + LIS3MDL - 9 DoF IMU with Accel / Gyro / Mag](https://www.adafruit.com/product/4485)
_This item is discontinued - **you can grab** [Adafruit LSM6DS3 + LIS3MDL - Precision 9 DoF IMU](https://adafruit.com/products/5543) **instead!&nbsp;** _

Add motion,&nbsp;direction and orientation&nbsp;sensing to your Arduino project with this all-in-one 9 Degree...

No Longer Stocked
[Buy Now](https://www.adafruit.com/product/4485)
[Related Guides to the Product](https://learn.adafruit.com/products/4485/guides)
### Adafruit LSM6DS3TR-C + LIS3MDL - Precision 9 DoF IMU

[Adafruit LSM6DS3TR-C + LIS3MDL - Precision 9 DoF IMU](https://www.adafruit.com/product/5543)
Add high-quality motion,&nbsp;direction, and orientation&nbsp;sensing to your Arduino project with this all-in-one 9 Degree of Freedom (9-DoF) sensor with sensors from ST. This little breakout contains two chips that sit side-by-side to provide 9 degrees of full-motion data.

The board...

Out of Stock
[Buy Now](https://www.adafruit.com/product/5543)
[Related Guides to the Product](https://learn.adafruit.com/products/5543/guides)
### Adafruit LSM6DSOX + LIS3MDL - Precision 9 DoF IMU

[Adafruit LSM6DSOX + LIS3MDL - Precision 9 DoF IMU](https://www.adafruit.com/product/4517)
Add high-quality motion,&nbsp;direction, and orientation&nbsp;sensing to your Arduino project with this all-in-one 9 Degree of Freedom (9-DoF) sensor with sensors from ST. This little breakout contains two chips that sit side-by-side to provide 9 degrees of full-motion data.

The board...

In Stock
[Buy Now](https://www.adafruit.com/product/4517)
[Related Guides to the Product](https://learn.adafruit.com/products/4517/guides)
### Adafruit Feather nRF52840 Sense

[Adafruit Feather nRF52840 Sense](https://www.adafruit.com/product/4516)
The **Adafruit Feather Bluefruit Sense** takes our popular [Feather nRF52840 Express](https://www.adafruit.com/product/4062) and adds a smorgasbord of sensors to make a great wireless sensor platform. This Feather microcontroller comes with Bluetooth® Low Energy and...

In Stock
[Buy Now](https://www.adafruit.com/product/4516)
[Related Guides to the Product](https://learn.adafruit.com/products/4516/guides)
### Adafruit CLUE - nRF52840 Express with Bluetooth® LE

[Adafruit CLUE - nRF52840 Express with Bluetooth® LE](https://www.adafruit.com/product/4500)
Do you feel like you just don't have a CLUE? Well, we can help with that - get a CLUE here at Adafruit by picking up this sensor-packed development board. We wanted to build some projects that have a small screen and a lot of sensors. To make it compatible with existing projects, we made...

In Stock
[Buy Now](https://www.adafruit.com/product/4500)
[Related Guides to the Product](https://learn.adafruit.com/products/4500/guides)
### Adafruit 9-DOF Accel/Mag/Gyro+Temp Breakout Board - LSM9DS1

[Adafruit 9-DOF Accel/Mag/Gyro+Temp Breakout Board - LSM9DS1](https://www.adafruit.com/product/3387)
Add motion, direction and orientation sensing to your Arduino project with this all-in-one 9-DOF sensor. Inside the chip are three sensors, one is a classic 3-axis accelerometer, which can tell you which direction is down towards the Earth (by measuring gravity) or how fast the board is...

In Stock
[Buy Now](https://www.adafruit.com/product/3387)
[Related Guides to the Product](https://learn.adafruit.com/products/3387/guides)
### Adafruit Precision NXP 9-DOF Breakout Board

[Adafruit Precision NXP 9-DOF Breakout Board](https://www.adafruit.com/product/3463)
The NXP Precision 9DoF breakout combines two of the best motion sensors we've tested here at Adafruit: The **FXOS8700** 3-Axis accelerometer and magnetometer, and the **FXAS21002** 3-axis gyroscope.

These two sensors combine to make a nice 9-DoF kit, that...

No Longer Stocked
[Buy Now](https://www.adafruit.com/product/3463)
[Related Guides to the Product](https://learn.adafruit.com/products/3463/guides)
### Adafruit LSM6DSOX 6 DoF Accelerometer and Gyroscope

[Adafruit LSM6DSOX 6 DoF Accelerometer and Gyroscope](https://www.adafruit.com/product/4438)
Behold, the ST LSM6DSOX: The latest in a long line of quality Accelerometer+Gyroscope 6-DOF IMUs from ST.

This IMU sensor has 6 degrees of freedom - 3 degrees each of linear acceleration and angular velocity at varying rates within a respectable range. For the accelerometer:...

In Stock
[Buy Now](https://www.adafruit.com/product/4438)
[Related Guides to the Product](https://learn.adafruit.com/products/4438/guides)

## Related Guides

- [LSM6DSOX, ISM330DHC, & LSM6DSO32 6 DoF IMUs](https://learn.adafruit.com/lsm6dsox-and-ism330dhc-6-dof-imu.md)
- [LIS3MDL Triple-axis Magnetometer](https://learn.adafruit.com/lis3mdl-triple-axis-magnetometer.md)
- [Introducing Adafruit CLUE](https://learn.adafruit.com/adafruit-clue.md)
- [Adafruit Feather nRF52840 Sense](https://learn.adafruit.com/adafruit-feather-sense.md)
- [ST 9-DoF Combo Breakouts and Wings](https://learn.adafruit.com/st-9-dof-combo.md)
- [Adafruit LSM6DS3TR-C + LIS3MDL - Precision 9 DoF IMU](https://learn.adafruit.com/adafruit-lsm6ds3tr-c-lis3mdl-precision-9-dof-imu.md)
- [PyLeap BLE Controlled NeoPixels with CLUE](https://learn.adafruit.com/pyleap-ble-controlled-neopixels-with-clue.md)
- [PyBadger Event Badge](https://learn.adafruit.com/pybadger-event-badge.md)
- [Wirelessly Code your Bluetooth Device with CircuitPython](https://learn.adafruit.com/wirelessly-code-your-bluetooth-device-with-circuitpython.md)
- [Controlling Objects in Unity with a 9 DoF Sensor and Arduino](https://learn.adafruit.com/controlling-objects-in-unity-with-arduino.md)
- [Karel The Robot In CircuitPython](https://learn.adafruit.com/karel-the-robot-in-circuitpython.md)
- [CLUE Sensor Plotter in CircuitPython](https://learn.adafruit.com/clue-sensor-plotter-circuitpython.md)
- [Metronome CLUE](https://learn.adafruit.com/metronome-clue.md)
- [Bluetooth CLUE Robot Car using CircuitPython](https://learn.adafruit.com/bluetooth-clue-robot-car-using-circuitpython.md)
- [Clue Coffee Scale](https://learn.adafruit.com/clue-coffee-scale.md)
- [CircuitPython BLE Morse Code Chat](https://learn.adafruit.com/circuitpython-ble-wireless-morse-code-chat.md)
- [Adafruit LSM6DS33 6-DoF IMU Breakout](https://learn.adafruit.com/lsm6ds33-6-dof-imu-accelerometer-gyro.md)
- [Creative Inspiration Activity Generator](https://learn.adafruit.com/creative-inspiration-activity-generator.md)
- [BLE Vibration Bracelet](https://learn.adafruit.com/ble-vibration-bracelet.md)
- [Adafruit Feather M0 Express](https://learn.adafruit.com/adafruit-feather-m0-express-designed-for-circuit-python-circuitpython.md)
