Trossen XBee  Top Banner
Page 2 of 2 FirstFirst 12
Results 11 to 20 of 20

Thread: L3G4200D Gyro Integration on Arduino

  1. #11
    Join Date
    Dec 2008
    Location
    Washington
    Posts
    312
    Images
    35
    Rep Power
    23

    Re: L3G4200D Gyro Integration on Arduino

    Ah you are correct!

    Code:
    while((millis() - pastMillis)<9);
    Insted of dealy(10); results in about 93 degrees for every 90. I am guessing the easiest way to eliminate inconsistent sample rate as a factor would be to use millis() in the math itself but "excuse my stupidity here " in the formula where are the "kilo-degrees per sample time" coveted to kilo-degrees per second?
    Dalton Caughell

  2. #12
    Join Date
    Sep 2010
    Location
    ಠ_ಠ
    Posts
    1,180
    Images
    25
    Rep Power
    49

    Re: L3G4200D Gyro Integration on Arduino

    Not sure if the even more severe sleep deprivation is making me miss sarcasm or not.

    Code:
    current_rotational_rate [degrees/s] = sensor_value [digits] * 8.25 [millidegrees/s/digit] * (1/1000) [degree/millidegree]
    
      // Raw Integration of rotational rate to produce current angle
      // omega = dtheta/dt -> omega*dt = dtheta -> theta1 - theta0 = omega*(t1-t0) -> theta1 = theta0 + omega*(t1-t0)
    current_angle [deg] = last_angle [deg] + { (current_rotational_rate) [deg/s] * (time_current - time_last) [s] }
      // The Averaged/Smoothed Integration imlemented in your code
    current_angle [deg] = last_angle [deg] + { ((last_rotational_rate+current_rotational_rate)/2) [deg/s] * (time_current - time_last) [s] }
    so this should work
    Code:
    unsigned long pastMicros = 0;
    unsigned long currMicros = 0;
    float dt = 0.0;
    
    void loop()
    {
      pastMillis = millis();
      getGyroValues();  // This will update x, y, and z with new values
      pastMicros = currMicros;
      currMicros = micros();
    
      // if we are considering a certain range of z to be noise, should we even bother doing any calculations or updating any values when z is considered noise?  Seriously asking because of aforementioned sleep deprivation.
      if(z >= gyroHigh || z <= gyroLow)
      {
        // determine time interval between sensor readings with a bit more accuracy than available just using millis()
        // of course, micros() only updates in intervals of 4 [us], but still far better resolution/sig-figs than millis()
        if (currMicros>pastMicros)  //micros() overflows/resets every ~70 minutes
          dt = (float) (currMicros-pastMicros)/1000000.0;
        else
          dt = (float) ((4294967295-pastMicros)+currMicros)/1000000.0;
    
        degreesPerSecond = (((float)z * 8.75))/100;
    
        // here we do an averaged/smoothed integration of rotational rate to produce current angle.
        currentAngle += ((p_z + degreesPerSecond)/2) * dt;
    
        // Should p_z be updated if z is insufficient to change the current angle?  Again, seriously asking because I trust my mind even less than usual.
        p_z = degreesPerSecond;
      }
     
      Serial.println(currentAngle);
     
      // wait ~10 milliseconds
      while ( (millis()-pastMillis)<10 ) // millis() overflows once every ~50 days, so less inclined to worry
      {
        delayMicroseconds(50);
      }
    }
    Last edited by tician; 04-15-2012 at 03:13 AM. Reason: i'm goin' bed
    Please pardon the pedantry... and the profanity... and the convoluted speech pattern...
    "You have failed me, Brain!"

  3. #13
    Join Date
    Dec 2008
    Location
    Washington
    Posts
    312
    Images
    35
    Rep Power
    23

    Re: L3G4200D Gyro Integration on Arduino

    Lol it was not sarcasm I have been devoting every hour to getting our FTC bot up and running and I was pretty burned out Totally missed a basic concept, but everything is working now. There was a bit of left over error but I tuned it out manually.

    Because I got a few pm's about the final code here it is for refrence.

    L3G4200D_V3-120417a.zip

    Thanks again!
    Dalton Caughell

  4. #14
    Join Date
    Sep 2010
    Location
    ಠ_ಠ
    Posts
    1,180
    Images
    25
    Rep Power
    49

    Re: L3G4200D Gyro Integration on Arduino

    Went back to a fixed 10 [ms] delay? If so, you could remove the "pastMillis = millis();" line in loop(), since it is just wasting cycles with an invariant delay.
    Please pardon the pedantry... and the profanity... and the convoluted speech pattern...
    "You have failed me, Brain!"

  5. Re: L3G4200D Gyro Integration on Arduino

    I've had a look at your code, thanks for sharing it.

    However, I have a question.

    I read values from my L3G4200D using the SPI bus.
    Angular rate values when the sensor is in steady state are not 0. Typically I have a value around 100 when the sensor is steady around the z axys. Let's consider this as an example.

    I use a calibration method similar to yours, detecting a max and min threshold inside which I consider samples to be noise around the steady state condition.

    Now, if the z-sample is 130, I want to integrate it, however, when calculating the DegreesPerSecond I think I should consider only the delta from the steady state value (100) to the sampled valid value (130), that is 30.

    Basically I've had expected to see a line like this in your code:

    Code:
    z -= steadyStateValue
    Resulting in something like this:

    Code:
      if(z >= gyroHigh || z <= gyroLow)
      {
        z -= steadyStateValue
        degreesPerSecond = (float)z * 0.00000908; //this value was 0.0000085 but was manually calibrated to its current value
        if (currMicros>pastMicros)  //micros() overflows/resets every ~70 minutes
          dt = (float) (currMicros-pastMicros)/1000000.0;
        else
          dt = (float) ((4294967295-pastMicros)+currMicros)/1000000.0;
        currentAngle += ((p_z + degreesPerSecond)/2) * dt;
        p_z = degreesPerSecond;
      }
      else 
      {
        p_z = 0;
      }
    It sounds starnge to me that this has not been pointed out during the discussion.

    Am I missing something?

    Thanks.

  6. #16
    Join Date
    Sep 2010
    Location
    ಠ_ಠ
    Posts
    1,180
    Images
    25
    Rep Power
    49

    Re: L3G4200D Gyro Integration on Arduino

    I am pretty sure there was the assumption that the sensors was assembled and functioning well and that the steady state value was essentially zero with noise varying between gyroHigh and gyroLow. I do not recall the steady state value from the gyro in any of the CM-730's in the lab being that far from a zero value, but I may be mistaken. Is the sensor on a custom board you assembled or is it a breakout board from a manufacturer/re-seller? The L3G4200D datasheet does mention improper soldering and/or mechanical stress introducing error into the zero/steady-state value*. That said, if you do not have any trouble with the sensor other than the steady state value, then just compensate for it. If there are other problems, like improper scaling or non-responsive axes, then you might want to contact the manufacturer/seller of the board.

    * Under the heading 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.
    Please pardon the pedantry... and the profanity... and the convoluted speech pattern...
    "You have failed me, Brain!"

  7. #17
    Join Date
    Apr 2012
    Posts
    1,686
    Images
    25
    Rep Power
    54

    Re: L3G4200D Gyro Integration on Arduino

    You don't want to use millis() at all if you want accurate timing. You want the microsecond function, whose name escapes me (micros()?)
    Also, to get consistent sample rates, you probably want to set a timer to fire for each time you should sample, and sample from the interrupt handler.

  8. #18
    Join Date
    Sep 2010
    Location
    ಠ_ಠ
    Posts
    1,180
    Images
    25
    Rep Power
    49

    Re: L3G4200D Gyro Integration on Arduino

    Quote Originally Posted by jwatte View Post
    You don't want to use millis() at all if you want accurate timing. You want the microsecond function, whose name escapes me (micros()?)
    Also, to get consistent sample rates, you probably want to set a timer to fire for each time you should sample, and sample from the interrupt handler.
    The code posted above uses only micros() for math and uses millis() with a 50 [us] delay interval for a roughly consistent sample rate, although the final code ROBOTMAN uploaded dumped that for a simple fixed delay irrespective of the time taken to process the loop. Ideally one would just use a timer interrupt for sampling sensors, but I'm pretty sure the arduino was dedicated purely to sampling the gyro, calculating the current angle, and pushing that value out over the UART to the PC, so I think that plus frustration/deadline led to a situation of "good enough."
    Please pardon the pedantry... and the profanity... and the convoluted speech pattern...
    "You have failed me, Brain!"

  9. Re: L3G4200D Gyro Integration on Arduino

    tician, thank you for your reply.

    My L3G4200D is mounted on a Sparkfun breakout.
    Here below you can find actual samples of my sensor for 1 second interval:

    Code:
    X:95 Y:-10 Z:6
    X:91 Y:-17 Z:9
    X:96 Y:-10 Z:4
    X:94 Y:-7 Z:6
    X:93 Y:-16 Z:4
    X:97 Y:-15 Z:2
    X:101 Y:-16 Z:3
    X:96 Y:-8 Z:2
    X:92 Y:-10 Z:5
    However, no problem to compensate that, maybe ROBOTMAN was luckier with the zero-rate level being closer to 0 .

    Thank you for the datasheet quote.

  10. Re: L3G4200D Gyro Integration on Arduino

    I am also using the same gyro L3G4200D.
    I am trying to get angle from it...
    I've used ADXL 335 accelerometer.

    I am trying to get angles with respect to roll, yaw & pitch

    Here is my code:

    Code:
    float Rx,Ry,Rz,Yd,Xd,Zd,Rxe,Rye,Rze,Xavg,Yavg,Zavg,T,Rxg,Ryg,Rzg,c,Re,R,Rx1,Ry1,Rz1;
    Th = 5;
    c = 180/3.14;
    T = 0.0155;  //15.5 ms (verified by using counter)
    while(1)
    {
                    get_accl_data();                    // Accl data from ADC  
                    accelerometer();                    // Converting ADC values in "g" - Rx, Ry, Rz
                    inclination();                         // Normalizing Rx, Ry, Rz
                    gyro();                                // Computing Xavg, Yavg, Zavg by using two consecutive readings
                    
                    if((Xavg >= Th)||(Xavg <= -Th))
                    {
                        Xd = atan2(Rye, Rze);
                        Xd =(Xd + (Xavg*T));
                        Xd *= c;
                        ftoal(Xd,str);
                        UARTprintf("Xd : %s            \n\r",str);
                        Xd /= c;
                    }
                    if((Yavg >= Th)||(Yavg <= -Th))
                    {
                        Yd = atan2(Rxe, Rze);
                        Yd =(Yd + (Yavg*T));
                        Yd *= c;
                        ftoal(Yd,str1);
                        UARTprintf("        Yd : %s    \n\r",str1);
                        Yd /= c;
                    }
                    if((Zavg >= Th)||(Zavg <= -Th))
                    {
                        Zd = atan2(Rye, Rxe);
                        Zd =Zd + (Zavg*T);
                        Zd *= c;
                        ftoal(Zd,str2);
                        UARTprintf("                    Zd : %s\n\r",str2);
                        Zd /= c;
                    }
    
                    Rxg = sin(Yd) / (sqrt(1 + ( (cos(Yd)*cos(Yd) )*(tan(Xd) * tan(Xd) ))));
                    Ryg = sin(Xd) / (sqrt(1 + ( (cos(Xd) * cos(Xd) ) *( tan(Yd) * tan(Yd) ))));
                    Rzg = ((Rzg > 0) ? 1 : ((Rzg < 0) ? -1 : 1))*(sqrt(1 - (Rxg*Rxg)-(Ryg*Ryg)));
    
                    Rxe = (Rx*0.02)+(Rxg*0.98);
                    Rye = (Ry*0.02)+(Ryg*0.98);
                    Rze = (Rz*0.02)+(Rzg*0.98);
    
                    Re = sqrt((Rxe*Rxe) + (Rye*Rye) + (Rze*Rze) );
    
                    Rxe = Rxe/Re;
                    Rye = Rye/Re;
                    Rze = Rze/Re;
      
                   SysCtlDelay(800000);     // 10 ms delay
    }

    I am not getting the accurate angles...
    I am getting some angles proportional to acceleration at a time when I move it.
    And after moving it from angle 0 to angle 45 (for example) it stabilizes after a 1-2 sec. and giving stable values of Xd, Yd, Zd again!!

    What I am missing??

    Please help me

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Similar Threads

  1. PVision library for Arduino (Pixart/Wiimote to Arduino)
    By shobley in forum Robot Computers
    Replies: 1
    Last Post: 03-01-2009, 05:07 PM
  2. Question(s) Gyro IAccelerometer or IMU
    By dlwasler in forum Sensors
    Replies: 0
    Last Post: 02-17-2009, 12:26 PM
  3. Question(s) [Which] Gyro with SSC-32?
    By Superlaxstar112 in forum Arbotix, Microcontrollers, Arduino
    Replies: 7
    Last Post: 08-19-2008, 05:04 AM
  4. New Feature: Gallery Profile Integration!!
    By Alex in forum Off Topic
    Replies: 0
    Last Post: 05-07-2008, 09:45 AM
  5. Gyro choice???
    By quickster47 in forum Humanoids, Walkers & Crawlers
    Replies: 1
    Last Post: 10-05-2007, 04:12 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •