SparkFun 9DoF IMU (ICM-20948) Breakout Hookup Guide

Pages
Contributors: Ell C, Liquid Soulder
Favorited Favorite 0

Introduction

The SparkFun 9DoF IMU Breakout incorporates all the amazing features of Invensense's ICM-20948 into a Qwiic-enabled breakout board replete with logic shifting and broken out GPIO pins for all your motion sensing needs. The ICM-20948 itself is an extremely low powered, I2C and SPI enabled 9-axis motion tracking device that is ideally suited for smartphones, tablets, wearable sensors, and IoT applications. Featuring a 3-Axis Gyroscope with four selectable ranges, a 3-Axis Accelerometer, again with four selectable ranges, a 3-axis compass with a wide range to ±4900 µT, and an on-board Digital Motion Processor, this little breakout can even detect the motion of invisibility cloaks. Not really. Just checking to see if you were still with me. But it is pretty amazing. Check it out:

SparkFun 9DoF IMU Breakout - ICM-20948 (Qwiic)

SparkFun 9DoF IMU Breakout - ICM-20948 (Qwiic)

SEN-15335
$16.95
1

In this hookup guide, we'll connect our sensor up to our Esp32 Thing Plus microcontroller and run a of quick (Qwiic) example to get you up and running with this fantastic board!

Required Materials

To follow along with this tutorial, you will need the following materials. You may not need everything though depending on what you have. Add it to your cart, read through the guide, and adjust the cart as necessary.

Tools

If you choose to utilize the broken out GPIO, you will need a soldering iron, solder, and general soldering accessories.

Soldering Iron - 60W (Adjustable Temperature)

Soldering Iron - 60W (Adjustable Temperature)

TOL-14456
$14.95
7
Solder Lead Free - 15-gram Tube

Solder Lead Free - 15-gram Tube

TOL-09163
$3.50
2

Suggested Reading

If you aren't familiar with the Qwiic system, we recommend reading here for an overview.

Qwiic Connect System
Qwiic Connect System

We would also recommend taking a look at the following tutorials if you aren't familiar with them.

How to Solder: Through-Hole Soldering

This tutorial covers everything you need to know about through-hole soldering.

Accelerometer Basics

A quick introduction to accelerometers, how they work, and why they're used.

I2C

An introduction to I2C, one of the main embedded communications protocols in use today.

Serial Terminal Basics

This tutorial will show you how to communicate with your serial devices using a variety of terminal emulator applications.

Hardware Overview

We've put a lot of effort into making this the most useful and versatile breakout for the ICM 20948. Let's take a closer look at all the special parts.

Sensor

At the heart of the board (metaphorically and geometrically) is the ICM 20948 from Invensense. This puppy packs the ability to measure up to 10 unique values (3 axes of acceleration, rotational rate, and magnetic strength data as well as an on-board temperature sensor). The sensor is placed dead-center between the four 4-40 stand-off mounting holes to drastically simplify computation in dynamics.

ICM 20948 Sensor

ICM 20948 Sensor

Level Shifters

The ICM is a fickle fellow - optionally allowing a 3.3V supply voltage but requiring I/O to work at 1.8V. This is just the price we pay for amazing technolojay (hey that rhymes). Since there aren't many popular development boards that run at the voltage of the future we've added high speed level shifting to each and every IO pin. These cool MOSFETS allow for bi-directional voltage translation up to the maximum SPI speed of the ICM - 7MHz - which will allow you to make inertial measurements with fantastic temporal resolution. Feel free to use the ICM IO anywhere from 1.8V to 5.5V!

Mosfets

TXS0108 Modules

Power

Input power on this board should be between 1.8-5.5V. The ICM is riding the wave of 1.8V level devices so we've included a built-in regulator to make it easy to interface with 3.3V or 5V microcontrollers. There is an LED on the front of the board that will light up when the board is powered correctly. You can disable the LED functionality by cutting the LED jumper on the back of the board. This is described in the Jumpers section below.

power LED on the front of the board

Power LED

Qwiic Connectors

There are two Qwiic connectors on the board such that you can daisy-chain the boards should you choose to do so. If you're unfamiliar with our Qwiic system, head on over to our Qwiic page to see the advantages! Of course, if you don't want to use Qwiic we've still broken out every pin on 0.1" spaced plated through-hole headers. You can find more information about these connections in the Headers section.

Qwiic Connectors

Qwiic Connectors

GPIO

For flexibility, we've broken out functional pins for both I2C and SPI. There are no modifications required to switch between I2C mode and SPI out of the box, but if the 'ADR' jumper on the back is closed SPI will be unavailable.

I2C Pin Labels SPI Pin Labels

Jumpers

Look at all those jumpers on the back of the board! Here's what they do:

