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

what is the problem please

One problem is that you failed to post a link to the mysterious "L3G4200D".

Another problem is that you are doing Serial output, which requires that interrupts be enabled, in an ISR, where interrupts are disabled.

Another problem is that the ISR calls getGyroValues() and so does loop(). Only one of them should.

Another problem is that z is updated by an ISR, but is not volatile, so loop() doesn't know that z might have changed. ALL variables written to be an ISR and used by other functions MUST be volatile.

Hi i didn’t understand, could you modify my code please :slight_smile:

jone31:
Hi i didn't understand, could you modify my code please :slight_smile:

What's not to understand?

PaulS:
One problem is that you failed to post a link to the mysterious "L3G4200D".

So post us a link to the part. That's not hard. I don't see how we would modify your code without knowing the part in question.

PaulS:
Another problem is that you are doing Serial output, which requires that interrupts be enabled, in an ISR, where interrupts are disabled.

Just take the serial code out of the interrupt handlers. What's hard to understand about that? Highlight any line in the ISR that starts with Serial and press delete.

PaulS:
Another problem is that the ISR calls getGyroValues() and so does loop(). Only one of them should.

Again, this is real easy. Either let the ISR call that function or let loop call that function. The calls to the function from one or the other should be deleted. What's hard to understand about that?

PaulS:
Another problem is that z is updated by an ISR, but is not volatile, so loop() doesn't know that z might have changed. ALL variables written to be an ISR and used by other functions MUST be volatile.

OK, so make z a volatile variable. Where you define that variable, put the word volatile in front of it. What's hard about that?

Ok i change my code, i will make it verry simple

int i;
volatile float xcall;
volatile float roll, r;
// get value from x axe
int X()
{
	byte lx, hx;
	Wire.beginTransmission(105);
	Wire.write(0X28);
	Wire.endTransmission();
	Wire.requestFrom(105, 1);
	while (!Wire.available());

	lx = (Wire.read());

	Wire.beginTransmission(105);
	Wire.write(0X29);
	Wire.endTransmission();
	Wire.requestFrom(105, 1);
	while (!Wire.available());

	hx = (Wire.read());

	r = (hx << 8 | lx);
	if (i == 2000)       // for the calibraation
	r -= xcall;
	return r;

}
// gyro initialisation
void initgyro()
{

	Wire.begin();
	Wire.beginTransmission(105);                      
	Wire.write(CTRL_REG1);                                
	Wire.write(0x0F);                                 
	Wire.endTransmission();                            

	Wire.beginTransmission(105);                      
	Wire.write(CTRL_REG4);                                
	Wire.write(0b10000000);                                  
	Wire.endTransmission();                            
	delay(500);
}

void setup()
{
initgyro();

//define the offset
	for (i = 0; i < 2000; i++)
	{
		xcall += X();
		if (i % 100 == 0)
			Serial.print(".");
		delay(5);
	}
}

void loop()
{
roll = X()* 0.00875;

integ(roll); // convert dps to degree

Serial.println(integ(roll)); 

}

When i move slowly and i put the gyro on the grounde i have 0 degree but when u moove it a lot, after i put it on the grounde i have not 0 degree even i declare volatile variable.

Why does X() return r? There is NOTHING about those names that makes any sense.

You don't seem to understand that gyroscopes drift. The more you shake and manhandle them, the more they drift.

But still no link to the device

PaulS:
Why does X() return r?

it's for the calibration.
i know the gyro drift but how do you explain , the developers of quadcopter do ??
even you shake a lot the quadcopter is stable !!

it's for the calibration.

So, why not call the function FSAVJATSRTAVA() and have it return dAGasdhzscVNmzxcNuo?

Stupid names do not cut it!

i know the gyro drift but how do you explain , the developers of quadcopter do ??
even you shake a lot the quadcopter is stable !!

So, they account for drift. Why don't you?