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; }