int main() { TCCR0A = 0; // configure timer0 to run at 78 kHz TCCR0B = 0x04; // and overflow when TCNT0 = 256 (~3 ms) play_from_program_space(rhapsody); while(1) { // allow the sequence to keep playing automatically through the following delays #ifndef ALWAYS_CHECK play_mode(PLAY_AUTOMATIC); #else play_mode(PLAY_CHECK); #endif lcd_goto_xy(0, 0); print("blink!"); int i; for (i = 0; i < 8; i++) { #ifdef ALWAYS_CHECK play_check(); #endif red_led(1); delay_ms(500); red_led(0); delay_ms(500); } lcd_goto_xy(0, 0); print("timing"); lcd_goto_xy(0, 1); print(" "); // clear bottom LCD line // turn off automatic playing so that our time-critical code won't be interrupted by // the buzzer's long timer1 interrupt. Otherwise, this interrupt could throw off our // timing measurements. Instead, we will now use playCheck() to keep the sequence // playing in a way that won't throw off our measurements. #ifndef ALWAYS_AUTOMATIC play_mode(PLAY_CHECK); #endif unsigned char maxTime = 0; for (i = 0; i < 8000; i++) { TCNT0 = 0; while (TCNT0 < 20) // time for ~250 us ; if (TCNT0 > maxTime) maxTime = TCNT0; // if the elapsed time is greater than the previous max, save it #ifndef ALWAYS_AUTOMATIC play_check(); // check if it's time to play the next note and play it if so #endif } lcd_goto_xy(0, 1); print("max="); print_long((unsigned int)maxTime); print(" "); // overwrite any left over characters } }
// Waits for the next byte and returns it. Runs play_check to keep // the music playing and calls pid_check() to keep following the line. char read_next_byte() { while(serial_get_received_bytes() == read_index) { play_check(); // pid_check takes some time; only run it if we don't have more bytes to process if(serial_get_received_bytes() == read_index) pid_check(); } char ret = buffer[read_index]; read_index ++; if(read_index >= 100) read_index = 0; return ret; }