L3G4200D Tripple Axis Gyroscope + Arduino

Discussions area for bildr's blog posts.
From: http://bildr.org/2011/06/l3g4200d-arduino/

We have covered, accelerometers, GPSs, compasses... But no gyros. Why? Not sure, but I figured today I would put an end to that, so I grabbed a L3G4200D 3-axis gyro from sparkfun.

The L3G4200D is a 3-axis angula ...
ameyer
Founder
 
Posts: 3327
Joined: Thu Jan 21, 2010 11:59 pm
Location: The Bay Area

from the datasheet, page 10, Digital zero-rate level (DVoff) is listed as +/-75dps when the gyro is in 2000dps mode. This is further explained on page 15 under the section "2.6.2 Zero-Rate Level":

2.6.2 Zero-rate level

Zero-rate level describes the actual output signal if there is no angular rate present. The
zero-rate level of precise MEMS sensors is, to some extent, a result of stress to the sensor
and, therefore, the zero-rate level can slightly change after mounting the sensor onto a
printed circuit board or after exposing it to extensive mechanical stress. This value changes
very little over temperature and time.


awesome blog btw :mrgreen:
vmspionage
 
Posts: 1
Joined: Tue Jun 07, 2011 3:15 pm

Thanks!
Weirdly, lowering the rate to 250, or 500 seemed to make it worse.

vmspionage wrote:from the datasheet, page 10, Digital zero-rate level (DVoff) is listed as +/-75dps when the gyro is in 2000dps mode. This is further explained on page 15 under the section "2.6.2 Zero-Rate Level":

2.6.2 Zero-rate level

Zero-rate level describes the actual output signal if there is no angular rate present. The
zero-rate level of precise MEMS sensors is, to some extent, a result of stress to the sensor
and, therefore, the zero-rate level can slightly change after mounting the sensor onto a
printed circuit board or after exposing it to extensive mechanical stress. This value changes
very little over temperature and time.


awesome blog btw :mrgreen:
ameyer
Founder
 
Posts: 3327
Joined: Thu Jan 21, 2010 11:59 pm
Location: The Bay Area

It seems that units are not deg/sec but rather referenced to full scale. The scale values (sensitivity) from page 10 are : 8.75e-3,17.5e-3, 70e-3 for 250,500,2000 respectively.
schoeny
 
Posts: 3
Joined: Thu Aug 18, 2011 3:38 pm

Wow... Really?
So weird.

Being brain dead right now... and Idea how to implement that?

schoeny wrote:It seems that units are not deg/sec but rather referenced to full scale. The scale values (sensitivity) from page 10 are : 8.75e-3,17.5e-3, 70e-3 for 250,500,2000 respectively.
ameyer
Founder
 
Posts: 3327
Joined: Thu Jan 21, 2010 11:59 pm
Location: The Bay Area

I do the conversion after the fact.
at 2000dps setting use a SCALE factor, I use 18/256 to get dps. Like this:

long t;

t = (((long)x *18))>>8; // >>8 should be better than /256
Serial.print((int)t, DEC);

[repeat for y, z]

other scale values:
250dps setting: 224/256 to get centi-degrees/sec
500 dps: 45/256 to get (roughly) deci-degrees/sec

Personally, I use milliradians/sec (1024 milliradians/radian) so my conversion to radians is simpler. Certianly, knowing what the scale values are is the biggest part.
schoeny
 
Posts: 3
Joined: Thu Aug 18, 2011 3:38 pm

Have you ever noticed that the z-axis sometomes outputs suspiciously large values (absolute)?

Like this:
35 -68 0
32 -65 -5
42 -61 0
28 -66 -7
44 -67 -1
38 -60 -1
47 -64 -4
39 -59 -3
44 -62 -3
38 -65 -1
41 -62 -3
38 -67 3
36 -63 255 <--- I see this about once every 10 seconds.
45 -60 0
39 -63 3
40 -61 0
42 -64 0
46 -66 0
40 -66 -1