Pullup Jumpers

  • I2C Pullup - Does nothing, the pullups are not populated on the board because the TXS0108 has them built-in
  • Aux Pullup - Cut these jumpers to disconnect the pullup resistors from the auxiliary I2C bus

LED Jumper

  • Cutting this jumper allows you to disable the LED functionality on the front of the board.

Address Jumper

  • When open (default) the address of the ICM is 0x69 and it is possible to use SPI communication. When soldered closed the address changes to 0x68. Closing the jumper prevents you from using SPI.
Pullup Jumpers LED Jumper I2C Address Jumper

Hardware Hookup

One of the many advantages of the Qwiic system is that hooking up your hardware is extremely simple. Simply grab a Qwiic cable and plug your 9DoF in!

Hooking up microcontroller to breakout via qwiic cable

Easy peasy lemon squeezy

If you'd like to use the broken out GPIO pins, things get a bit more complicated. That said, to make life a little easier we've organized them by function, and provided lots of labels. You'll first notice that one side has the text 'I2C' and the other side says 'SPI.' The labels on either side are those that apply to that kind of communication.

I2C Pin Labels SPI Pin Labels

Next, you'll see that on the left side are the main connections to the host microcontroller. When connecting I2C you'll have a 'No Connect' pin that serves as the chip select when using SPI. As noted before, there are no modifications required to switch between I2C mode and SPI out of the box. However if the 'ADR' jumper is closed SPI will be unavailable.

On the right side are connections to external sensors that can be controlled by the ICM, as well as the 'INT' and 'FSYNC' interrupt pins. The auxiliary I2C bus pins are level shifted to/from the 'VIN' level that you supply.

Breakout Board Pin Functions (SPI)
Breakout Pin Arduino Uno Esp32 Thing Plus Microcontroller Pin Requirements
MOSI 11 18 Data output of chosen SPI port
SCLK 13 5 Clock output of chosen SPI port
MISO 12 19 Data input of chosen SPI port
CS 2 2 An output pin to select the ICM for SPI
Breakout Board Pin Functions (I2C)
Breakout Pin Arduino Uno Esp32 Thing Plus Microcontroller Pin Requirements
DA SDA 23 Data line of chosen I2C port
CL SCL 22 Clock line of chosen I2C port
AD0 - - Optional - use to control I2C address from software
Breakout Board Pin Functions (Auxiliary I2C and Interrupts)
Breakout Pin Arduino Uno Esp32 Thing Plus Microcontroller Pin Requirements
ADA - - Data line of auxiliary I2C bus
ACL - - Clock line of auxiliary I2C bus
FSYNC - - Optional - synchronize measurements with a signal out from the microcontroller
INT - - Optional - respond to configurable interrupts in from the ICM

Software Setup and Example Code

Note: This example assumes you are using the latest version of the Arduino IDE on your desktop. If this is your first time using Arduino, please review our tutorial on installing the Arduino IDE. If you have not previously installed an Arduino library, please check out our installation guide.

In this example, we are using the SparkFun Esp32 Thing WROOM Plus. If you have not used this board before, head on over to the ESP32 Thing Plus Hookup Guide for a general overview, as well as information on getting set up with board definitions.

ESP32 Thing Plus Hookup Guide

March 7, 2019

Hookup guide for the ESP32 Thing Plus using the ESP32 WROOM's WiFi/Bluetooth system-on-chip in Arduino.

In order to use the ICM-20948 breakout, you'll need to install the SparkFun ICM-20948 Arduino Library. We recommend you install the library via the Arduino IDE by using the library manager and search for Sparkfun 9DoF IMU Breakout. Or you can download and manually install a zip of the library by clicking on the link below. For those who want to view the code, check out the GitHub repo.

Example 1

In this example, we've hookup up our ICM-20948 to an ESP32 Thing Plus using a short Qwiic cable.

Once you've installed the ICM-20948 library, load the first example sketch from File->Examples->SparkFun 9DoF IMU Breakout - ICM 20948 - Arduino Library->Arduino->Example1_Basics.

Where to find Example 1 in the Arduino IDE

Having a hard time seeing? Click the image for a closer look.

The very first thing you'll see in the code is the #include statement for the library. Alongside that is a convenient link that will help you get the library through the Arduino library manager. Next is a commented out #define statement called 'USE_SPI'. If instead you have chosen to connect your ICM with the SPI pins all you need to do is uncomment that line.

language:c
#include "ICM_20948.h"  // Click here to get the library: http://librarymanager/All#SparkFun_ICM_20948_IMU

//#define USE_SPI       // Uncomment this to use SPI

