Arquivo de etiquetas: gyro

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:
// https://www.sparkfun.com/datasheets/Sensors/Accelerometer/ADXL345.pdf
// http://bildr.org/2011/03/adxl345-arduino/
// https://learn.sparkfun.com/tutorials/itg-3200-hookup-guide
// https://www.sparkfun.com/datasheets/Sensors/Gyro/PS-ITG-3200-00-01.4.pdf
// https://www.sparkfun.com/products/10121

#include <Wire.h>

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

// ITG-3200 (GYRO) REGISTERS
#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

// ADXL345 (ACCEL) REGISTERS
#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

//ITG-3200
//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
  Serial.begin(9600);
  
  //Initialize the I2C communication.
  Wire.begin();

  //Set the gyroscope scale for the outputs to +/-2000 degrees per second
  writeI2C(GYRO, DLPF_FS, (DLPF_FS_SEL_0|DLPF_FS_SEL_1|DLPF_CFG_0));
  //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("");
   Serial.println("==============================");
   Serial.println("=ACCELEROMETER DATA (ADXL345)=");
   Serial.println("==============================");
   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(x);
   Serial.print(" Y-axis: ");
   Serial.print(y);
   Serial.print(" Z-axis: ");
   Serial.print(z);
   Serial.println("");
   Serial.println("==============================");
   Serial.println("= GYROSCOPE DATA (ITG-3200)  =");
   Serial.println("==============================");
   //Angular velocity on x axis
   data = readRoll();
   Serial.print("Roll: ");
   Serial.print(data);
   
   //Angular velocity on y axis
   data = readPitch();
   Serial.print(" Pitch: ");
   Serial.print(data);

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

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 = Wire.read();
    }
  } else {    //ADXL345 multiple-byte read to prevent a change in data between reads of sequential registers
    while (Wire.available()){
      adxl345[aux] = Wire.read();
      aux++;
    }
  }
  Wire.endTransmission();
  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
}

Result:

IMU Output - Arduino Example
IMU Output – Arduino Example