I'm planning on putting this on a turntable to see if the glitch is always a 255 in the LSB.
schoeny
 
Posts: 3
Joined: Thu Aug 18, 2011 3:38 pm

To improve the quality of data set BDU (0x80) on CTRL4_REG (0x23) and use multi-byte reads of 6 bytes at once via register 0x28|0x80 (i.e., 0xA8). This is the read-burst version of the X_LOW register.
afanofosc
 
Posts: 1
Joined: Wed Sep 21, 2011 6:29 pm

Hi,

I am trying this mems and I am facing with a problem related to the zero rate level. It changes over time and after few minutes it is higher than before and so I am accumulating errors calculating the angle value. Is it normal ? Does anyone know how to avoid this behaviour ?

sorry, I am new of this topic (and sorry also for my english)

thanks a lot
steteb
 
Posts: 1
Joined: Thu Sep 22, 2011 3:23 pm

Hi everyone !

I am trying to communicate with the same devices but using SPI protocole. The problem is that pins (SCL, SDO, SOA and CS) deliver 5V signals instead of 3.3V. Isn't it dangerous for the MEMS to receive a 5V signal since the power supply shall not be higher than 3.6V? Is it possible to configure the voltage of delivered signals?

Thank you !
Terence
 
Posts: 4
Joined: Mon Sep 19, 2011 10:30 am

The sparkfun example for SPI is using 5v. If you are worried, Id use a logic level converter like this guy:
http://www.sparkfun.com/products/8745


Terence wrote:Hi everyone !

I am trying to communicate with the same devices but using SPI protocole. The problem is that pins (SCL, SDO, SOA and CS) deliver 5V signals instead of 3.3V. Isn't it dangerous for the MEMS to receive a 5V signal since the power supply shall not be higher than 3.6V? Is it possible to configure the voltage of delivered signals?

Thank you !
ameyer
Founder
 
Posts: 3327
Joined: Thu Jan 21, 2010 11:59 pm
Location: The Bay Area

Hello
Ik bought then L3G4200D on a little board like Arduino (sale of SAMENKOPEN)
Can anybody help me with code in Basic (MikroElectronica) with a test program
thanks
jbv000
 
Posts: 1
Joined: Sun Nov 13, 2011 5:31 am

Sorry, Iv'e never used MikroElectronica before. But here is an example of communicating with I2C in it: http://www.mikroe.com/eng/chapters/view ... #example11



jbv000 wrote:Hello
Ik bought then L3G4200D on a little board like Arduino (sale of SAMENKOPEN)
Can anybody help me with code in Basic (MikroElectronica) with a test program
thanks
ameyer
Founder
 
Posts: 3327
Joined: Thu Jan 21, 2010 11:59 pm
Location: The Bay Area

schoeny wrote:Have you ever noticed that the z-axis sometomes outputs suspiciously large values (absolute)?

Like this:
35 -68 0
32 -65 -5
42 -61 0
28 -66 -7
44 -67 -1
38 -60 -1
47 -64 -4
39 -59 -3
44 -62 -3
38 -65 -1
41 -62 -3
38 -67 3
36 -63 255 <--- I see this about once every 10 seconds.
45 -60 0
39 -63 3
40 -61 0
42 -64 0
46 -66 0
40 -66 -1

I'm planning on putting this on a turntable to see if the glitch is always a 255 in the LSB.


anyone solved this? i have the same problem
robcoenen
 
Posts: 1
Joined: Tue May 08, 2012 9:01 pm

If you're still interesting in answer, you take the angle adding 2 bytes. I think, the the gyroscope is changing data when you read them.
You need to set 7 bit in CTRL_REG4 (Block Data Update: output registers not updated until MSB and LSB reading).
You can look a good article http://robot-develop.org/archives/4282 (sorry, in Russian).
alexey
 
Posts: 1
Joined: Sun Jan 27, 2013 2:33 pm

Hey all,

