Thread: Yaw Sensor
View Single Post
  #8   Spotlight this post!  
Unread 14-02-2004, 10:16
Larry Barello Larry Barello is offline
http://www.barello.net
#0492 (Titan Robotics Club)
Team Role: Mentor
 
Join Date: Jan 2002
Location: Bellevue, WA
Posts: 85
Larry Barello has a spectacular aura aboutLarry Barello has a spectacular aura about
Re: Yaw Sensor

Here is the code from team 492's current robot. It uses the ADXRS150 evaluation board. They are available from Future, but I got ours as samples directly from Analog. The basic code works for any gyro, you just need to adjust the various #defines.

Wiring is simple too. The evaluation board is a 20pin dip. You need to connect two pins to ground and two to +5v and one pin is the output. A standard three conductor servo cable is all you need. I put ours on a bit of breadboard + a socket along with some other stuff.

Note, our code is called at 100hz. The Gyro has a bandwidth > 40hz so you want to sample it much faster. It wouldn't hurt to sample at 200-400hz, but 100 seems good enough. 38hz (the 26.2ms loop rate for IFI) is too slow.

Also note, below, that our observed scale was more like 200deg/sec range vs the specified 150. The scale changes with temperature, so if you want really accurate results you need to use the built in temperature sensor to compensate. I am going to just calibrate at the competition and trust that the temperature will be reasonably constant over the day.

Code:
/********************** Gyro Task ***************************************
    Gyro output is from .25 to 4.25 volts/5v range.  ADC is 10 bits.
    Full scale output is +/- 150 deg/sec.  Sampling rate is SYSCLOCK hz.

    Adjust FULLSCALEINPUT & OUTPUT to match the observed values
    so that when the robot is turned 360 deg the reported angle is
    360.  Double check by returning robot to starting position and
    verifying angle is 0.            
    
    Note: The gyro reading is 10bits, but I shift it over 4 to get a 16 bit value.
    This allows a fractional "offset" value which, when integrated over time
    will give a more accurate "zero" value.
*/

#define FULLSCALEINPUT (203.0 * 2.0)
#define FULLSCALEOUTPUT (1023.0 * 16.0)
#define PERIOD (1.0/GYROCLOCK)

#define GYROSCALE (FULLSCALEINPUT * PERIOD / FULLSCALEOUTPUT)

// GyroTask called at the primary loop rate of 100hz.  Delay 1.28 seconds before
// setting the basic gyro offset.  Gyro seems stable enough to last the 2 minute
// match without drifting significantly. Only high speed turns will mess it up.

#define GYRODELAY 128

int InitGyro = GYRODELAY;
int GyroOffset;
int iGyroTheta, iGyroRate;		// These are Zero at boot time
long temp;

float fTheta = GYROSCALE;

void Gyro_Task(void)
{
    int GyroVal = GetADC(Gyro) << 4;

    switch(InitGyro)
    {
        default:            // Delay until stable reading
            InitGyro--;
            temp += GyroVal;// Get average ADC value over 1 second
            break;
        case 0:             
            InitGyro = -1;
            GyroOffset = temp / GYRODELAY;
            break;
        case -1:
            iGyroRate = GyroVal - GyroOffset;
            fTheta += (float)iGyroRate * GYROSCALE;
            iGyroTheta = fTheta;    // Make integer version available.
            break;
    }
}