LSM9DS1 Breakout Hookup Guide

Pages
Contributors: jimblom
Favorited Favorite 9

Using the Arduino Library

To help demonstrate the library's functionality, a handful of examples are included which range from basic to more advanced. To begin to get a feel for the library's API, try loading up some of the other examples. The comments at the top of the sketch will instruct you on any extra hookup that may be required to use interrupts or other features.

On this page we'll quickly run down some of the more basic, fundamental concepts implemented by the library.

Setup Stuff

To enable the library, you'll need to include it, and you also need to include the SPI and Wire libraries:

language:c
#include <SPI.h> // SPI library included for SparkFunLSM9DS1
#include <Wire.h> // I2C library included for SparkFunLSM9DS1
#include <SparkFunLSM9DS1.h> // SparkFun LSM9DS1 library

Make sure the SPI and Wire includes are above the "SparkFunLSM9DS1" (even though you'll only be using one of the two interfaces).

Constructor

The constructor creates an instance of the LSM9DS1 class. Once you've created the instance, that's what you'll use to control the breakout from there on. This single line of code is usually placed in the global area of your sketch.

The constructor should be left without any parameters:

language:c
// Use the LSM9DS1 class to create an object. [imu] can be
// named anything, we'll refer to that throught the sketch.
LSM9DS1 imu;

Setting Up the Interface

The LSM9DS1 has tons of settings to be configured. Some are minute, others are more critical. The three most critical settings we'll need to configure are the communication interface and the device addresses. To configure these values, we'll make calls to the IMU's settings struct.

Here's an example that sets the IMU up for I2C mode, with the default (high) I2C addresses:

language:c
// SDO_XM and SDO_G are both pulled high, so our addresses are:
#define LSM9DS1_M   0x1E // Would be 0x1C if SDO_M is LOW
#define LSM9DS1_AG  0x6B // Would be 0x6A if SDO_AG is LOW
...
imu.settings.device.commInterface = IMU_MODE_I2C; // Set mode to I2C
imu.settings.device.mAddress = LSM9DS1_M; // Set mag address to 0x1E
imu.settings.device.agAddress = LSM9DS1_AG; // Set ag address to 0x6B

Alternatively, if you're using SPI mode, the imu.settings.device.mAddress and imu.settings.device.agAddress values become the chip select pins. For example, if you're using SPI mode with CS_AG connected to D10 and CS_M connected to D9, your setting configuration would look like this:

language:c
imu.settings.device.commInterface = IMU_MODE_SPI; // Set mode to SPI
imu.settings.device.mAddress = 9; // Mag CS pin connected to D9
imu.settings.device.agAddress = 10; // AG CS pin connected to D10

Configuring any value from the imu.settings.device can't take place in the global are of a sketch. If you get a compilation error, like 'imu' does not name a type, you may have those in the wrong place -- put them in setup().

begin()-ing and Setting Sensor Ranges

Once you've created the LSM9DS1 object, and configured its interface, call the begin() member function to initialize the IMU.

The begin() function will take the settings you've adjusted in the previous step, and attempt to communicate with and initialize the sensors. You can check the return value of begin() to verify whether or not the set up was successful -- it will return 0 if something goes wrong.

language:c
if (!imu.begin())
{
    Serial.println("Failed to communicate with LSM9DS1.");
    Serial.println("Looping to infinity.");
    while (1)
      ;
}

Once begin() has returned a success, you can start reading some sensor values!

Reading and Interpreting the Sensors

What good is the sensor if you can't get any data from it!? Here are the functions you'll need to get acceleration, rotation speed, and magnetic field strength data from the library.

readAccel(), readGyro(), and readMag()

These three functions -- readAccel(), readGyro(), and readMag() -- poll the LSM9DS1 to get the most up-to-date readings from each of the three sensors.

The read functions don't take any parameters, and they don't return anything, so how do you get that data? After the function runs its course, it'll update a set of three class variables, which will have the sensor data you desire. readAccel() will update ax, ay, and az, readGyro() will update gx, gy, and gz, and readMag() will update mx, my, and mz. Here's an example:

language:c
imu.readAccel(); // Update the accelerometer data
Serial.print(imu.ax); // Print x-axis data
Serial.print(", ");
Serial.print(imu.ay); // print y-axis data
Serial.print(", ");
Serial.println(imu.az); // print z-axis data

An example of reading and printing all three axes of accelerometer data.

Those values are all signed 16-bit integers, meaning they'll range from -32,768 to 32,767. That value doesn't mean much unless you know the scale of your sensor, which is where the next functions come into play.

calcAccel(), calcGyro(), and calcMag()

The library keeps track of each sensor's scale, and it implements these helper functions to make translating between the raw ADC readings of the sensor to actual units easy.

calcAccel(), calcGyro(), and calcMag() all take a single parameter -- a signed 16-bit integer -- and convert to their respective units. They all return a float value, which you can do with as you please.

Here's an example of printing calculated gyroscope values:

language:c
imu.readGyro(); // Update gyroscope data
Serial.print(imu.calcGyro(imu.gx)); // Print x-axis rotation in DPS
Serial.print(", ");
Serial.print(imu.calcGyro(imu.gy)); // Print y-axis rotation in DPS
Serial.print(", ");
Serial.println(imu.calcGyro(imu.gz)); // Print z-axis rotation in DPS

Setting Sensor Ranges and Sample Rates

Some of the more commonly altered attributes in the IMU are the sensor ranges and output data rates. These values can be configured, once again, by setting a value in the settings struct.

For example, to set the IMU's accelerometer range to ±16g, gyroscope to ±2000 °/s, and magnetometer to ±8 Gs, do something like this:

language:c
imu.settings.accel.scale = 16; // Set accel range to +/-16g
imu.settings.gyro.scale = 2000; // Set gyro range to +/-2000dps
imu.settings.mag.scale = 8; // Set mag range to +/-8Gs
imu.begin(); // Call begin to update the sensor's new settings

The output data rates are a bit more abstract. These values can range from 1-6, where 1 is the slowest update rate and 6 is the fastest.