Spent a day or so writing a complete Arduino code suite for this gyro. Feel free to use it and let it solve all your problems! ;) Let me know if there are any issues.

Code: Select all
// Name: L3G4200D_Gyro_Init_and_Test
// Written by: William Martin
// Developed for: The University of Tennessee Graduate Robotics Team
// Created: 3/1/2013
// Last Modified: 3/3/2013
// Contact: wmartin8@utk.edu
// License: open-source, but I do appreciate the above lines being included in your code
// Based on: http://bildr.org/2011/06/l3g4200d-arduino/ and the MIT License

/**** GENERAL NOTES ****
- this code is only converned with the yaw axis (z) of the gyro. To work with
- the roll (x) and pitch (y) axes, you can copy this code with a slight change of variable names.

- boolean variable 'calibrate' should only need to set to 'true' if you are getting
- unexpected behavior from code. This may happen if your use requires the gyro to be rotated
- either extremely quickly or extremly slowly.
******* END NOTES ********/

#include <Wire.h>

#define CTRL_REG1 0x20
#define CTRL_REG2 0x21
#define CTRL_REG3 0x22
#define CTRL_REG4 0x23
#define CTRL_REG5 0x24

// This character buffer holds all of the Serial.print statements.
char p_buffer[115];
// By wrapping all of our Serial.print statements in P, the character strings are stored in the
// PROGMEM (flash) memory (32k) instead of the EPROM (2k). This fixes a weird bug that was causing my
// code to crash  during runtime because I had too many character strings embedded in the print statements
// that was causing the SRAM to overflow
#define P(str) (strcpy_P(p_buffer, PSTR(str)), p_buffer)

// These are basically define statements used in the funtion calls below
const boolean CLOCKWISE = true;
const boolean COUNTERCLOCKWISE = false;

int L3G4200D_Address = 105; //I2C address of the L3G4200D

// These hold the instantaneous values from the gryo for pitch, roll, and yaw
int rollGyroVal;
int pitchGyroVal;
int yawGyroVal;

const int gyroNoiseThresh = 25; // Ignore gyroscope values below this value
const int gyroDelayTime = 20; // refresh rate of gyroscope.
double yawGyroValDouble; // running sums get very large. We need to poll the int from the register and convert it to a double
double yawGyroValRunSum = 0; // when turning, we poll the gyro thousands of times and accumulate the values help in yawGyroVal

double clicksPerDegCW = -663.33; // a constant used when turning X degrees clockwise. This value can be re-set by turning the calibrate variable to TRUE and following on-screen instructions
double clicksPerDegCCW = 647.67; // a constant used when turning X degrees counter clockwise. This value can be re-set by turning the calibrate variable to TRUE and following on-screen instructions

// Boolean program controllers for the gyroscope
boolean calibrate = false; // set to true if you want to recalibrate the gyro (doesn't seem like gyro is detecting accurate number of degrees turned
boolean testMode = true; // set to true if you want to test the gyro to see if it needs to be recalibrated

boolean gyroTurnTimeoutError = false; // keeps track of if the gyro has timed out on a turn
int turnTimeout = 8000; // maximum time required for a turn (ms). Error above is thrown if turn takes longer than this

void setup(){

  Wire.begin();
  Serial.begin(9600);

  Serial.println(P("\n\n\nStarting up L3G4200D"));
  setupL3G4200D(2000); // Configure L3G4200  - 250, 500 or 2000 deg/sec

  delay(1500); //wait for the sensor to be ready
 
  if(calibrate) {

    // In this block, we perform calibration to reset the values stored in clicksPerDegCW and clicksPerDegCCW.
    // IMPORTANT NOTE - after calibration, you will need to copy and paste the values displayed on the serial moniter into the
    // variable declarations above!!!!
   
    recalibrateGyroscope();
   
   
  }
 
  if (testMode) {
   
    // This function tests to see that the current values in clicksPerDegCW and clicksPerDegCCW
    // are currently working or need to be reset
    testCalibrationResults();
   
  }
   
 

}

