Help with gy-80

Hello!! I’ve decided to take up robotics as a hobby for the holidays and am building a simple IMU based quad. The sensor I have chosen is GY-80 (10 DOF IMU), it has an accelerometer, a gyroscope, a barometer and a magnetometer. I am presently concentrating on the accelrometer ADXL345 and the gyro L3G4200D. Currently, my only goal is to read the data from these 2 sensors using a single program.

I have never interfaced any sensor , i/p, o/p devices before and this is my first learning experience. I came across some links which had programs on reading data from these individual sensors and they worked fine individually. But when I used my understanding to put these 2 pieces of code together, I failed big time (clearly bad understanding). I am able to read the data from the gyro but the accelerometer reads (0,0,0) for (X,Y,Z).

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Arduino 1.0+ only

#include <Wire.h>

#define gyro_CTRL_REG1 0x20
#define gyro_CTRL_REG2 0x21
#define gyro_CTRL_REG3 0x22
#define gyro_CTRL_REG4 0x23
#define gyro_CTRL_REG5 0x24

#define accel_CTRL_REG1 0x2D
#define accel_CTRL_REG2 0x31
#define accel_CTRL_REG3 0x2C

int gyro_Address = 105; //I2C address of the L3G4200D
int accel_Address = 83; //I2C address of the ADXL345

// gyro variables
int roll_rate;
int pitch_rate;
int yaw_rate;

//accelerometer variables
int accel_x;
int accel_y;
int accel_z;

void setup(){

Wire.begin();
Serial.begin(9600);

Serial.println(“starting up L3G4200D and ADXL345”);

setupL3G4200D(250); // Configure L3G4200 - 250, 500 or 2000 deg/sec
setupADXL345();
delay(1500); //wait for the accelerometer to be ready
}

void loop(){
getGyroValues(); // This will update roll, pitch and yaw rates
getAccelValues(); // This will update x, y and z accelarations

Serial.print(“roll rate:”);
Serial.print(roll_rate);

Serial.print(" pitch rate:");
Serial.print(pitch_rate);

Serial.print(" yaw rate:");
Serial.println(yaw_rate);

Serial.print(“x rate:”);
Serial.print(accel_x);

Serial.print(" y rate:");
Serial.print(accel_y);

Serial.print(" z rate:");
Serial.println(accel_z);

delay(1000); //Just here to slow down the serial to make it more readable
}

void getGyroValues()
{

byte xMSB = readRegister(gyro_Address, 0x29);
byte xLSB = readRegister(gyro_Address, 0x28);
roll_rate = ((xMSB << 8) | xLSB); //The smiley needs to be replaced by eight

byte yMSB = readRegister(gyro_Address, 0x2B);
byte yLSB = readRegister(gyro_Address, 0x2A);
pitch_rate = ((yMSB << 8) | yLSB); //The smiley needs to be replaced by eight

byte zMSB = readRegister(gyro_Address, 0x2D);
byte zLSB = readRegister(gyro_Address, 0x2C);
yaw_rate = ((zMSB << 8) | zLSB); //The smiley needs to be replaced by eight
}

void getAccelValues()
{
byte xaMSB = readRegister(accel_Address, 0x33);
byte xaLSB = readRegister(accel_Address, 0x32);
accel_x = ((xaMSB << 8) | xaLSB); //The smiley needs to be replaced by eight

byte yaMSB = readRegister(accel_Address, 0x35);
byte yaLSB = readRegister(accel_Address, 0x34);
accel_y = ((yaMSB << 8) | yaLSB); //The smiley needs to be replaced by eight

byte zaMSB = readRegister(accel_Address, 0x37);
byte zaLSB = readRegister(accel_Address, 0x36);
accel_z = ((zaMSB << 8) | zaLSB); //The smiley needs to be replaced by eight

}

