LSM9DS0 Accelerometer, Magnetometer and Gyro in-one

Description:  
The LSM9DS0 gyro/accelerometer/magnetometer works off of and communicates using 3.3V so it's very important you use a microcontroller that uses 3.3V logic and not 5V logic to communicate with it. If you want to communicate with the sensor using 5V you use what's called a Logic Level Converter or logic level shifter. DO NOT USE 5V microcontroller without a logic level shifter. There are many extra features that the LSM9DS0 can do so I encourage you to look at the datasheet to check them out. The LSM9DS0 breakout board measures acceleration, magnetic field, angular rate of change, temperature and its specs are below:

Specifications:
  • ±2/±4/±6/±8/±16 g linear acceleration full-scale
  • ±2/±4/±8/±12 gauss magnetic full-scale
  • ±245/±500/±2000 dps angular rate full scale
  • Embedded temperature sensor
  • SPI and I2C communication
  • 2.4 to 3.6 supply voltage
Resources:
 LSM9DS0 Schematic
 LSM9DS0 Datasheet
 3 Axis Digital MEMS Gyroscopes

How to use your LSM9DS0 Sensor

Now for some arduino code using SPI and I2C to get you started below:
Using SPI:
#include <SPI.h> //add arduino SPI library;
//list of all register's binary addresses;
byte WHO_AM_I_G           = 0B00001111;
byte CTRL_REG1_G          = 0B00100000;
byte CTRL_REG2_G          = 0B00100001;
byte CTRL_REG3_G          = 0B00100010;
byte CTRL_REG4_G          = 0B00100011;
byte CTRL_REG5_G          = 0B00100100;
byte REFERENCE_G          = 0B00100101;
byte STATUS_REG_G         = 0B00100111;
byte OUT_X_L_G            = 0B00101000;
byte OUT_X_H_G            = 0B00101001;
byte OUT_Y_L_G            = 0B00101010;
byte OUT_Y_H_G            = 0B00101011;
byte OUT_Z_L_G            = 0B00101100;
byte OUT_Z_H_G            = 0B00101101;
byte FIFO_CTRL_REG_G      = 0B00101110;
byte FIFO_SRC_REG_G       = 0B00101111;
byte INT1_CFG_G           = 0B00110000;
byte INT1_SRC_G           = 0B00110001;
byte INT1_TSH_XH_G        = 0B00110010;
byte INT1_TSH_XL_G        = 0B00110011;
byte INT1_TSH_YH_G        = 0B00110100;
byte INT1_TSH_YL_G        = 0B00110101;
byte INT1_TSH_ZH_G        = 0B00110110;
byte INT1_TSH_ZL_G        = 0B00110111;
byte INT1_DURATION_G      = 0B00111000;
byte OUT_TEMP_L_XM        = 0B00000101;
byte OUT_TEMP_H_XM        = 0B00000110;
byte STATUS_REG_M         = 0B00000111;
byte OUT_X_L_M            = 0B00001000;
byte OUT_X_H_M            = 0B00001001;
byte OUT_Y_L_M            = 0B00001010;
byte OUT_Y_H_M            = 0B00001011;
byte OUT_Z_L_M            = 0B00001100;
byte OUT_Z_H_M            = 0B00001101;
byte WHO_AM_I_XM          = 0B00001111;
byte INT_CTRL_REG_M       = 0B00010010;
byte INT_SRC_REG_M        = 0B00010011;
byte INT_THS_L_M          = 0B00010100;
byte INT_THS_H_M          = 0B00010101;
byte OFFSET_X_L_M         = 0B00010110;
byte OFFSET_X_H_M         = 0B00010111;
byte OFFSET_Y_L_M         = 0B00101000;
byte OFFSET_Y_H_M         = 0B00101001;
byte OFFSET_Z_L_M         = 0B00101010;
byte OFFSET_Z_H_M         = 0B00101011;
byte REFERENCE_X          = 0B00101100;
byte REFERENCE_Y          = 0B00101101;
byte REFERENCE_Z          = 0B00101110;
byte CTRL_REG0_XM         = 0B00011111;
byte CTRL_REG1_XM         = 0B00100000;
byte CTRL_REG2_XM         = 0B00100001;
byte CTRL_REG3_XM         = 0B00100010;
byte CTRL_REG4_XM         = 0B00100011;
byte CTRL_REG5_XM         = 0B00100100;
byte CTRL_REG6_XM         = 0B00100101;
byte CTRL_REG7_XM         = 0B00100110;
byte STATUS_REG_A         = 0B00100111;
byte OUT_X_L_A            = 0B00101000;
byte OUT_X_H_A            = 0B00101001;
byte OUT_Y_L_A            = 0B00101010;
byte OUT_Y_H_A            = 0B00101011;
byte OUT_Z_L_A            = 0B00101100;
byte OUT_Z_H_A            = 0B00101101;
byte FIFO_CTRL_REG        = 0B00101110;
byte FIFO_SRC_REG         = 0B00101111;
byte INT_GEN_1_REG        = 0B00110000;
byte INT_GEN_1_SRC        = 0B00110001;
byte INT_GEN_1_THS        = 0B00110010;
byte INT_GEN_1_DURATION   = 0B00110011;
byte INT_GEN_2_REG        = 0B00110100;
byte INT_GEN_2_SRC        = 0B00110101;
byte INT_GEN_2_THS        = 0B00110110;
byte INT_GEN_2_DURATION   = 0B00110111;
byte CLICK_CFG            = 0B00111000;
byte CLICK_SRC            = 0B00111001;
byte CLICK_THS            = 0B00111010;
byte TIME_LIMIT           = 0B00111011;
byte TIME_LATENCY         = 0B00111100;
byte TIME_WINDOW          = 0B00111101;
byte ACT_THS              = 0B00111110;
byte ACT_DUR              = 0B00111111;