void loop(){
  // The main loop is left empty so that you can incorporate the code developed here into
  // your project. Here is an example of how you may like to use this code in some robotics application...
 
  /*
  boolean turnDirection;
  double turnDegrees;
 
  turnDirection = getDirectionToTurn(); // some function you wrote
  turnDegrees = getDegreesToTurn(); // some function you wrote
 
  startTurning(turnDirection); // make your robot start turning (another function you wrote)
  gyroTurnTimeoutError = gyroBasedTurns(turnDirection, turnDegrees); // function returns once gyro has been rotated far enough
  stopTurning(); // tell motors to stop turning based on gyro data
 
  if (gyroTurnTimeoutError) { // gryo not working? startTurning function not working?
  }
  else { // success!
  }
  */
 
 
}







/******** BELOW THIS LINE IS ALL FUNCTIONS FOR THE L3G4200D GYRO UNIT *********/
boolean gyroBasedTurns(boolean dir, double angleDegrees) {
 // dir = 1 -> clockwise, dir = 0 -> counterClockWise
 
 // This function continuously moniters the gyroscope's yaw reading until
 // it has turned angleDegrees in dir direction. It returns true if the turn is successful
 // and false if the turn event has timed out.
 
 double clicksToTurn = 0;
 if (dir == CLOCKWISE) {
   clicksToTurn = angleDegrees * clicksPerDegCW;
 }
 
 else if (dir == COUNTERCLOCKWISE) {
   clicksToTurn = angleDegrees * clicksPerDegCCW;
 }
 
 double yawGyroValDouble = 0;
 double totalClicks = 0;
 
 int starttime = millis(); // get start time
 int endtime = starttime; // init end time
 
 while (abs(totalClicks) < abs(clicksToTurn)) {
  getGyroValues();  // This will update rollGyroVal, pitchGyroVal, and yawGyroVal with new values

  yawGyroValDouble =yawGyroVal;
  if(abs(yawGyroValDouble) > abs(gyroNoiseThresh)){ // ignore noise
      totalClicks+=yawGyroValDouble; // update runsum
    }
 
  delay (gyroDelayTime);
  endtime = millis();
  if ((endtime - starttime) > turnTimeout) {
    return true; // turn timed out. Return an error
  }

 }
 
 return false; // we've accumulated anough clicks to be able to say that the turn has completed. Return
}


void testCalibrationResults() {
 
    // This function runs a few simple tests to determine if the gyro is correctly calibrated
 
    Serial.println(P("Now to test. After you type a key, the program will wait for "));
    Serial.println(P("you to rotate the gyro 90 degrees clockwise. "));
    Serial.println(P("It will inform you once you have done so."));
   
    while(Serial.available() == 0){} // wait for user to enter a button
    Serial.read(); Serial.println(P("Go!"));

    gyroTurnTimeoutError = gyroBasedTurns(CLOCKWISE, 90.0);
    if (gyroTurnTimeoutError) {
      Serial.println(P("Error - turn timed out."));
    } else {
    Serial.println(P("Turn Complete.\n"));}
   
    Serial.println(P("Now type a key, then rotate the gyro 90 degrees counter-clockwise..."));
   
    while(Serial.available() == 0){}
    Serial.read(); Serial.println(P("Go!"));
    gyroTurnTimeoutError = gyroBasedTurns(COUNTERCLOCKWISE, 90.0);
    if (gyroTurnTimeoutError) {
      Serial.println(P("Error - turn timed out."));
    } else {
    Serial.println(P("Turn Complete.\n"));}
   
    Serial.println(P("Now type a key, then rotate the gyro 180 degrees clockwise..."));
   
    while(Serial.available() == 0){}
    Serial.read(); Serial.println(P("Go!"));
    gyroTurnTimeoutError = gyroBasedTurns(CLOCKWISE, 180.0);
    if (gyroTurnTimeoutError) {
      Serial.println(P("Error - turn timed out."));
    } else {
    Serial.println(P("Turn Complete.\n"));}
   
    Serial.println(P("Now type a key, then rotate the gyro 180 degrees counter-clockwise..."));
   
    while(Serial.available() == 0){}
    Serial.read(); Serial.println(P("Go!"));
    gyroTurnTimeoutError = gyroBasedTurns(COUNTERCLOCKWISE, 180.0);
    if (gyroTurnTimeoutError) {
      Serial.println(P("Error - turn timed out."));
    } else {
    Serial.println(P("Turn Complete.\n"));}
   
    Serial.println(P("Testing complete. If these tests were satisfactory, "));
    Serial.println(P("change 'boolean testMode' valraible initialization to 'FALSE'"));
    Serial.println(P("And begin using your gyroscope!"));
}


void recalibrateGyroscope() {
 
  // This function determines the 'clicks per degree' variable values. Follow onscreen instructions.
 
  double CWaverages[5] = {0}; // init arrays to hold test values
  double CCWaverages[5] = {0};
  int NUMTESTS = 3; // increase this number to eliminate noise in calibration tests. Decrease to be less annoyed with calibration
 
  Serial.println(P("Welcome to the gyroscope calibration routine! Let's get started...\n"));
  Serial.println(P("You are going to be rotating the gryoscope back and forth a few times to set the "));
  Serial.println(P(" clicksPerDegCW and clicksPerDegCCW variable values. Follow the on-screen instructions.\n\n"));
 
  for(int i=0; i<NUMTESTS; i++) {
  CWaverages[i] = setCountPerDegCW(clicksPerDegCW, gyroDelayTime);
  CCWaverages[i] = setCountPerDegCCW(clicksPerDegCCW, gyroDelayTime);
  Serial.print(P("(Test set "));
  Serial.print(i+1);
  Serial.print(P(" of "));
  Serial.print(NUMTESTS);
  Serial.println(P(" completed.)"));
  }
 
  Serial.println(P("\n\nTesting complete! Here is the data collected: \n (clicksPerDegCW,\tclicksPerDegCW)"));
 
  clicksPerDegCW = 0; // reset these values
  clicksPerDegCCW = 0;
  for(int i=0; i<NUMTESTS; i++) {
    Serial.print(CWaverages[i]);
    Serial.print(",\t");
    Serial.println(CCWaverages[i]);
    clicksPerDegCW+=CWaverages[i];
    clicksPerDegCCW+=CCWaverages[i];
  }
  clicksPerDegCW = clicksPerDegCW/(double)NUMTESTS;
  clicksPerDegCCW = clicksPerDegCCW/(double)NUMTESTS;
 
  Serial.println(P("(Numbers in the two columns above should be very similar. If numbers in the same "));
  Serial.println(P("column have different signs, then you have confused clockwise with counterclockwise.)"));
  Serial.println(P("You will now need to change some values\n in the initializaion at the top of the code."));
  Serial.print(P("\nChange the line 'double clicksPerDegCW = XXXX;' to 'double clicksPerDegCW = "));
  Serial.print(clicksPerDegCW);
  Serial.println("; ");
  Serial.print(P("Change the line 'double clicksPerDegCCW = XXXX;' to 'double clicksPerDegCCW = "));
  Serial.print(clicksPerDegCCW);
  Serial.println(P("; "));
  Serial.println(P("\nNow, change the boolean variable calibrate to 'false' \nand re-upload the code to the Arduino."));
  Serial.print(P("You should also set the boolean variable testMode to 'true' \nto verify "));
  Serial.println(P("that the re-calibration is giving expected results."));
 
}


