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