byte Read  = 0B10000000;
byte Write = 0B00000000;

//chip select pin on arduino;
const int CS_G = 9;
const int CS_XM  =  10;
/*
SPI.h sets these for us in arduino
const int SDI = 11;
const int SDO_XM and int SDO_G = 12;
const int SCL = 13;
*/

void setup() {  
  Serial.begin(9600);
  //start the SPI library;
  SPI.begin();
  //initalize the chip select pins;
  pinMode(CS_G, OUTPUT);
  pinMode(CS_XM, OUTPUT);
//activate accelerometer and temperature
WriteRegister_XM(CTRL_REG1_XM,0B00110111);  
WriteRegister_XM(CTRL_REG5_XM,0B10001000);  //activate temp
WriteRegister_XM(CTRL_REG7_XM,0B00000000);  
//activate gyro
WriteRegister_G(CTRL_REG1_G,0B00001111); 
delay(10);

}

void loop() {

//gyro section
byte X_L = ReadRegister_G(OUT_X_L_G);
byte X_H = ReadRegister_G(OUT_X_H_G);
byte Y_L = ReadRegister_G(OUT_Y_L_G);
byte Y_H = ReadRegister_G(OUT_Y_H_G);
byte Z_L = ReadRegister_G(OUT_Z_L_G);
byte Z_H = ReadRegister_G(OUT_Z_H_G);

int X_AXIs = X_H <<8 | X_L;
int Y_AXIs = Y_H <<8 | Y_L;
int Z_AXIs = Z_H <<8 | Z_L;

Serial.print("X-Axis: ");
Serial.println(X_AXIs, DEC); //raw x axis data
Serial.print("Y-Axis: ");
Serial.println(Y_AXIs, DEC);  //raw y axis data
Serial.print("Z-Axis: ");
Serial.println(Z_AXIs, DEC);  //raw z axis data

Serial.print("X-Axis: ");  //.00875 is from the datasheet and my settings when i writeregister
Serial.println(0.00875*(X_AXIs+110), DEC);  
Serial.print("Y-Axis: ");                   
Serial.println(0.00875*(Y_AXIs+190), DEC);  
Serial.print("Z-Axis: ");                   
Serial.println(0.00875*(Z_AXIs+115), DEC);  
                                            
//the number 110 above comes from me averaging the first 100 samples of raw gyro                                            
//data sitting still in this axis and applying the equation .00875((rawdata axis data)-(average data))                                            
//everyones gyro will be different so nobodys will be the same and YOU have to manually                                            
//provide it or write in the code which would be best.(I know I'll get on it lol..priorities)                                            
//All axis will also be a different number...I also put a datasheet in the resources about this.                                            
//Output will be in dps(degrees per second)                                              
                                            
//accelerometer/magnetometer section
byte X_L_M = ReadRegister_XM(OUT_X_L_M);
byte X_H_M = ReadRegister_XM(OUT_X_H_M);
byte Y_L_M = ReadRegister_XM(OUT_Y_L_M);
byte Y_H_M = ReadRegister_XM(OUT_Y_H_M);
byte Z_L_M = ReadRegister_XM(OUT_Z_L_M);
byte Z_H_M = ReadRegister_XM(OUT_Z_H_M);

byte X_L_A = ReadRegister_XM(OUT_X_L_A);
byte X_H_A = ReadRegister_XM(OUT_X_H_A);
byte Y_L_A = ReadRegister_XM(OUT_Y_L_A);
byte Y_H_A = ReadRegister_XM(OUT_Y_H_A);
byte Z_L_A = ReadRegister_XM(OUT_Z_L_A);
byte Z_H_A = ReadRegister_XM(OUT_Z_H_A);

int X_AXIS_M = X_H_M <<8 | X_L_M;
int Y_AXIS_M = Y_H_M <<8 | Y_L_M;
int Z_AXIS_M = Z_H_M <<8 | Z_L_M;

int X_AXIS_A = X_H_A <<8 | X_L_A;
int Y_AXIS_A = Y_H_A <<8 | Y_L_A;
int Z_AXIS_A = Z_H_A <<8 | Z_L_A;

Serial.print("X-Axis_M: ");
Serial.println(X_AXIS_M*0.00008, DEC); // .00008 comes from the datasheet and my settings for the magnetometer.
Serial.print("Y-Axis_M: ");            // output will be in gauss
Serial.println(Y_AXIS_M*0.00008, DEC);
Serial.print("Z-Axis_M: ");
Serial.println(Z_AXIS_M*0.00008, DEC);

Serial.print("X-Axis_A: ");
Serial.println(X_AXIS_A*0.000061, DEC); // .000061 comes from the datasheet and my settings for the accelerometer.
Serial.print("Y-Axis_A: ");             // output will be in g's.
Serial.println(Y_AXIS_A*0.000061, DEC);
Serial.print("Z-Axis_A: ");
Serial.println(Z_AXIS_A*0.000061, DEC);

//temperature section
byte Temp_L = ReadRegister_XM(OUT_TEMP_L_XM);
byte Temp_H = ReadRegister_XM(OUT_TEMP_H_XM);

int Temp = Temp_H <<8 | Temp_L;

Serial.print("Temperature: ");
Serial.print(Temp, DEC);
Serial.println(" C");

delay(500);
}