int setCountPerDegCW(int currentVal, int gyroDelayTime) {
 
  Serial.println(P("After hitting any key, you will have 5 seconds"));
  Serial.println(P(" to rotate the gyro 180 degrees clockwise."));
  while(Serial.available() == 0){} // wiat for user to type a key
  Serial.read(); // throw away result
  double yawGyroValDouble=0;
  double yawGyroValRunSum=0;
  int starttime = millis();
  Serial.println(P("Go!"));
  int endtime = starttime;
  while ((endtime - starttime) <=5000) // do this loop for up to 5000mS
  {
    getGyroValues();  // This will update rollGyroVal, pitchGyroVal, and yawGyroVal with new values
    yawGyroValDouble =yawGyroVal; // convert to double
    if(abs(yawGyroValDouble) > abs(gyroNoiseThresh)){ // ignore noise
      yawGyroValRunSum += yawGyroValDouble; // add to running sum
    }
    delay (gyroDelayTime); // let gyro refresh
    endtime = millis(); // get elapsed time of test
  }
 
  Serial.println(P("Time's up!"));
  Serial.print(P("Click count found was: "));
  Serial.println(yawGyroValRunSum);
  Serial.print(P("The variable 'clicksPerDegCW in this test is: "));
  Serial.println(yawGyroValRunSum/180);
 
  return yawGyroValRunSum/180;
   
}

int setCountPerDegCCW(int currentVal, int gyroDelayTime) {
 
  Serial.println(P("After hitting any key, you will have 5 seconds"));
  Serial.println(P(" to rotate the gyro 180 degrees counter clockwise."));
  while(Serial.available() == 0){}
  Serial.read();
  double yawGyroValDouble=0;
  double yawGyroValRunSum=0;
  int starttime = millis();
  Serial.println("Go!");
  int endtime = starttime;
  while ((endtime - starttime) <=5000) // do this loop for up to 5000mS
  {
    getGyroValues();  // This will update rollGyroVal, pitchGyroVal, and yawGyroVal with new values
    yawGyroValDouble =yawGyroVal; // convert to double
    if(abs(yawGyroValDouble) > abs(gyroNoiseThresh)){ // ignore noise
      yawGyroValRunSum += yawGyroValDouble; // update running sum
    }
    delay (gyroDelayTime); // allow gyro to refresh
    endtime = millis(); // get elapsed time
  }
 
  Serial.println(P("Time's up!"));
  Serial.print(P("Click count found was: "));
  Serial.println(yawGyroValRunSum);
  Serial.print(P("The variable 'clicksPerDegCCW in this test is: "));
  Serial.println(yawGyroValRunSum/180);
 
  return yawGyroValRunSum/180;
   
}

void getGyroValues(){

  // Get instantaneous roll, pitch and yaw values from gyro
  byte rollGyroValMSB = readRegister(L3G4200D_Address, 0x29);
  byte rollGyroValLSB = readRegister(L3G4200D_Address, 0x28);
  rollGyroVal = ((rollGyroValMSB << 8) | rollGyroValLSB);

  byte pitchGyroValMSB = readRegister(L3G4200D_Address, 0x2B);
  byte pitchGyroValLSB = readRegister(L3G4200D_Address, 0x2A);
  pitchGyroVal = ((pitchGyroValMSB << 8) | pitchGyroValLSB);

  byte yawGyroValMSB = readRegister(L3G4200D_Address, 0x2D);
  byte yawGyroValLSB = readRegister(L3G4200D_Address, 0x2C);
  yawGyroVal = ((yawGyroValMSB << 8) | yawGyroValLSB);
}

