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.

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.


Arduino Forum > Using Arduino > Sensors > Any chance to prevent drift on a 3DOF gyro?


arduino

Comments

Popular posts from this blog

Convierte tu Raspberry en un NAS. Firmware fvdw-sl 15.3 - Raspberry Pi Forums

How to format a Get Request

avrdude: verification error, first mismatch at byte 0x0000 0x0c != 0x62