byte ReadRegister_XM(byte Address){
  byte result = 0;
  digitalWrite(CS_XM, LOW); 
  SPI.transfer(Read | Address);
  result = SPI.transfer(0x00);
/*  Serial.print(Address, BIN);
  Serial.print(" : ");
  Serial.println(result, BIN); */
  digitalWrite(CS_XM, HIGH);
return(result);  
}

void WriteRegister_XM(byte Address, byte Value){
  digitalWrite(CS_XM, LOW); 
  SPI.transfer(Write | Address);
  SPI.transfer(Value);
  digitalWrite(CS_XM, HIGH);  
}

byte ReadRegister_G(byte Address){
  byte result = 0;
  digitalWrite(CS_G, LOW); 
  SPI.transfer(Read | Address);
  result = SPI.transfer(0x00);
/*  Serial.print(Address, BIN);
  Serial.print(" : ");
  Serial.println(result, BIN); */
  digitalWrite(CS_G, HIGH);
return(result);  
}

void WriteRegister_G(byte Address, byte Value){
  digitalWrite(CS_G, LOW); 
  SPI.transfer(Write | Address);
  SPI.transfer(Value);
  digitalWrite(CS_G, HIGH);  
}


Using I2C:

#include <Wire.h> //add arduino I2C library;
//list of all registers binary addresses;
byte WHO_AM_I_G           = 0B00001111;
byte CTRL_REG1_G          = 0B00100000;
byte CTRL_REG2_G          = 0B00100001;
byte CTRL_REG3_G          = 0B00100010;
byte CTRL_REG4_G          = 0B00100011;
byte CTRL_REG5_G          = 0B00100100;
byte REFERENCE_G          = 0B00100101;
byte STATUS_REG_G         = 0B00100111;
byte OUT_X_L_G            = 0B00101000;
byte OUT_X_H_G            = 0B00101001;
byte OUT_Y_L_G            = 0B00101010;
byte OUT_Y_H_G            = 0B00101011;
byte OUT_Z_L_G            = 0B00101100;
byte OUT_Z_H_G            = 0B00101101;
byte FIFO_CTRL_REG_G      = 0B00101110;
byte FIFO_SRC_REG_G       = 0B00101111;
byte INT1_CFG_G           = 0B00110000;
byte INT1_SRC_G           = 0B00110001;
byte INT1_TSH_XH_G        = 0B00110010;
byte INT1_TSH_XL_G        = 0B00110011;
byte INT1_TSH_YH_G        = 0B00110100;
byte INT1_TSH_YL_G        = 0B00110101;
byte INT1_TSH_ZH_G        = 0B00110110;
byte INT1_TSH_ZL_G        = 0B00110111;
byte INT1_DURATION_G      = 0B00111000;
byte OUT_TEMP_L_XM        = 0B00000101;
byte OUT_TEMP_H_XM        = 0B00000110;
byte STATUS_REG_M         = 0B00000111;
byte OUT_X_L_M            = 0B00001000;
byte OUT_X_H_M            = 0B00001001;
byte OUT_Y_L_M            = 0B00001010;
byte OUT_Y_H_M            = 0B00001011;
byte OUT_Z_L_M            = 0B00001100;
byte OUT_Z_H_M            = 0B00001101;
byte WHO_AM_I_XM          = 0B00001111;
byte INT_CTRL_REG_M       = 0B00010010;
byte INT_SRC_REG_M        = 0B00010011;
byte INT_THS_L_M          = 0B00010100;
byte INT_THS_H_M          = 0B00010101;
byte OFFSET_X_L_M         = 0B00010110;
byte OFFSET_X_H_M         = 0B00010111;
byte OFFSET_Y_L_M         = 0B00101000;
byte OFFSET_Y_H_M         = 0B00101001;
byte OFFSET_Z_L_M         = 0B00101010;
byte OFFSET_Z_H_M         = 0B00101011;
byte REFERENCE_X          = 0B00101100;
byte REFERENCE_Y          = 0B00101101;
byte REFERENCE_Z          = 0B00101110;
byte CTRL_REG0_XM         = 0B00011111;
byte CTRL_REG1_XM         = 0B00100000;
byte CTRL_REG2_XM         = 0B00100001;
byte CTRL_REG3_XM         = 0B00100010;
byte CTRL_REG4_XM         = 0B00100011;
byte CTRL_REG5_XM         = 0B00100100;
byte CTRL_REG6_XM         = 0B00100101;
byte CTRL_REG7_XM         = 0B00100110;
byte STATUS_REG_A         = 0B00100111;
byte OUT_X_L_A            = 0B00101000;
byte OUT_X_H_A            = 0B00101001;
byte OUT_Y_L_A            = 0B00101010;
byte OUT_Y_H_A            = 0B00101011;
byte OUT_Z_L_A            = 0B00101100;
byte OUT_Z_H_A            = 0B00101101;
byte FIFO_CTRL_REG        = 0B00101110;
byte FIFO_SRC_REG         = 0B00101111;
byte INT_GEN_1_REG        = 0B00110000;
byte INT_GEN_1_SRC        = 0B00110001;
byte INT_GEN_1_THS        = 0B00110010;
byte INT_GEN_1_DURATION   = 0B00110011;
byte INT_GEN_2_REG        = 0B00110100;
byte INT_GEN_2_SRC        = 0B00110101;
byte INT_GEN_2_THS        = 0B00110110;
byte INT_GEN_2_DURATION   = 0B00110111;
byte CLICK_CFG            = 0B00111000;
byte CLICK_SRC            = 0B00111001;
byte CLICK_THS            = 0B00111010;
byte TIME_LIMIT           = 0B00111011;
byte TIME_LATENCY         = 0B00111100;
byte TIME_WINDOW          = 0B00111101;
byte ACT_THS              = 0B00111110;
byte ACT_DUR              = 0B00111111;

