void Sample_Gyro(void)
{
// The current gyro reading
unsigned char gyro_reading;
// The previous gyro reading, used to average out
// the results
unsigned char prev_reading;
// Is the gyro calibrated or not?
unsigned static char gyro_calibrated;
// Used to count the number of samples taken thus
// far during calibration
unsigned static char samplecount;
// The value returned when the gyro is at rest.
// This is determined via the calibration routine.
unsigned char gyro_rest;
// Start a conversion and wait for it to finish
// before continuing on. [207, 220]
ADCSRA |= (1 << ADSC);
while(!(ADCSRA & 0x10));
// Get the high 8 bits of the results [218]
gyro_reading = ADCH;
// Account for sampling time
gyro_reading = gyro_reading * GYRO_SAMPLE_RATE;
// Handle overloading. This happens when the bot is
// spinning faster than the gyro can read. We can't
// really do anything from here, other than set a
// flag and let other functions know we're spinning
// too fast.
if(gyro_reading > GYRO_MAX_HIGH || gyro_reading < GYRO_MAX_LOW)
{
gyro_overloaded = TRUE;
}
// If we aren't calibrated yet, lets do that
if(gyro_calibrated == FALSE)
{
// We need to take a minimum amount of
// samples to calibrate
if(samplecount < GYRO_CAL_MIN_SAMPLES)
{
// Accumulate the samples
gyro_rest += gyro_reading;
}
else
{
// Average the samples to find the
// rest point
gyro_rest /= GYRO_CAL_MIN_SAMPLES;
// We are done calibrating
gyro_calibrated = TRUE;
return;
}
}
// Now we want to convert the gyro output to signed.
// We do this by subtracting gyrobase, making the
// reading center around 0.
// Positive is one direction, negative another, then
// we just integrate it
// Now we're also averaging the current sample with
// the previous before normalizing it.
current_heading += (signed long) (((gyro_reading + prev_reading) / 2) - gyro_rest);
// We are done so set the current reading to the
// previous
prev_reading = gyro_reading;
}