Arquivo de etiquetas: imu

ITG-3200 (Gyroscope) & ADXL345 (Accelerometer) – Arduino Example

Recently I got an IMU (Inertial Measurement Unit) from Sparkfun, called SparkFun 6 Degrees of Freedom IMU Digital Combo Board.

IMU Breakout Doard - 6 Degree of Freedom

This IMU has embedded a gyroscope (ITG-3200) and a accelerometer (ADXL345) in a breakout board being useful for application that requires knowledge about orientation, position, and velocity.

The gyroscope is responsible to measure angular velocity on body axes:

  • X Axis – Roll
  • Y Axis – Pitch
  • Z Axis – Yaw

Some examples:

Angular Movements - Gyro Examples

The accelerometer is responsible to measure acceleration on the body axes (x, y and z) that is useful to determine how fast a body is speeding up or slowing down.

Another point is the use of I2C (Inter-Integrated Circuit) bus that is an intra-board serial bus that uses only two “wires” for comunication: one responsible for synchronizing the devices on bus (CLOCK – SCL)  and another one responsible for data transmission (DATA – SDA).

This article aims to present a arduino implementation that simply shows output data from sensors. The references on source code are highly recommended for study before deploy this code in real application.

// SparkFun 6 Degrees of Freedom IMU Digital Combo Board
// ITG-3200 (GYRO) & ADXL345 (ACCEL) - Arduino Example Algorithm
// Author: Gustavo Bertoli
// References:

#include <Wire.h>

// I2C Devices Address
#define GYRO 0x68    // ITG-3200 I2C Address - 0x68
#define ACCEL 0x53   // ADXL345  I2C Address - 0x53

#define GYRO_X_H 0x1D
#define GYRO_X_L 0x1E
#define GYRO_Y_H 0x1F
#define GYRO_Y_L 0x20
#define GYRO_Z_H 0x21
#define GYRO_Z_L 0x22
#define DLPF_FS 0x16
#define SMPLRT_DIV 0x15

#define ACCEL_X_L 0x32 
#define ACCEL_X_H 0x33
#define ACCEL_Y_L 0x34
#define ACCEL_Y_H 0x35
#define ACCEL_Z_L 0x36
#define ACCEL_Z_H 0x37
#define POWER_CTL 0x2D
#define DATA_FORMAT 0x31

//DLPF, Full Scale Register Bits
//FS_SEL must be set to 3 for proper operation
//Set DLPF_CFG to 3 for 1kHz Fint and 42 Hz Low Pass Filter
char DLPF_CFG_0 = 1<<0;
char DLPF_CFG_1 = 1<<1;
char DLPF_CFG_2 = 1<<2;
char DLPF_FS_SEL_0 = 1<<3;
char DLPF_FS_SEL_1 = 1<<4;

byte adxl345[6];

void setup()
  //Set serial communication at 9600 baudrate
  //Initialize the I2C communication.

  //Set the gyroscope scale for the outputs to +/-2000 degrees per second
  //Set the sample rate to 100 hz  
  writeI2C(GYRO, SMPLRT_DIV, 9);

  //to enable measurement mode in ADXL345 (measure bit)
  writeI2C(ACCEL, POWER_CTL, 0b00001000);
  //The DATA_FORMAT register controls the presentation of data to Register 0x32 through Register 0x37
  //writeI2C(ACCEL, DATA_FORMAT, 0b0000);

void loop()
   int data = 0;
   int x, y ,z; //acceleration - ADXL345
   Serial.println("=ACCELEROMETER DATA (ADXL345)=");
   readI2C(ACCEL,ACCEL_X_L,6);    //ADXL345 multiple-byte read to prevent a change in data between reads of sequential registers
   // each axis reading comes in 10 bit resolution, ie 2 bytes.  Least Significat Byte first!!
   // thus we are converting both bytes in to one int
   x = (((int)adxl345[1]) << 8) | adxl345[0];   
   y = (((int)adxl345[3]) << 8) | adxl345[2];
   z = (((int)adxl345[5]) << 8) | adxl345[4];
   Serial.print("X-axis: ");
   Serial.print(" Y-axis: ");
   Serial.print(" Z-axis: ");
   Serial.println("= GYROSCOPE DATA (ITG-3200)  =");
   //Angular velocity on x axis
   data = readRoll();
   Serial.print("Roll: ");
   //Angular velocity on y axis
   data = readPitch();
   Serial.print(" Pitch: ");

   //Angular velocity on z axis
   data = readYaw();
   Serial.print(" Yaw: ");

int readRoll (void){
  int data = 0;
  data = readI2C(GYRO, GYRO_X_H,1)<<8;
  data |= readI2C(GYRO, GYRO_X_L,1);
  return data;
int readPitch (void){
  int data = 0;
  data = readI2C(GYRO, GYRO_Y_H,1)<<8;
  data |= readI2C(GYRO, GYRO_Y_L,1);
  return data;
int readYaw (void){
  int data = 0;
  data = readI2C(GYRO, GYRO_Z_H,1)<<8;
  data |= readI2C(GYRO, GYRO_Z_L,1);
  return data;
// function to read from a device on I2C bus
byte readI2C(byte devAddress, byte devRegister, int numBytes){
  byte data = 0; 
  int aux = 0;
  Wire.beginTransmission(devAddress);   //Set device address on I2C bus
  Wire.write(devRegister);              //Set register to read from device
  Wire.endTransmission();               //Stop

  Wire.beginTransmission(devAddress);   //Set device address on I2C bus
  Wire.requestFrom(devAddress, numBytes);      //read data

  if (numBytes == 1) {
    if (Wire.available()){
      data =;
  } else {    //ADXL345 multiple-byte read to prevent a change in data between reads of sequential registers
    while (Wire.available()){
      adxl345[aux] =;
  return data;

// function to write in a device on I2C bus
void writeI2C(byte devAddress, byte devRegister, byte devData){
  Wire.beginTransmission(devAddress);    //Start tx - set device address on I2C bus
  Wire.write(devRegister);               //Set register from I2C device
  Wire.write(devData);                  //Set value to register 
  Wire.endTransmission();                //Stop tx


IMU Output - Arduino Example
IMU Output – Arduino Example