byte Read    = 0B00000001;
byte Write   = 0B00000000;
byte Address_XM = 0B00111010;  //address of accelerometer/magnetometer with SAO connected to Vdd
byte Address_G  = 0B11010110;  //address of gyro with SAO connected to Vdd
//byte Address_XM  = 0B00111100;  //address of accelerometer/magnetometer with SAO connected to ground
//byte Address_G   = 0B11010100;  //address of gyro with SAO connected to ground
/*
Wire.h sets these for us in arduino...that's analog pin 4 and 5
const int SDA = 4; 
const int SCL = 5; 
*/

void setup() {
  Serial.begin(9600);
  //start the Wire library;
  Wire.begin();
//activate accelerometer and temperature
WriteRegister_XM(CTRL_REG1_XM,0B00110111);  
WriteRegister_XM(CTRL_REG5_XM,0B10001000);  //temperature activated
WriteRegister_XM(CTRL_REG7_XM,0B00000000);  
//activate gyro
WriteRegister_G(CTRL_REG1_G,0B00001111); 
delay(100);
}

void loop() {

//gyro section
byte X_L = ReadRegister_G(OUT_X_L_G);
byte X_H = ReadRegister_G(OUT_X_H_G);
byte Y_L = ReadRegister_G(OUT_Y_L_G);
byte Y_H = ReadRegister_G(OUT_Y_H_G);
byte Z_L = ReadRegister_G(OUT_Z_L_G);
byte Z_H = ReadRegister_G(OUT_Z_H_G);

int X_AXIs = X_H <<8 | X_L;
int Y_AXIs = Y_H <<8 | Y_L;
int Z_AXIs = Z_H <<8 | Z_L;

Serial.print("X-Axis: ");
Serial.println(X_AXIs, DEC); //raw x axis data
Serial.print("Y-Axis: ");
Serial.println(Y_AXIs, DEC);  //raw y axis data
Serial.print("Z-Axis: ");
Serial.println(Z_AXIs, DEC);  //raw z axis data

Serial.print("X-Axis: ");  //.00875 is from the datasheet and my settings when i writeregister
Serial.print(0.00875*(X_AXIs+110), DEC);
Serial.println(" dps");
Serial.print("Y-Axis: ");                   
Serial.print(0.00875*(Y_AXIs+190), DEC);
Serial.println(" dps");
Serial.print("Z-Axis: ");                   
Serial.print(0.00875*(Z_AXIs+115), DEC);
Serial.println(" dps");
                                            
//the number 110 above comes from me averaging the first 100 samples of raw gyro                                            
//data sitting still in this axis and applying the equation .00875((rawdata axis data)-(average data))                                            
//everyones gyro will be different so nobodys will be the same and YOU have to manually                                            
//provide it or write in the code which would be best.(I know I'll get on it lol..priorities)                                            
//All axis will also be a different number...I also put a datasheet in the resources about this.                                            
//Output will be in dps(degrees per second)                                              
                                            
//accelerometer/magnetometer section
byte X_L_M = ReadRegister_XM(OUT_X_L_M);
byte X_H_M = ReadRegister_XM(OUT_X_H_M);
byte Y_L_M = ReadRegister_XM(OUT_Y_L_M);
byte Y_H_M = ReadRegister_XM(OUT_Y_H_M);
byte Z_L_M = ReadRegister_XM(OUT_Z_L_M);
byte Z_H_M = ReadRegister_XM(OUT_Z_H_M);

byte X_L_A = ReadRegister_XM(OUT_X_L_A);
byte X_H_A = ReadRegister_XM(OUT_X_H_A);
byte Y_L_A = ReadRegister_XM(OUT_Y_L_A);
byte Y_H_A = ReadRegister_XM(OUT_Y_H_A);
byte Z_L_A = ReadRegister_XM(OUT_Z_L_A);
byte Z_H_A = ReadRegister_XM(OUT_Z_H_A);

int X_AXIS_M = X_H_M <<8 | X_L_M;
int Y_AXIS_M = Y_H_M <<8 | Y_L_M;
int Z_AXIS_M = Z_H_M <<8 | Z_L_M;

int X_AXIS_A = X_H_A <<8 | X_L_A;
int Y_AXIS_A = Y_H_A <<8 | Y_L_A;
int Z_AXIS_A = Z_H_A <<8 | Z_L_A;

Serial.print("X-Axis_M: ");
Serial.print(X_AXIS_M*0.00008, DEC); // .00008 comes from the datasheet and my settings for the magnetometer.
Serial.println(" Gauss");
Serial.print("Y-Axis_M: ");            // output will be in gauss
Serial.print(Y_AXIS_M*0.00008, DEC);
Serial.println(" Gauss");
Serial.print("Z-Axis_M: ");
Serial.print(Z_AXIS_M*0.00008, DEC);
Serial.println(" Gauss");

Serial.print("X-Axis_A: ");
Serial.print(X_AXIS_A*0.000061, DEC); // .000061 comes from the datasheet and my settings for the accelerometer.
Serial.println(" G");
Serial.print("Y-Axis_A: ");             // output will be in g's.
Serial.print(Y_AXIS_A*0.000061, DEC);
Serial.println(" G");
Serial.print("Z-Axis_A: ");
Serial.print(Z_AXIS_A*0.000061, DEC);
Serial.println(" G");
delay(500);


//temperature section
byte Temp_L = ReadRegister_XM(OUT_TEMP_L_XM);
byte Temp_H = ReadRegister_XM(OUT_TEMP_H_XM);

int Temp = Temp_H <<8 | Temp_L;

Serial.print("Temperature: ");
Serial.print(Temp, DEC);
Serial.println(" C");

}


