L3G4200D problem

Hello, i used this code, to get values of x y z, the probleme when i move the gyro a lot and i put it on the ground, i have not 0 value from all axes, i have wrong values. what is the problem please

//Arduino 1.0+ only

#include <Wire.h>

#define CTRL_REG1 0x20
#define CTRL_REG2 0x21
#define CTRL_REG3 0x22
#define CTRL_REG4 0x23
#define CTRL_REG5 0x24

int L3G4200D_Address = 105; //I2C address of the L3G4200D

int x = 0;
float p_z = 0;
int y;
int z = 0;
float degreesPerSecond = 0;
float gyroRate = 0;
float currentAngle = 0;
float currentAngleDegrees = 0;
long currMillis = 0;
long pastMillis = 0;
long calibrationSum = 0;
int gyroZero = 0;
int gyroHigh = 0;
int gyroLow = 0;
unsigned long currMicros = 0;
unsigned long pastMicros = 0;
float dt = 0;

void setup(){

  Wire.begin();
  Serial.begin(115200);

  Serial.println("starting up L3G4200D");
  setupL3G4200D(2000); // Configure L3G4200  - 250, 500 or 2000 deg/sec

  delay(1500); //wait for the sensor to be ready 
  calibrate();
  attachInterrupt(0, updateAngle, RISING);
}

void loop()
{
  pastMillis = millis();
  getGyroValues();
  
  pastMicros = currMicros;
  currMicros = micros();
  
  if(z >= gyroHigh || z <= gyroLow)
  {
    degreesPerSecond = (float)z * 0.00000085; //this value was 0.0000085 but was manually calibrated to its current value
    if (currMicros>pastMicros)  //micros() overflows/resets every ~70 minutes
      dt = (float) (currMicros-pastMicros)/1000000.0;
    else
      dt = (float) ((4294967295-pastMicros)+currMicros)/1000000.0;
    currentAngle += ((p_z + degreesPerSecond)/2) * dt;
    p_z = degreesPerSecond;
  }
  else 
  {
    p_z = 0;
  }
  Serial.println(currentAngle * 1000);
  delay(10);
}

void updateAngle()
{
  Serial.println("here");
  getGyroValues();
}

void calibrate()
{
  for(int i = 0; i < 4000; i++)
  {
    getGyroValues();

    if(z > gyroHigh)
    {
      gyroHigh = z;
    }
    else if(z < gyroLow)
    {
      gyroLow = z;
    }
  }
}

void getGyroValues(){

  //byte xMSB = readRegister(L3G4200D_Address, 0x29);
  //byte xLSB = readRegister(L3G4200D_Address, 0x28);
  //x = ((xMSB << 8) | xLSB);

  //byte yMSB = readRegister(L3G4200D_Address, 0x2B);
  //byte yLSB = readRegister(L3G4200D_Address, 0x2A);
  //y = ((yMSB << 8) | yLSB);

  byte zMSB = readRegister(L3G4200D_Address, 0x2D);
  byte zLSB = readRegister(L3G4200D_Address, 0x2C);
  z = ((zMSB << 8) | zLSB);
   
}

int setupL3G4200D(int scale){
  //From  Jim Lindblom of Sparkfun's code

  // Enable x, y, z and turn off power down:
  writeRegister(L3G4200D_Address, CTRL_REG1, 0b00001111);

  // If you'd like to adjust/use the HPF, you can edit the line below to configure CTRL_REG2:
  writeRegister(L3G4200D_Address, 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(L3G4200D_Address, CTRL_REG3, 0b00001000);

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

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

  // CTRL_REG5 controls high-pass filtering of outputs, use it
  // if you'd like:
  writeRegister(L3G4200D_Address, CTRL_REG5, 0b00000001);
}

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;
}

Gyros have a zero offset, which needs to be determined and subtracted. That offset will also change with time and temperature.

Thanks, but how to determined and subtracted that offset please :frowning:

Average some readings while the gyro is not moving.

Ok, and after i substruct this value from the gyro ? please could you modify my code please :slight_smile:

Google "arduino calibrate gyro" for lots of code and ideas.

i didn't find good ideas