Go Down

Topic: Problem With Gyroscope Sensor (L3G4200D) (Read 5931 times) previous topic - next topic

daffigusti

Hi all,
I have a problem on reading Gyroscope sensor on Arduino. I use 10DOF L3G4200D+ADXL345+HMC5883L+BMP085 Nine Axis IMU Module From Here http://www.goodluckbuy.com/10dof-l3g4200dadxl345hmc5883lbmp085-nine-axis-imu-module.html and Iteaduino.
The sensor :


This is My Configuration :
Code: [Select]

Sensor        Arduino
VCC_3.3V ->  3.3v
SDA         ->  A4
SCL         ->  A5
GND        -> GND


And this the code, I got it from this tutorial -> http://forum.bildr.org/viewtopic.php?t=443
Code: [Select]

//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 = 0x69; //I2C address of the L3G4200D

int x;
int y;
int z;

void setup(){

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

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

  delay(1500); //wait for the sensor to be ready
}

void loop(){
   getGyroValues();  // This will update x, y, and z with new values

  Serial.print("X:");
  Serial.print(x);

  Serial.print(" Y:");
  Serial.print(y);

  Serial.print(" Z:");
  Serial.println(z);

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

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, 0b0100000);
}

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


My problem is the values become unstable if I move the sensor at a certain degrees. Please see the image below:


Is there any configuration of the sensor to fix the problem?
thanks in advance.

Krodal

#1
Jul 08, 2012, 11:02 am Last Edit: Jul 08, 2012, 11:06 am by Krodal Reason: 1
This your board: http://iteadstudio.com/store/index.php?main_page=product_info&products_id=467
And this is your code: http://bildr.org/2011/06/l3g4200d-arduino/

You connect the 3.3V of the "Arduino" to the 3.3V of the sensor board. That's good, but the sensor board has a voltage regulator. So instead of the 3.3V connection, you could connect the +5V of the Arduino to the VCC_IN of the sensor board. But perhaps you knew that already.

The sensor board seems to have already 4k7 pull-up resistors at the SDA and SCL lines.

My problem with the code is that it doesn't check for an error. For example Wire.endTransmission() would return an error if the I2C communication went wrong.

I think that your values are okay. They are raw unfiltered sensor values, so some fluctuation is normal. The gyro sensor is not a tilt sensor. An accelerometer can be used as a tilt sensor. It measures the earth gravity (and also vibration) and would detect a 45 degrees angle.
So I think there is no problem to fix.

Search for forum for "L3G4200D", in the past few weeks there has been a few others with questions about this sensor. It might be interesting to read them.

MarkT

All MEMS gyros are "rate-gyros" - this means they produce an output proportional to the rate-of-change of angle, not to the current angle.  This is fundamental to the technology.

To use this to get an estimate of angle you have to sample the output regularly and integrate it.

However even if you get this setup correctly with the right constants and null points it will still drift with time, quite significantly.

Expect the angle to drift by 10 degrees or so in a few tens of seconds _best case_.  The normal procedure is to combine the fast changes from the gyro with a low-pass-filtered estimate of orientation from an accelerometer.
[ I won't respond to messages, use the forum please ]

daffigusti

Thank you all, I am understand now.
I think the sensor is similar with the tilt sensor.

Go Up