int setupL3G4200D(int scale){
  //From  Jim Lindblom of Sparkfun's code

  // Enable rollGyroVal, pitchGyroVal, yawGyroVal and turn off power down:
  writeRegister(L3G4200D_Address, CTRL_REG1, 0b00001111);

  // If you'd like to adjust/use the HPF, you can edit the line below to configure CTRL_REG2:
  writeRegister(L3G4200D_Address, CTRL_REG2, 0b00000000);

  // Configure CTRL_REG3 to generate data ready interrupt on INT2
  // No interrupts used on INT1, if you'd like to configure INT1
  // or INT2 otherwise, consult the datasheet:
  writeRegister(L3G4200D_Address, CTRL_REG3, 0b00001000);

  // CTRL_REG4 controls the full-scale range, among other things:

  if(scale == 250){
    writeRegister(L3G4200D_Address, CTRL_REG4, 0b00000000);
  }else if(scale == 500){
    writeRegister(L3G4200D_Address, CTRL_REG4, 0b00010000);
  }else{
    writeRegister(L3G4200D_Address, CTRL_REG4, 0b00110000);
  }

  // CTRL_REG5 controls high-pass filtering of outputs, use it
  // if you'd like:
  writeRegister(L3G4200D_Address, CTRL_REG5, 0b00000000);
}

void writeRegister(int deviceAddress, byte address, byte val) {
    Wire.beginTransmission(deviceAddress); // start transmission to device
    Wire.write(address);       // send register address
    Wire.write(val);         // send value to write
    Wire.endTransmission();     // end transmission
}

int readRegister(int deviceAddress, byte address){

    int v;
    Wire.beginTransmission(deviceAddress);
    Wire.write(address); // register to read
    Wire.endTransmission();

    Wire.requestFrom(deviceAddress, 1); // read a byte

    while(!Wire.available()) {
        // waiting
    }

    v = Wire.read();
    return v;
}
williammartin
 
Posts: 1
Joined: Sun Mar 03, 2013 5:24 pm

I am integrating the L3G4200D with a Raspberry Pi. The Rpi is generating the SCLK, MOSI, CS signals in the right way. The various control registers - CTRL_REG1, CTRL_REG2 addresses have been set correctly by the RPi. Also, I have followed @williammartin's code (as given above to set the control register values). But for some reason, the SDO (slave data o/p) pin of the gyro always remains high and the gyro only outputs a 0xFF. Can somebody please help me with the reasons for this?


Thanks..
smithakamat
 
Posts: 1
Joined: Fri Apr 19, 2013 8:43 pm

Sorry, I dont have any experience with the RPi


smithakamat wrote:I am integrating the L3G4200D with a Raspberry Pi. The Rpi is generating the SCLK, MOSI, CS signals in the right way. The various control registers - CTRL_REG1, CTRL_REG2 addresses have been set correctly by the RPi. Also, I have followed @williammartin's code (as given above to set the control register values). But for some reason, the SDO (slave data o/p) pin of the gyro always remains high and the gyro only outputs a 0xFF. Can somebody please help me with the reasons for this?


Thanks..
ameyer
Founder
 
Posts: 3327
Joined: Thu Jan 21, 2010 11:59 pm
Location: The Bay Area

ameyer wrote:From: http://bildr.org/2011/06/l3g4200d-arduino/

We have covered, accelerometers, GPSs, compasses... But no gyros. Why? Not sure, but I figured today I would put an end to that, so I grabbed a L3G4200D 3-axis gyro from sparkfun.

The L3G4200D is a 3-axis angula ...

Hello everyone i ve just joined this forum..i wanted to know if i install this sensor, where it would be exposed to a lot of mud and dirt and where the moisture content could get high eventually..would it still work???
riju16
 
Posts: 1
Joined: Fri Nov 15, 2013 1:47 am

With it out in the open, probably not. But you could easily pot it in epoxy or silicon - http://hackaday.com/2012/06/04/potting- ... -silicone/


riju16 wrote:
ameyer wrote:From: http://bildr.org/2011/06/l3g4200d-arduino/

We have covered, accelerometers, GPSs, compasses... But no gyros. Why? Not sure, but I figured today I would put an end to that, so I grabbed a L3G4200D 3-axis gyro from sparkfun.

The L3G4200D is a 3-axis angula ...

Hello everyone i ve just joined this forum..i wanted to know if i install this sensor, where it would be exposed to a lot of mud and dirt and where the moisture content could get high eventually..would it still work???
ameyer
Founder
 
