Any chance to prevent drift on a 3DOF gyro?
hi,
i played around l3g4200d 3dof gyro sensor using sparkfuns example code.
actually need x-axis, sort_of_stable output, when don't move sensor.
i had eliminate zero-point errors, there.
but unfortunately, huge drift when move sensor , put starting position.
is there chance eliminate drift 1 3dof sensor, or need 3dof accelerometer sensor too?
i haven't found l3g4200d, using fifo registers here?
also couldn't find out yet bandwidth provide best accuracy.
<edit> math behind x_angle value not final now. i'm not sure how cope interupt routine , millis()-readings.
i played around l3g4200d 3dof gyro sensor using sparkfuns example code.
actually need x-axis, sort_of_stable output, when don't move sensor.
i had eliminate zero-point errors, there.
but unfortunately, huge drift when move sensor , put starting position.
is there chance eliminate drift 1 3dof sensor, or need 3dof accelerometer sensor too?
i haven't found l3g4200d, using fifo registers here?
also couldn't find out yet bandwidth provide best accuracy.
<edit> math behind x_angle value not final now. i'm not sure how cope interupt routine , millis()-readings.
code: [select]
/* l3g4200d 3-axis gyro example code
by: jim lindblom
sparkfun electronics
date: 4/18/11
license: cc-sa 3.0 - use code you'd like, ask
for attribution. , let know if you've improved anything!
circuit:
l3g4200d breakout-------------arduino uno
gnd-----------------------------gnd
vcc-----------------------------3.3v
scl-----------------------------d13
sda-----------------------------d11
sdo-----------------------------d12
cs------------------------------d10
int2/dr-------------------------d6
int1----------------------------d7
this example code intended use st. microelectronics'
l3g4200d triple-axis digital gyroscop. l3g4200d capable of
both i2c , spi communications, we'll use spi in example.
this code sets l3g4200d's 5 control registers, ,
streams data 3 axes on serial monitor @ 9600bps.
*/
#include <spi.h>
#include "l3g4200d.h"
#include <wire.h>
#include <liquidcrystal_i2c.h> //sainsmart test library 20x4 i2c lcd
// pin definitions
const int int2pin = 6;
const int int1pin = 7;
const int chipselect = 10;
// gyro reading
int x;
int x_angle =0; //start sensor top down on flat surface
int x_offset = 15; // that's average value when sensor isn't moving
int show_angle = 0;
liquidcrystal_i2c lcd(0x27,20,4); // set lcd address 0x27 20x4 display
void setup()
{
lcd.init();
lcd.init(); // initialize lcd twice
lcd.backlight();
lcd.setcursor(3,0);
lcd.print("l3g4200d test");
// start spi library:
spi.begin();
spi.setdatamode(spi_mode3);
spi.setclockdivider(spi_clock_div8);
pinmode(int1pin, input);
pinmode(int2pin, input);
pinmode(chipselect, output);
digitalwrite(chipselect, high);
delay(100);
setupl3g4200d(2); // configure l3g4200 selectabe full scale range
// 0: 250 dps
// 1: 500 dps
// 2: 2000 dps
}
void loop()
{
// don't read gyro values until gyro says it's ready
while(!digitalread(int2pin));
getgyrovalues(); // update x new values
x+= x_offset; //eliminate 0 offset , ignore small changes minimize drift
if (!( x < 7 && x > -7 )){
x_angle += x;
} // end if
show_angle += 1; // try read data fast possible send data every 50 loops
if (show_angle == 50 ){
lcd.setcursor(2,2);
lcd.print("raw x ");
lcd.print(x, dec);
lcd.print(" "); // erase bigger values screen
lcd.setcursor(2,3);
lcd.print("pitch ");
lcd.print(x_angle, dec);
lcd.print(" ");
show_angle = 0;
} // end if
} // end loop
int readregister(byte address)
{
int toread;
address |= 0x80; // tells l3g4200d we're reading;
digitalwrite(chipselect, low);
spi.transfer(address);
toread = spi.transfer(0x00);
digitalwrite(chipselect, high);
return toread;
}
void writeregister(byte address, byte data)
{
address &= 0x7f; // tell l3g4200d we're writing
digitalwrite(chipselect, low);
spi.transfer(address);
spi.transfer(data);
digitalwrite(chipselect, high);
}
int setupl3g4200d(byte fullscale)
{
// let's first check we're communicating properly
// who_am_i register should read 0xd3
if(readregister(who_am_i)!=0xd3)
return -1;
// enable x, y, z , turn off power down:
writeregister(ctrl_reg1, 0b00001111);
// if you'd adjust/use hpf, can edit line below configure ctrl_reg2:
writeregister(ctrl_reg2, 0b00000000);
// configure ctrl_reg3 generate data ready interrupt on int2
// no interrupts used on int1, if you'd configure int1
// or int2 otherwise, consult datasheet:
writeregister(ctrl_reg3, 0b00001000);
// ctrl_reg4 controls full-scale range, among other things:
fullscale &= 0x03;
writeregister(ctrl_reg4, fullscale<<4);
// ctrl_reg5 controls high-pass filtering of outputs, use it
// if you'd like:
writeregister(ctrl_reg5, 0b00000000);
}
int getgyrovalues()
{
x = (readregister(0x29)&0xff)<<8;
x |= (readregister(0x28)&0xff);
}
the value gyro "rate of change" (degrees per second). think have multiply time period in order actual degrees. gyroscope free-runing or reading of register trigger new reading?
if don't need full 2000 degrees-per-second range might want turn down full-scale range make more sensitive.
if don't need full 2000 degrees-per-second range might want turn down full-scale range make more sensitive.
Arduino Forum > Using Arduino > Sensors > Any chance to prevent drift on a 3DOF gyro?
arduino
Comments
Post a Comment