int setupADXL345()
{
writeRegister(accel_Address,accel_CTRL_REG1,00000000); //Reset
writeRegister(accel_Address,accel_CTRL_REG1,00010000); //Autosleep
writeRegister(accel_Address,accel_CTRL_REG1,00000001); //Turn ON
writeRegister(accel_Address,accel_CTRL_REG1,00001000); //Measure

writeRegister(accel_Address,accel_CTRL_REG2,00001000);

writeRegister(accel_Address,accel_CTRL_REG3,00001001);

}

int setupL3G4200D(int scale)
{
// Enable x, y, z and turn off power down:
writeRegister(gyro_Address, gyro_CTRL_REG1, 0b00001111);

// If you’d like to adjust/use the HPF, you can edit the line below to configure CTRL_REG2:
writeRegister(gyro_Address, gyro_CTRL_REG2, 0b00000000);

// Configure CTRL_REG3 to generate data ready interrupt on INT2
// No interrupts used on INT1, if you’d like to configure INT1
// or INT2 otherwise, consult the datasheet:
writeRegister(gyro_Address, gyro_CTRL_REG3, 0b00001000);

// CTRL_REG4 controls the full-scale range, among other things:

if(scale == 250){
writeRegister(gyro_Address, gyro_CTRL_REG4, 0b00000000);
}else if(scale == 500){
writeRegister(gyro_Address, gyro_CTRL_REG4, 0b00010000);
}else{
writeRegister(gyro_Address, gyro_CTRL_REG4, 0b00110000);
}

// CTRL_REG5 controls high-pass filtering of outputs, use it
// if you’d like:
writeRegister(gyro_Address, gyro_CTRL_REG5, 0b00000000);
}

void writeRegister(int deviceAddress, byte address, byte val) {
Wire.beginTransmission(deviceAddress); // start transmission to device
Wire.write(address); // send register address
Wire.write(val); // send value to write
Wire.endTransmission(); // end transmission
}

int readRegister(int deviceAddress, byte address){

int v;
Wire.beginTransmission(deviceAddress);
Wire.write(address); // register to read
Wire.endTransmission();

Wire.requestFrom(deviceAddress, 1); // read a byte

while(!Wire.available()) {
// waiting
}

v = Wire.read();
return v;
}
////////////////////////////////////////////////////////////////////////////////////////////////

That is the code I have put together. I will be thankful for anyone guiding me in the right direction here. Again I am a total noob here, so please excuse any level of stupidity found in the code.

Thanks
:slight_smile:

There is nothing obviously wrong with your approach, that I can see.

There are several things you to do, to check what is going wrong. Can you actually communicate with both the gyro and the accelerometer devices ? Try running the sketch which checks what I2C devices are present, and check that you get a response from both devices.

Try writing a sketch which only communicates with one device. See if it works that way. You can do this by just deleting about 45% of the code in your existing sketch. Delete either the gyro code or the accelerometer code to make a shorter sketch.

Read the instructions for the device carefully, to make sure you have not omitted some important step to initialise the device.

In setupADXL345() you appear to be trying to write an 8-bit pattern to the chip. But I don't think you can express an 8-bit pattern simply as 100001100 , that will be a billion, it won't be a bit pattern, you need to express it as a hexadecimal byte, like 0xA4 or something. There is also a syntax for binary, i forget what it is, but it isn't what you did.

michinyon: I don't think you can express an 8-bit pattern simply as 100001100 , that will be a billion, it won't be a bit pattern, you need to express it as a hexadecimal byte, like 0xA4 or something. There is also a syntax for binary,

0b100001100

Thank you so much, Michinyon & Tylernt. That worked!! I now understand that ‘0b’ is a prefix to an 8-bit value to designate it as binary. :slight_smile:

After burning the code into the arduino, I was observing the readings on the serial moniter, the Z-accelaration was not really fluctuating on the accelerometer. It was staying fixed at "511’ as shown in the image. Is this a hardware problem or some error in the code?

Thanks a lot!!

Were you moving the accelerometer?

Yes I was moving the entire setup, even allowing a free fall to see if "accel_Z" changes.

Never mind. I found it. The key was to turn on the full scale resolution, ie to set the bits 0,1 and 3 of register 0X31 to be 1.

Thanks for the help with point one though. :D