Posts: 3327
Joined: Thu Jan 21, 2010 11:59 pm
Location: The Bay Area

robcoenen wrote:
schoeny wrote:Have you ever noticed that the z-axis sometomes outputs suspiciously large values (absolute)?

Like this:
35 -68 0
32 -65 -5
42 -61 0
28 -66 -7
44 -67 -1
38 -60 -1
47 -64 -4
39 -59 -3
44 -62 -3
38 -65 -1
41 -62 -3
38 -67 3
36 -63 255 <--- I see this about once every 10 seconds.
45 -60 0
39 -63 3
40 -61 0
42 -64 0
46 -66 0
40 -66 -1

I'm planning on putting this on a turntable to see if the glitch is always a 255 in the LSB.


anyone solved this? i have the same problem


Annoying isn't it? I tried the BDU bit and the A8 register trick and neither helped. What did work was setting it to read both the A8 and the 28 registers, then compare them. If they differ, read them again! Seems to have solved 100% of my glitching. Now I can get on to calibrating in peace.

Fwiw, changing to the A8 register moved the majority of my glitches from X to Z, though I still was seeing them from time to time in Y, and I also tried playing with update speed and placing delays around in the wire commands without luck. I also saw values of 253 through 255, though most of them were 255 in a single register. Increasing the update freq from 100 to 200 hz doubled the glitching. Too bad it can't go below 100.
virtual1
 
Posts: 1
Joined: Sat Mar 15, 2014 6:14 pm

To avoid the value of 255, try to read the STATUS_REG and wait until the data available and no data overrun. As example on Z axis:
#define STATUS_REG 0x27
#define ZOR_REG 0b01000000
#define ZDA_REG 0b00000100

void gyroWaitAndRead()
{
//wait until new z data available and no overrun
byte statusflag = readRegister(L3G4200D_Address, STATUS_REG);
while(!(statusflag & ZDA_REG) && (statusflag & ZOR_REG)) {
statusflag = readRegister(L3G4200D_Address, STATUS_REG);
}
//read values
getGyroValues();
}
jeki
 
Posts: 1
Joined: Wed Mar 19, 2014 12:20 am

jeki wrote:To avoid the value of 255, try to read the STATUS_REG and wait until the data available and no data overrun. As example on Z axis:
#define STATUS_REG 0x27
#define ZOR_REG 0b01000000
#define ZDA_REG 0b00000100

void gyroWaitAndRead()
{
//wait until new organifi green juice data available and no overrun
byte statusflag = readRegister(L3G4200D_Address, STATUS_REG);
while(!(statusflag & ZDA_REG) && (statusflag & ZOR_REG)) {
statusflag = readRegister(L3G4200D_Address, STATUS_REG);
}
//read values
getGyroValues();
}


Hi Jeki, what do I do with this?
Last edited by Milbo on Tue Apr 18, 2017 9:09 am, edited 2 times in total.
Milbo
 
Posts: 1
Joined: Sat Aug 20, 2016 4:21 am

Sadly, there is very little chance of getting a response as this was over 2 years ago. Unfortunately I don' know the answer myself.


Milbo wrote:
jeki wrote:To avoid the value of 255, try to read the STATUS_REG and wait until the data available and no data overrun. As example on Z axis:
#define STATUS_REG 0x27
#define ZOR_REG 0b01000000
#define ZDA_REG 0b00000100

void gyroWaitAndRead()
{
//wait until new z data available and no overrun
byte statusflag = readRegister(L3G4200D_Address, STATUS_REG);
while(!(statusflag & ZDA_REG) && (statusflag & ZOR_REG)) {
statusflag = readRegister(L3G4200D_Address, STATUS_REG);
}
//read values
getGyroValues();
}


Hi Jeki, what do I do with this?
ameyer
Founder
 
Posts: 3327
Joined: Thu Jan 21, 2010 11:59 pm
Location: The Bay Area


Return to Blog Posts

Who is online

Users browsing this forum: No registered users and 1 guest

cron