Up next is a short section where you can configure your particular setup. First of all if you need to change your serial port, e.g. if you're using a SAMD21 board, you can change the 'SERIAL_PORT' define ('SerialUSB' for SAMD21). You can do the same to change your I2C port or SPI port, depending on which you're using. When using I2C you have the ability to change the I2C address of the sensor with the Address 0 bit. By default it is '1' but you could change it to 0 if you've closed the 'ADR' jumper. When using SPI you need to specify a chip select pin - in the example we default to pin 2.

language:c
#define SERIAL_PORT Serial

#define SPI_PORT SPI    // Your desired SPI port.       Used only when "USE_SPI" is defined
#define CS_PIN 2        // Which pin you connect CS to. Used only when "USE_SPI" is defined

#define WIRE_PORT Wire  // Your desired Wire port.      Used when "USE_SPI" is not defined
#define AD0_VAL   1     // The value of the last bit of the I2C address. 
                        // On the SparkFun 9DoF IMU breakout the default is 1, and when 
                        // the ADR jumper is closed the value becomes 0

That's it for stuff you (might) need to do to set up the example! Now we'll just all hop in the bus, take a tour, and I'll point out items on your right and left.

The next little block creates either a ICM_20948_I2C or ICM_20948_SPI object called 'myICM'. Since they have the same name, and they both inherit from the grandaddy ICM_20948 class, we'll be able to use them interchangeably later on in the example.

language:c
#ifdef USE_SPI
  ICM_20948_SPI myICM;  // If using SPI create an ICM_20948_SPI object
#else
  ICM_20948_I2C myICM;  // Otherwise create an ICM_20948_I2C object
#endif

In the setup() function we have your standard Arduino initialization of your serial port, and then we have the last interface-dependent section. There you'll see the 'myICM' object being started up with the appropriate arguments for the chosen interface. This example shows all arguments being explicitly stated, but it is also possible to call the .begin() function with default arguments. The initialization will repeat with a delay until the device is successfully found. If it is not connecting try checking your wiring.

language:c
#ifdef USE_SPI
    SPI_PORT.begin();
    myICM.begin( CS_PIN, SPI_PORT ); 
#else
    WIRE_PORT.begin();
    WIRE_PORT.setClock(400000);
    myICM.begin( WIRE_PORT, AD0_VAL );
#endif

Here's a little trick for debugging the ICM - nearly all operations will update the internal 'myICM.status' value. You can check it directly (0 means all good, anything else is an error) or you can use the statusString() method to get the latest status in human-readable form.

language:c
    SERIAL_PORT.print( F("Initialization of the sensor returned: ") );
    SERIAL_PORT.println( myICM.statusString() );
    if( myICM.status != ICM_20948_Stat_Ok ){
      SERIAL_PORT.println( "Trying again..." );
      delay(500);
    }else{
      initialized = true;
    }

The last part of the sketch is the loop() where the sensor gets polled for new data, and that data gets pushed over the serial port. All the data is contained in the 'AGMT' structure, which stands for Accelerometer, Gyroscope, Magnetometer, and Temperature sensors. For convenience this sketch also includes functions (that are not part of the library) to print the results in a pretty format.

language:c
void loop() {

  if( myICM.dataReady() ){
    myICM.getAGMT();                // The values are only updated when you call 'getAGMT'
//    printRawAGMT( myICM.agmt );     // Uncomment this to see the raw values, taken directly from the agmt structure
    printScaledAGMT( myICM.agmt);   // This function takes into account the sclae settings from when the measurement was made to calculate the values with units
    delay(30);
  }else{
    Serial.println("Waiting for data");
    delay(500);
  }

}

When you open up your Serial Monitor, you should see something like the following:

Serial Output

Having a hard time seeing? Click the image for a closer look.

There ya have it! Now go ahead and hack it up.

Resources and Going Further

For more information on the ICM-20948, check out the links below:

Need more inspiration? Check out these related tutorials!

The Uncertain 7-Cube

The Uncertain 7-Cube is a non-committal, less-than-helpful, but also entirely honest fortune teller. Simply ask it a yes or no question, give it a nudge, and the 7-Cube will dutifully inform you that it doesn’t have all the facts and doesn’t feel comfortable making a guess.

LSM9DS1 Breakout Hookup Guide

A hookup guide for the LSM9DS1, which features a 3-axis accelerometer, 3-axis gyroscope, and 3-axis magnetometer. It's an IMU-in-a-chip!

MPU-9250 Hookup Guide

Get up and running with the MPU-9250 9-axis MEMS sensor.

Using the A111 Pulsed Radar Sensor with a Raspberry Pi

Learn how to download, build, and use the Acconeer A111 SDK with a Raspberry Pi! The tiny A111 pulsed coherent radar (PCR) adds high-precision, cutting-edge distance measurement for speed-, material-, motion-,or gesture-sensing projects! We’re not talking about simple ultrasonic, or even infrared, sensors here, but 60GHz radar!