5 years, 7 months ago.

I2C Communication

I am having L3G4200D gyroscope sensor communicate to Mbed LPC 1768 Through I2C. I manage to get the correct output if I only read the output of one axis. The output angle is not right when I want to read the data from all axis. The output is reduced and gives me around 20 degrees when I actually turned about 90 degrees. It seems that all of the axes are having the same issue and the errors are constant. Anyone experience this issue before?

include the mbed library with this snippet

#include "mbed.h"

I2C i2c(p9, p10); 
Serial pc(USBTX, USBRX);
Thread angleThread;

const int Addr_Write = 0xD2;
const int Addr_Read = 0xD3; 
const int regAddr = 0x0F;
const int CTRL_REG1 = 0x20; 
const int CTRL_REG2 = 0x21;
const int CTRL_REG3 = 0x22;
const int CTRL_REG4 = 0x23;
const int CTRL_REG5 = 0x24; 
const int OUT_X_H = 0x29;
const int OUT_X_L = 0x28; 
const int OUT_Y_H = 0x2B;
const int OUT_Y_L = 0x2A; 
const int OUT_Z_H = 0x2D;
const int OUT_Z_L = 0x2C;

char data_WhoAmI[1] = {0}; 
char data_xH[1] = {0};
char data_xL[1] = {0};
char data_yH[1] = {0};
char data_yL[1] = {0}; 
char data_zH[1] = {0};
char data_zL[1] = {0};

float sensitivity = 0.0175; 
float x_dAngle = 0.0000;
float y_dAngle = 0.0000;
float z_dAngle = 0.0000;
float x_angle = 0.0000;
float y_angle = 0.0000;
float z_angle = 0.0000;
float sum = 0.0000;
float offset = 0.0000; 
float dt = 0.02; 
int16_t x_combineValue = 0;
int16_t y_combineValue = 0;
int16_t z_combineValue = 0;


void readData() {
    char xAxis_H[1] = {OUT_X_H};
    i2c.write(Addr_Write, xAxis_H, 1);
    i2c.read(Addr_Read, data_xH, 1);
    
    char xAxis_L[1] = {OUT_X_L};
    i2c.write(Addr_Write, xAxis_L, 1);
    i2c.read(Addr_Read, data_xL, 1);
    
    x_combineValue = data_xH[0] << 8 | data_xL[0];
    
    char yAxis_H[1] = {OUT_Y_H};
    i2c.write(Addr_Write, yAxis_H, 1);
    i2c.read(Addr_Read, data_yH, 1);
    
    char yAxis_L[1] = {OUT_Y_L};
    i2c.write(Addr_Write, yAxis_L, 1);
    i2c.read(Adrr_Read, data_yL, 1);
    
    y_combineValue = data_yH[0] << 8 | data_yL[0];
    
    char zAxis_H[1] = {OUT_Z_H}; 
    i2c.write(Addr_Write, zAxis_H, 1);
    i2c.read(Addr_Read, data_zH, 1);
        
    char zAxis_L[1] = {OUT_Z_L};
    i2c.write(Addr_Write, zAxis_L, 1);
    i2c.read(Addr_Read, data_zL, 1);
        
    z_combineValue = data_zH[0] << 8 | data_zL[0];
    wait_ms(20);
}
 
/* void calibration() {
    pc.printf("Calibrating Offset...");
    for (int i=0; i<200; i++){
        readData();
        z_dAngle = sensitivity* z_combineValue;
        sum = sum + z_dAngle*dt;
    }
    offset = sum/200;
}*/ 

void readGyro() {
    
    while(1) {
            
        readData();
        
        x_dAngle = sensitivity * x_combineValue;
        x_angle = x_angle + x_dAngle*dt;
        
        y_dAngle = sensitivity * y_combineValue;
        y_angle = y_angle + y_dAngle * dt;
        
        z_dAngle = sensitivity * z_combineValue;
        z_angle = z_angle + z_dAngle*dt;
        
        pc.printf("%f %f %f\n", x_angle, y_angle, z_angle);
    }
}

int main() {
    
    i2c.frequency(400000);
    
    char WHO_AM_I[1] = {regAddr};
    i2c.write(Addr_Write, WHO_AM_I, 1);
    i2c.read(Addr_Read, data_WhoAmI, 1);
    pc.printf("SAD is 0x%X\n", data_WhoAmI[0]);
    
    char ctrl_reg1[2] = {CTRL_REG1,0xBF};
    i2c.write(Addr_Write, ctrl_reg1, 2);
    
    char ctrl_reg2[2] = {CTRL_REG2, 0x00};
    i2c.write(Addr_Write, ctrl_reg2, 2);

    char ctrl_reg3[2] = {CTRL_REG3, 0x00};
    i2c.write(Addr_Write, ctrl_reg3, 2);
    
    char ctrl_reg4[2] = {CTRL_REG4, 0x10};
    i2c.write(Addr_Write, ctrl_reg4, 2); 
    
    char ctrl_reg5[2] = {CTRL_REG5, 0x00};
    i2c.write(Addr_Write, ctrl_reg5, 2);
    
    wait(0.5);
    angleThread.start(readGyro);
    
    while(1) {       
    }
}
Be the first to answer this question.