L3GD20 Gyro questions
Moderators: adafruit_support_bill, adafruit

L3GD20 Gyro questions

by gildorr on Mon Dec 03, 2012 1:48 pm

I've been playing around with a L3GD20 gyro breakout board for a couple days now, and the results that I'm getting are not quite what I expect. I'm trying to determine if the problem is in my understanding of the board output, the method I'm using in my code, or my math. To keep things simple, I'm only looking at a single axis at the moment.

The gyro data looks to be a 16 bit signed value, from which I have assumed a data value of 32768, with the gyro initialed at 500DPS, equals the board rotating at 500 degree/s , and -32768 would be 500 degree/s in the opposite direction. Is my understanding of the board output correct?

I'm using that data, plus timing from millis() to try to determine the current position of the board. I'm going to be using the gyro data to control colors using the color wheel code on a strand of WS2801, so I'm converting a 360 degree circle into 256 positions. You can see below the code I'm using in my testing. I've noticed the data contains a fair bit of noise, so I'm excluding any values between -200 and 200.

My expectation is that 1 full rotation around the x axis should result in a change of position of 256, in practice though it winds up taking about 1 1/2 - 2 full rotations to measure 256. I realize that an accelerometer might be better for what I'm trying to do, and I will probably add one to my project, but any direction on getting my gyro code working would be greatly appreciated.

[Edit - moderator - please use the 'code' button when submitting code]
Code: Select all | TOGGLE FULL SIZE
#include <Wire.h>
#include <Adafruit_L3GD20.h>

// By default, uses I2C
//Adafruit_L3GD20 gyro;
// Alternately, you can use SPI, but you have to define the pins
#define GYRO_CS 4 // labeled CS
#define GYRO_DO 5 // labeled SA0
#define GYRO_DI 8  // labeled SDA
#define GYRO_CLK 7 // labeled SCL
Adafruit_L3GD20 gyro(GYRO_CS, GYRO_DO, GYRO_DI, GYRO_CLK);

float pos=0;
unsigned long last_time, this_time, diff_time;

void setup()
{
  Serial.begin(9600);
  if (!gyro.begin(gyro.L3DS20_RANGE_500DPS))
  {
    Serial.println("Oops ... unable to initialize the L3GD20. Check your wiring!");
    while (1);
  }
  last_time=millis();
}

void loop()
{
  gyro.read(); 
  this_time=millis();
  diff_time=this_time-last_time;
  last_time=this_time;
  if (gyro.data.x>200||gyro.data.x<-200)
    {pos+=diff_time*gyro.data.x/92160;}
  Serial.print("X: "); Serial.print((int)gyro.data.x);   Serial.print(" ");
  Serial.print("POS: "); Serial.println((float)pos);   Serial.print(" ");
}
gildorr
 
Posts: 4
Joined: Wed Oct 10, 2012 6:35 pm

Re: L3GD20 Gyro questions

by adafruit_support_bill on Mon Dec 03, 2012 2:12 pm

What are your loop times? You may be getting some cumulative round-off error on your calculations.
User avatar
adafruit_support_bill
 
Posts: 29782
Joined: Sat Feb 07, 2009 9:11 am

Re: L3GD20 Gyro questions

by gildorr on Mon Dec 03, 2012 2:54 pm

At the moment I'm letting the loop run as fast as it can, using millis to calculate the run time each loop. I've added a delay of 5-20ms and the results were pretty much the same. Adding a delay of 100+ms and I wound up with data being inconsistent.
gildorr
 
Posts: 4
Joined: Wed Oct 10, 2012 6:35 pm

Re: L3GD20 Gyro questions

by adafruit_support_bill on Mon Dec 03, 2012 5:39 pm

And roughly how fast (in degrees per second) are you actually rotating the sensor during your tests? Does the rotation speed affect the magnitude of the error?
User avatar
adafruit_support_bill
 
Posts: 29782
Joined: Sat Feb 07, 2009 9:11 am

Re: L3GD20 Gyro questions

by gildorr on Tue Dec 04, 2012 10:37 am

I would estimate 3-5 seconds per rotation in my testing, so around 70-120 degrees / second. The only increase in error that I've noticed directly related to rotation speed occurs when I move the sensor faster than the maximum set speed, 500 degrees / second in my case.
gildorr
 
Posts: 4
Joined: Wed Oct 10, 2012 6:35 pm

Re: L3GD20 Gyro questions

by adafruit_support_bill on Tue Dec 04, 2012 10:55 am

Doing a little research, the measurement range and sensitivity of MEMS gyro sensors varies quite a bit from sample to sample & they do need to be calibrated. Once calibrated however, the sensitivity remains very stable over time.

Analog has a nice white-paper on the subject.
http://www.analog.com/static/imported-f ... 7_2010.pdf
User avatar
adafruit_support_bill
 
Posts: 29782
Joined: Sat Feb 07, 2009 9:11 am

Re: L3GD20 Gyro questions

by gildorr on Wed Dec 05, 2012 1:40 pm

The issue appears to be from my assumption that a value of 32768 when in 500DPS mode translated to a rotational speed of 500DPS. I used that to calculate that a gyro.data value of 65.536 (32768/500) was equal to a rate of 1 degree per second. From the data sheet for the gyro, at 500DPS setting the sensitivity for the gyro is .0175 degrees per second per value of gyro.data, so the actual value of gyro.data per degree is 57.142 (1/.0175)

With that change in my code, my rotation is now measured accurate to within about 2-3%, something I hope to improve upon further with a little more noise and DVoff filtering.
gildorr
 
Posts: 4
Joined: Wed Oct 10, 2012 6:35 pm

Re: L3GD20 Gyro questions

by ksilovich on Fri Feb 08, 2013 5:03 am

Any chance you would be willing to post your final code. I cant get any angular position set up on mine. I read the velocity fine.
Thanks
ksilovich
 
Posts: 1
Joined: Fri Feb 08, 2013 5:02 am