L3G4200D gyroscope output values

Go To Last Post
11 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi,

I am trying to read the output data of the L3G4200D gyrosensor. However, I am bit confused as to how interpret the output data. There are two output registers for each axis (OUT_N_L, OUT_N_H, where N= X,Y, or Z). For the x-axis for instance, if I read the OUT_X_H, the output data I get is from the range 0-255, if I read OUT_X_L however, the data is not stable at all, and it's constantly changing even when I'm not moving the gyro. Which one should I read (OUT_X_L or OUT_X_H)?

This is how I'm reading it:

writeByte(GYRADDR,CTRL_REG1, 0b00001111); // |DR1|DR0|BW1|BW0|PD|Zen|Yen|Xen| ... Xen, Yen, Zen, and PD must be 1

int16_t out_x, out_y, out_z; // Gyroscope output

 while(1){
    /* Gyrosensor output */
    //out_x = ReadByte(GYRADDR,OUT_X_H);
}

out_x is giving me values from 0-255 only though, why?

Thanks in advance.

P.S The TWI functions seem to work OK... Readbyte() is a int16_t function. I'm unable to post the whole code because I get an error message from this website's server.

*EDIT: Here is the code: http://hostcode.sourceforge.net/view/996

Last Edited: Sun. Sep 8, 2013 - 11:12 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

lcruz007 wrote:
Which one should I read (OUT_X_L or OUT_X_H)?

    //out_x = ReadByte(GYRADDR,OUT_X_H);

out_x is giving me values from 0-255 only though, why?


I haven't worked with the chip, so my comments are based on just what I read in the datasheet.

Out_X is a 16-bit value.
Out_X_L & Out_X_H are each 8-bit values.
So,

int16_t  Out_X, Out_X_L, Out_X_H;
// read Out_X_L & Out_X_H from chip
Out_X = (Out_X_H << 8) + Out_X_L;

If the function name is accurate, ReadByte(...) reads only an 8-bit value from the chip (a byte) even though the return value is int16_t.

As to why Out_N_L is noisy, did you connect the RC filter to the PLLFILT pin as shown in the datasheet?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Chuck99 wrote:
lcruz007 wrote:
Which one should I read (OUT_X_L or OUT_X_H)?

    //out_x = ReadByte(GYRADDR,OUT_X_H);

out_x is giving me values from 0-255 only though, why?


I haven't worked with the chip, so my comments are based on just what I read in the datasheet.

Out_X is a 16-bit value.
Out_X_L & Out_X_H are each 8-bit values.
So,

int16_t  Out_X, Out_X_L, Out_X_H;
// read Out_X_L & Out_X_H from chip
Out_X = (Out_X_H << 8) + Out_X_L;

If the function name is accurate, ReadByte(...) reads only an 8-bit value from the chip (a byte) even though the return value is int16_t.

As to why Out_N_L is noisy, did you connect the RC filter to the PLLFILT pin as shown in the datasheet?

Thank you, that really helps.

I did not add that filter. I am actually using an already assembled board with that gyroscope embedded, it's the Minimu-9 (http://www.pololu.com/catalog/pr...). I don't see the PLLFILT pin on the board, so I'm assumming that the board has already the RC circuit, but I'd have to check that... But still, OUT_N_L is really noisy.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi,

I am combining the two bytes into a single variable now by doing this:

    out_x = (ReadByte(GYRADDR,OUT_X_H)<<8) | ReadByte(GYRADDR,OUT_X_L);
    out_y = (ReadByte(GYRADDR,OUT_Y_H)<<8) | ReadByte(GYRADDR,OUT_Y_L);
    out_z = (ReadByte(GYRADDR,OUT_Z_H)<<8) | ReadByte(GYRADDR,OUT_Z_L);

However, OUT_N_L is really noisy. These are the values I am getting when the L3G400D is completely static.

out_x, out_y, out_z
44,-26,-26
18,-40,10
34,-32,12
41,-33,-6
-4,-27,207
23,-31,43
28,-19,12
1,-26,-1
-243,-26,227
18,-20,-6
36,-47,2

Does that seem normal? Since I am using the MinIMU-9, the chip has the low-pass filter already (http://b.pololu-files.com/pictur...).

What's wrong with my data? (OUT_N_H returns 0 when the gyroscope is not moving, but OUT_N_L is really noisy).

Thanks in advance.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

lcruz007 wrote:
What's wrong with my data? (OUT_N_H returns 0 when the gyroscope is not moving, but OUT_N_L is really noisy).

Pololu wrote:
Discontinuation notice: This board has been replaced by the newer MinIMU-9 v2 L3GD20 and LSM303DLHC carrier, which offers improved magnetic sensing resolution, a wider acceleration measurement range, and gyro measurements that are more resistant to audio noise and vibrations.

I don't know if that is causing your noise problem, but the image below from Pololu shows output from the Gyro converted to degrees, and is not as noisy.

What gain setting (range) are you using?

Attachment(s): 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Do you have to read the OUT_n_L and OUT_n_H registers in a particular order? This line:

Quote:
In read_burst mode, when data included in OUT_Z_H is read, the system again starts to read information from addr OUT_X_L.
seems to indicate that OUT_n_L needs to be read first, but I could find no other clear indication that this is a required order.

Regards,
Steve A.

The Board helps those that help themselves.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Chuck99: I just changed the sensitivity to 2000dps, which seems to improve the stability of the output, but still it's noisy.

This is the output I am getting when the gyroscope is completely static:

out_x,out_y,out_z:
1,-3,-13
-2,1,-3
0,-1,-8
-3,-1,-4
-5,2,-6
0,0,-2
2,-1,-9
252,3,-11
-4,0,-5
0,-1,-5
1,4,-7
-4,-1,-5
-3,2,-9
-3,4,-6
-8,1,-8
-1,4,-11
-3,2,-3
-2,0,-9

Koshchi: I don't know if they have to be read in a particular order, but I have seen others' code and they read it like I'm reading it:

out_x = (ReadByte(GYRADDR,OUT_X_H)<<8) |ReadByte(GYRADDR,OUT_X_L);

I came across this post where the user posted the code for the L3G4200D gyro and he describes a similar problem than the one I'm having: http://bildr.org/2011/06/l3g4200d-arduino/

Am I suppose to ignore that and assume that the output data is normal (others seem to have this problem too)?

Since I'm unable to post the whole code on the forums (I get an exception from avrfreaks' server), I posted it in another site, please take a look at the source code: http://hostcode.sourceforge.net/view/996