byte ReadRegister_XM(int Register){
byte result = 0;
Wire.beginTransmission((Address_XM | Write) >>1 ); //slave ID start talking
//ask for info in register
Wire.write(Register);
//complete the send
Wire.endTransmission(0);
//Request 1 byte

Wire.requestFrom((Address_XM | Read) >>1 , 1);
//wait for info
while( Wire.available() == 0);
result = Wire.read();  
//get info
Wire.endTransmission();
return(result);  
}

void WriteRegister_XM(byte Register, byte Value){
  Wire.beginTransmission((Address_XM | Write) >>1 );
  Wire.write(Register);
  Wire.write(Value);
  Wire.endTransmission();
}


byte ReadRegister_G(int Register){
byte result = 0;
Wire.beginTransmission((Address_G | Write) >>1 ); //slave ID start talking
//ask for info in register
Wire.write(Register);
//complete the send
Wire.endTransmission(0);
//Request 1 byte

Wire.requestFrom((Address_G | Read) >>1 , 1);
//wait for info
while( Wire.available() == 0);
result = Wire.read();  
//get info
Wire.endTransmission();
return(result);  
}

void WriteRegister_G(byte Register, byte Value){
  Wire.beginTransmission((Address_G | Write) >>1 );
  Wire.write(Register);
  Wire.write(Value);
  Wire.endTransmission();
}
How to change your I2C address(not needed unless you want 2 sensors on to run on the same I2C line)
You can always just bring SDO_G and SDO_XM to ground instead of doing the following below.
 
SKU : 
   SEN1004
Price : 
   $23.95
Qty : 
 

Comments

what is the difference between Serial.print and Serial.println?

Serial.println puts the cursor on a new line after it finishes whatever it's printing/displaying. Serial.print will just stay on the same line after it prints/displays.

why need (raw data +110) x sensitivity?where the 110 come from? and why need multiply by the sensitivity?

.00875((rawdata axis data)-(average data)) = dps...That is the equation given in the datasheet above labeled "3 axis digital MEMS Gyroscopes" Find the part closer to the end that says "How to get meaningful information". So my -110 came from me averaging 100 samples. So average data sitting in place would be (raw data added together/however many samples you take). Then you can take the sensitivity in our case we look at the datasheet for the lsm9ds0 and since we're using 245dps full scale we have to use a sensitivity of 8.75 mdps/lsb I would rather use dps so I convert that to .00875 dps/lsb. After you have those two values (average data and sensitivity) you just need to collect raw data and your gyroscope is operational using the very first equation. You have to apply this to each axis individually and on every startup.