LSM303C 6DoF Hookup Guide

Pages
Contributors: .Brent.
Favorited Favorite 1

Installing the Arduino Library

Download and Install the Library

Note: This code/library has been written and tested on Arduino IDE version 1.8.9. Otherwise, make sure you are using the latest stable 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.

Visit the GitHub repository to download the most recent version of the libraries, or click the link below to manually install:

The example Arduino code allows you to do things like read the magnetometer in all 3 axis, read the accelerometer in all 3 axis, and read the temperature of the die in Fahrenheit and Celsius.

Minimalist Example

Now, you can now run the example sketches. Open FileExamplesSparkFun LSM303C 6 DOF IMU Breakout Arduino LibraryMinimalistExample. This sketch is a simple as possible other than a little error checking. We'll be using the example in I2C mode.

The setup function configures the Arduino's serial port to 57600 baud and configures the LSM303C to some reasonable defaults.


LSM303C myIMU;

void setup() {

  Wire.begin();//set up I2C bus, comment out if using SPI mode
  Wire.setClock(400000L);//clock stretching, comment out if using SPI mode

  Serial.begin(57600);//initialize serial monitor, maximum reliable baud for 3.3V/8Mhz ATmega328P is 57600

  if (myIMU.begin() != IMU_SUCCESS)
  {
    Serial.println("Failed setup.");
    while(1);
  }
}

The loop function sequentially prints out the x, y, and z vales measured by the accelerometer, then the gyroscope, and then the magnetometer. This is followed up by the temperature of the die in degrees Celsius and Fahrenheit. All values are rounded to 4 digits past the decimal point.


void loop()
{
  //Get all parameters
  Serial.print("\nAccelerometer:\n");
  Serial.print(" X = ");
  Serial.println(myIMU.readAccelX(), 4);
  Serial.print(" Y = ");
  Serial.println(myIMU.readAccelY(), 4);
  Serial.print(" Z = ");
  Serial.println(myIMU.readAccelZ(), 4);

  // Not supported by hardware, so will return NAN
  Serial.print("\nGyroscope:\n");
  Serial.print(" X = ");
  Serial.println(myIMU.readGyroX(), 4);
  Serial.print(" Y = ");
  Serial.println(myIMU.readGyroY(), 4);
  Serial.print(" Z = ");
  Serial.println(myIMU.readGyroZ(), 4);

  Serial.print("\nMagnetometer:\n");
  Serial.print(" X = ");
  Serial.println(myIMU.readMagX(), 4);
  Serial.print(" Y = ");
  Serial.println(myIMU.readMagY(), 4);
  Serial.print(" Z = ");
  Serial.println(myIMU.readMagZ(), 4);

  Serial.print("\nThermometer:\n");
  Serial.print(" Degrees C = ");
  Serial.println(myIMU.readTempC(), 4);
  Serial.print(" Degrees F = ");
  Serial.println(myIMU.readTempF(), 4);
  
  delay(1000);
}

Here is some sample output:


Accelerometer:
 X = 56.7017
 Y = 42.7856
 Z = 946.2891

Gyroscope:
 X = nan
 Y = nan
 Z = nan

Magnetometer:
 X = -0.2051
 Y = 0.0527
 Z = 0.0742

Thermometer:
 Degrees C = 24.5000
 Degrees F = 76.1000

You may have noticed that gyro data is printed despite there not being a gyro on this board. If a value is not available, the library functions will return nan (not a number). In this case the LSM303C doesn't have a gyroscope, but it still returns a value for a consistent IMU interface. Any IMU library that implements the SparkFunIMU abstract class can be swapped out without having to change the code that uses the library. If at some point in the future it is determined that a project needs more or less degrees of freedom (and is coded with error checking) the code change is trivial. Change #include "SparkFunLSM303C.h" to #include "SparkFun<some other sensor>.h", and LSM303C myIMU; to <some other sensor> myIMU. If for whatever reason the sensor doesn't have valid data ready for a sensor that does exist, it will also return nan. This indicates that the value is undefined.

Configure Example

By default, the easy to configure example is configured exactly the same as the minimalist example. We'll be using the example in I2C mode. Here is the code that differentiates the two examples, the setup:


void setup() {

  Wire.begin();//set up I2C bus, comment out if using SPI mode
  Wire.setClock(400000L);//clock stretching, comment out if using SPI mode

  Serial.begin(57600);//initialize serial monitor, maximum reliable baud for 3.3V/8Mhz ATmega328P is 57600

  if (myIMU.begin(
  ///// Interface mode options
    //MODE_SPI,
    MODE_I2C,

  ///// Magnetometer output data rate options
    //MAG_DO_0_625_Hz,
    //MAG_DO_1_25_Hz,
    //MAG_DO_2_5_Hz,
    //MAG_DO_5_Hz,
    //MAG_DO_10_Hz,
    //MAG_DO_20_hZ,
    MAG_DO_40_Hz,
    //MAG_DO_80_Hz,

  ///// Magnetic field full scale options
    //MAG_FS_4_Ga,
    //MAG_FS_8_Ga,
    //MAG_FS_12_Ga,
    MAG_FS_16_Ga,
                  
  ///// Magnetometer block data updating options
    //MAG_BDU_DISABLE,
    MAG_BDU_ENABLE,

  ///// Magnetometer X/Y axes ouput data rate
    //MAG_OMXY_LOW_POWER,
    //MAG_OMXY_MEDIUM_PERFORMANCE,
    MAG_OMXY_HIGH_PERFORMANCE,
    //MAG_OMXY_ULTRA_HIGH_PERFORMANCE,

  ///// Magnetometer Z axis ouput data rate
    //MAG_OMZ_LOW_PW,
    //MAG_OMZ_MEDIUM_PERFORMANCE,
    MAG_OMZ_HIGH_PERFORMANCE,
    //MAG_OMZ_ULTRA_HIGH_PERFORMANCE,

  ///// Magnetometer run mode
    MAG_MD_CONTINUOUS,
    //MAG_MD_SINGLE,
    //MAG_MD_POWER_DOWN_1,
    //MAG_MD_POWER_DOWN_2,

  ///// Acceleration full scale
    ACC_FS_2g,
    //ACC_FS_4g,
    //ACC_FS_8g,

  ///// Accelerometer block data updating
    //ACC_BDU_DISABLE,
    ACC_BDU_ENABLE,

  ///// Enable X, Y, and/or Z axis
    //ACC_DISABLE_ALL,
    //ACC_X_ENABLE,
    //ACC_Y_ENABLE,
    //ACC_Z_ENABLE,
    //ACC_X_ENABLE|ACC_Y_ENABLE,
    //ACC_X_ENABLE|ACC_Z_ENABLE,
    //ACC_Y_ENABLE|ACC_Z_ENABLE,
    ACC_X_ENABLE|ACC_Y_ENABLE|ACC_Z_ENABLE,

  ///// Accelerometer output data rate
    //ACC_ODR_POWER_DOWN
    //ACC_ODR_10_Hz
    //ACC_ODR_50_Hz
    ACC_ODR_100_Hz
    //ACC_ODR_200_Hz
    //ACC_ODR_400_Hz
    //ACC_ODR_800_Hz
    ) != IMU_SUCCESS)
  {
    Serial.println("Failed setup.");
    while(1);  // Stop here 
  }
}

Configuring for SPI Mode

This setup function exposes all of the configuration options necessary to read the magnetometer and accelerometer. See the datasheet for more advanced configuration. To change a configuration option, uncomment the desired option in that section, and remove or comment out all other options in that section. For example, if you wanted to use the SPI interface, you would change that section to look like the following.


  ///// Interface mode options
    MODE_SPI,
    //MODE_I2C,

After uploading the sketch, open the serial monitor or your favorite terminal emulator and you should start seeing something similar to the following repeating over and over once per second.


Accelerometer:
 X = 64.5752
 Y = 31.4941
 Z = 943.1152

Magnetometer:
 X = -0.2085
 Y = 0.0425
 Z = 0.0972

Thermometer:
 Degrees C = 25.3750
 Degrees F = 77.6750

In the setup that this data capture came from, the breakout board was sitting roughly flat on a desk. This orients the z-axis parallel to the earths gravitational field of 1,000 mg. This is seen by the z-axis value of around 943. If the LSM303C were in free fall, the z-axis component would be 0 g, because it wouldn't be accelerating. Since the sensor isn't in free fall, it is measuring an effective acceleration of 1 g in the positive z direction up out of the table.