Does everything seems fine according to the datasheet?

Thanks in advance.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

lcruz007 wrote:
This is the output I am getting when the gyroscope is completely static:

out_x,out_y,out_z:
1,-3,-13
-2,1,-3
0,-1,-8
-3,-1,-4
-5,2,-6
0,0,-2
2,-1,-9
252,3,-11
-4,0,-5
0,-1,-5
1,4,-7
-4,-1,-5
-3,2,-9
-3,4,-6
-8,1,-8
-1,4,-11
-3,2,-3
-2,0,-9


Except for the 252, it doesn't look all that bad.
I think that 252 should have been a -4, but because you are reading the data from the Gyro asynchronously (you are not synchronizing with the 'Data Ready' flag from the Gyro), you get a new _L mixed with the old _H giving the erroneous result.

As Koshchi suggested, try reversing the _L & _H when reading the data.

// change this
    out_x = (ReadByte(GYRADDR,OUT_X_H)<<8) | ReadByte(GYRADDR,OUT_X_L);

// to this 
    out_x = ReadByte(GYRADDR,OUT_X_L) | (ReadByte(GYRADDR,OUT_X_H)<<8);

// for x,y, & z
  

A better approach, though it involves more work, is to use Block Data Update where "output registers not updated until MSB and LSB reading." The default setting is Continous Update. See Table 31 in the datasheet.

You should read all 6 data bytes in a single I2C read operation by using the address auto-increment feature (see datasheet page 22):

Quote:
Once a slave acknowledge (SAK) has been returned, an 8-bit sub-address is transmitted. The 7 LSb represent the actual register address while the MSB enables address auto-increment. If the MSb of the SUB field is 1, the SUB (register address) is automatically incremented to allow multiple data read/write.

So create a function such as:
Read6Bytes(GYRADDR,(OUT_X_L | 0x80));
which puts the 6 data bytes into an array.
Then pull the data from the array for the 3 axes.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Chuck99 wrote:

Except for the 252, it doesn't look all that bad.
I think that 252 should have been a -4, but because you are reading the data from the Gyro asynchronously (you are not synchronizing with the 'Data Ready' flag from the Gyro), you get a new _L mixed with the old _H giving the erroneous result.

As Koshchi suggested, try reversing the _L & _H when reading the data.

// change this
    out_x = (ReadByte(GYRADDR,OUT_X_H)<<8) | ReadByte(GYRADDR,OUT_X_L);

// to this 
    out_x = ReadByte(GYRADDR,OUT_X_L) | (ReadByte(GYRADDR,OUT_X_H)<<8);

// for x,y, & z
  

A better approach, though it involves more work, is to use Block Data Update where "output registers not updated until MSB and LSB reading." The default setting is Continous Update. See Table 31 in the datasheet.

You should read all 6 data bytes in a single I2C read operation by using the address auto-increment feature (see datasheet page 22):

Quote:
Once a slave acknowledge (SAK) has been returned, an 8-bit sub-address is transmitted. The 7 LSb represent the actual register address while the MSB enables address auto-increment. If the MSb of the SUB field is 1, the SUB (register address) is automatically incremented to allow multiple data read/write.

So create a function such as:
Read6Bytes(GYRADDR,(OUT_X_L | 0x80));
which puts the 6 data bytes into an array.
Then pull the data from the array for the 3 axes.

Thanks Chuck, I'll take a look into that and post my progress here!

Thank you.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hey all,

I finally could get a relatively stable reading from the gyroscope. I'm not reading all those bytes at the same time yet. But since _L is the byte with more noise, I am using _H to determine if the the gyroscope if moving or not, if it's not, I am just ignoring the values I get when combining these two bytes.

After integrating all the values with respect to time, I get a very close approximation of the actual degrees the gyro is being tilted. However, because of the gyro-drift the data becomes useless after a while. Since I cannot use a low-pass filter with the accelerometer to compensate for the gyro drift (I need the high-frequency data from the accelerometer too), I might use a tilt sensor to reset the gyro values when it's on a determined position.

I will try this and post my results. Thanks to everyone!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

How do you solved this problem ,I sent a private message