Help With I2C gyro  ITG 3200

Hi

I am new to Arduino and have to use an I2C gyro for my project to measure pitch, roll and yaw. I am using the ITG-3200 gyro. This is my code:

//To read a value char ITG3200Read(unsigned char address) { char data=0x00;

Wire.beginTransmission(0x64); Wire.send((address)); delay(5); Wire.endTransmission(); Wire.requestFrom(0x64,1); if (Wire.available()>0) { data = Wire.receive(); return data; } Wire.endTransmission(); }

void Gyro_Init() { Wire.beginTransmission(0x64); Wire.send(0x3E); Wire.send(0x80); //send a reset to the device Wire.endTransmission(); //end transmission

Wire.beginTransmission(0x64); Wire.send(0x15); Wire.send(0x00); //sample rate divider Wire.endTransmission(); //end transmission

Wire.beginTransmission(0x64); Wire.send(0x16); Wire.send(0x18); // ±2000 degrees/s (default value) Wire.endTransmission(); //end transmission

Wire.beginTransmission(0x64); Wire.send(0x17); Wire.send(0x05); // enable send raw values Wire.endTransmission(); //end transmission

// Wire.beginTransmission(0x64); // Wire.send(0x3E); // Wire.send(0x00); // Wire.endTransmission(); //end transmission }

kindly let me know what I should change as soon as possible as I am in a time crunch now.

kindly let me know what I should change

..in order to accomplish what? Is there something that doesn't work the way you want it to? Please use the code tag (# -button).

I've been trying to read the gyro values.. But all I get is 0 , a value which I get even when the gyro is disconnected

Posting only part of the code is no good as we can't see what goes round it and often that is the error. Also in this case yo have not said how you have wired it up. Specifically what have you done with the AD0 pin? The code would suggest that it is wired up to ground but have you? Also what voltage are you running the chip on and what voltage is the arduino running on. If they are different what provisions have you taken to perform voltage translation between the devices? Finally are you using the right I2C lines? It is analogue pins 4 & 5 not digital 4 & 5. Have you got pull up resistors on the I2C lines.

Without the above information we can only guess why it won't work.

this is my entire code:

#include <Wire.h>


// ITG3200 Register Defines
#define WHO      0x00
#define      SMPL      0x15
#define DLPF      0x16
#define INT_C      0x17
#define INT_S      0x1A
#define      TMP_H      0x1B
#define      TMP_L      0x1C
#define      GX_H      0x1D
#define      GX_L      0x1E
#define      GY_H      0x1F
#define      GY_L      0x20
#define GZ_H      0x21
#define GZ_L      0x22
#define PWR_M      0x3E
#define GYRO_ADDRESS 0x68

void setup()
{
  Gyro_Init();
  Wire.begin();
  Serial.begin(9600);
}

void loop()
{
          Serial.print("Gyrox: ");
          Serial.println(ITG3200Read(GX_H,GX_L),DEC);
          delay(1000);
}
char ITG3200Read(unsigned char addressh,unsigned char addressl)
{
   char data;
        
        Wire.beginTransmission(GYRO_ADDRESS);
        Wire.send((addressh));  
          Wire.endTransmission();
        Wire.requestFrom(GYRO_ADDRESS,1);
        if (Wire.available()>0)
          {
          data = Wire.receive();
          }
        Wire.beginTransmission(GYRO_ADDRESS);          
          Wire.send((addressl));    
          Wire.endTransmission();
          if (Wire.available()>0)
          {
          data |= Wire.receive()<<8;
          }
          return data;
          

//         Wire.endTransmission();
}



void Gyro_Init(void)
{
  Wire.beginTransmission(GYRO_ADDRESS);
  Wire.send(0x3E);
  Wire.send(0x80);  //send a reset to the device
  Wire.endTransmission(); //end transmission
  
  Wire.beginTransmission(GYRO_ADDRESS);
  Wire.send(0x15);
  Wire.send(0x00);   //sample rate divider
  Wire.endTransmission(); //end transmission
  
  Wire.beginTransmission(GYRO_ADDRESS);
  Wire.send(0x16);
  Wire.send(0x18); // ±2000 degrees/s (default value)
  Wire.endTransmission(); //end transmission
  
  Wire.beginTransmission(GYRO_ADDRESS);
  Wire.send(0x17);
  Wire.send(0x05);   // enable send raw values
  Wire.endTransmission(); //end transmission
  
//  Wire.beginTransmission(GYRO_ADDRESS);
//  Wire.send(0x3E);
//  Wire.send(0x00);   
//  Wire.endTransmission(); //end transmission
}

I edited the ITG function as I had missed a requestFrom() function

char ITG3200Read(unsigned char addressh,unsigned char addressl)
{
        
        Wire.beginTransmission(GYRO_ADDRESS);
        Wire.send((addressl));  
          Wire.endTransmission();
        Wire.requestFrom(GYRO_ADDRESS,2);
        if (Wire.available())
          {
           data = Wire.receive();
          }
          if (Wire.available())
          {
            data |= (Wire.receive()<<8);
          }
          return data;
}

I'm currently attempting to hook up the itg-3200, also with no luck. Going through your code, however, I found that in your setup function you call Gyro_Init() before starting wire.

void setup()
{
  Gyro_Init();
  Wire.begin();
  Serial.begin(9600);
}

This is why (at least for me) the arduino doesn't do anything. If you switch the order around, like so:

void setup()
{
  Wire.begin();
  Gyro_Init();
  Serial.begin(9600);
}

The arduino at least prints out data. Nonetheless, it is still bad data. Let me know if I'm even being helpful here...

@Hunter: I changed that.. Thank you for the heads up.. I still can't seem to read any value from the gyro.. Did it work out for you?

if (Wire.available())
          {
           data = Wire.receive();
          }
          if (Wire.available())
          {
            data |= (Wire.receive()<<8);
          }
          return data;

That is not the way to do it. Think what happens if Wire.available() returns false. That is data has not been received yet, the code just skips over the gathering of it. You have to wait UNTIL data is available:-

while (!Wire.available()) { } // do nothing until data arrives
           data = Wire.receive();  // now get the data

The could be other stuff but this will stop you receiving anything.

@Mike: Thanks.. Now it seems to get stuck infinitely in the while loop.. It doesn't return any data.. What could be the proble?

This is the gyro I'm using:

http://www.sparkfun.com/commerce/product_info.php?products_id=9801

I have connected Vdd, VIO to 3.3V.. (I have changed the address of the gyro as 0x69)..

Grnd, Clk - to ground

I have used 10k pull up resistors for the I2C lines

Ok. Here's what I know, or at least think I know:

  1. I'm using the sparkfun breakout for the gyro as well.
  2. Since arduino operates at 5v, I'm using a dual mosfet level shifter to bring i2c down (and up) to the correct voltage. Sparkfun sells a simple one, but I'm not using it
  3. After reading the datasheet for the gyro, I think that the problem is the wire library. We have no way of waiting for the acknowledge signal from the gyro, and thus no way of knowing when the transmission has completed.

@jefferydavid2003: Where did you find documentation for connecting clk to ground? Also why 10k pullup resistors

wire.requestFrom(uint8_t address, uint8_t quantity)

returns a value called "read" (uint8_t). //as seen in library...

This is the amount of data read and might be useful to you.

Also, I noticed that there is no overloaded event for the address being an "unsigned char", you may want it to be changed to uint8_t (just to be sure that the compiler isn't doing funny things).

Have you tried the example code?

Someone on the "comments" section said that they had to use address 0x69. Have you tried that?

From the data sheet I see the recommended voltage is 2v5, you should be OK with 3v3 but you must have voltage level translators on the clock and data lines if you are driving it from a 5v arduino. Failure to do this could fry the chip.

Thanks Mike.. The Gyro works now..

Thank you everyone who helped me out :)

Was that just by changing the voltage to 3V3?...

How did you make it work?

Uhhh So if it works can you post your finished code and setup? I still cannot get mine to work. How'd you convert from 3.3 to 5 volts?

This topic has helped me. Here is the code I am using. Any suggestions on improving the code for the gyro are welcome.

#include <Wire.h> // I2C library, gyroscope

#define GYRO_ADDR 0x69 // gyro address, binary = 11101001
#define SMPLRT_DIV 0x15 
#define DLPF_FS 0x16
#define INT_CFG 0x17
#define PWR_MGM 0x3E

//initializes the gyroscope
void initGyro()
{
      /*****************************************
      *      ITG 3200
      *      power management set to:
      *      clock select = internal oscillator
      *             no reset, no sleep mode
      *            no standby mode
      *      sample rate to = 3Hz
      *      parameter to +/- 2000 degrees/sec
      *      low pass filter = 5Hz
      *      no interrupt
      ******************************************/      
      Wire.beginTransmission(GYRO_ADDR);
      Wire.send(PWR_MGM);
      Wire.send(0x00);
      Wire.endTransmission();
      
      Wire.beginTransmission(GYRO_ADDR);
      Wire.send(SMPLRT_DIV);
      Wire.send(0xFF); // EB, 50, 80, 7F, DE, 23, 20, FF
      Wire.endTransmission();
      
      Wire.beginTransmission(GYRO_ADDR);
      Wire.send(DLPF_FS);
      Wire.send(0x1E); // +/- 2000 dgrs/sec, 1KHz, 1E, 19
      Wire.endTransmission();
      
      Wire.beginTransmission(GYRO_ADDR);
      Wire.send(INT_CFG);
      Wire.send(0x00);
      Wire.endTransmission();
}
void getGyroscopeData()
{
      int gyro = 0;
      /**************************************
            Gyro ITG-3200 I2C
            registers:
            x axis MSB = 1D, x axis LSB = 1E
            y axis MSB = 1F, y axis LSB = 20
            z axis MSB = 21, z axis LSB = 22
      **************************************/
      // Arduino Wire library (I2C)
      Wire.beginTransmission(GYRO_ADDR);
      Wire.send(0x1D); // MSB x axis
      Wire.endTransmission();
      Wire.requestFrom(GYRO_ADDR, 1); // one byte
      byte msb = 0;
      byte lsb = 0;
      while(!Wire.available())
      {
            // wait for data to be available
      };
            msb = Wire.receive();
      
      Wire.beginTransmission(GYRO_ADDR);
      Wire.send(0x1E); // LSB x axis
      Wire.endTransmission();
      Wire.requestFrom(GYRO_ADDR, 1); // one byte
      
      while(!Wire.available())
      {
            // wait for data to be available
      };
             lsb = Wire.receive();
      
      // calculate total x axis
      gyro = (( msb << 8) | lsb); 
      Serial.print(" gyroX= "); Serial.print(gyro);
      
      // clear variables
      msb = 0; 
      lsb = 0; 
      gyro = 0; 
      
      Wire.beginTransmission(GYRO_ADDR);
      Wire.send(0x1F); // MSB y axis
      Wire.endTransmission();
      Wire.requestFrom(GYRO_ADDR, 1); // one byte
      
      while(!Wire.available())
      {
            // wait for data to be available
      };
             msb = Wire.receive();
      
      Wire.beginTransmission(GYRO_ADDR);
      Wire.send(0x20); // LSB y axis
      Wire.endTransmission();
      Wire.requestFrom(GYRO_ADDR, 1); // one byte
      
      while(!Wire.available())
      {
            // wait!
      };
             lsb = Wire.receive();
      
      // calculate total y axis
      gyro = (( msb << 8) | lsb);
      Serial.print(" gyroX= "); Serial.print(gyro);
      
      // clear variables
      msb = 0;
      lsb = 0;
      gyro = 0;
      
      Wire.beginTransmission(GYRO_ADDR);
      Wire.send(0x21); // MSB z axis
      Wire.endTransmission();
      Wire.requestFrom(GYRO_ADDR, 1); // one byte
      
      while(!Wire.available())
      {
            // wait...
      };
             msb = Wire.receive();
      
      Wire.beginTransmission(GYRO_ADDR);
      Wire.send(0x22); // LSB z axis
      Wire.endTransmission();
      Wire.requestFrom(GYRO_ADDR, 1); // one byte
      
      while(!Wire.available())
      {
            // ...
      };
             lsb = Wire.receive();
      
      // calculate z axis
      gyro = (( msb << 8) | lsb);
      Serial.print(" gyroZ= "); Serial.println(gyro);

}

void setup()
{
      Serial.begin(9600);
      Wire.begin();
      initGyro();
}

void loop()
{
      getGyroscopeData();
      
      delay(500);
}

@levigot Thank You :) , this is working for me too No need of Level Translators..

Hi everyone.

levigot, I'm starting up with a ITG-3200 and also writing a lib! :)

As this is my 1st LIB I would like someone to have a look a it...

If anyone is interested download available at:

code.google.com/p/itg-3200driver/

Regards, flipo