// // Metronome. // A speaker is connected to pin P2.3 and ground. // Five LEDs are connected to P1.1, P1.2, P1.4, P1.5, and P1.7. // White plastic straws fit over the LEDs to make little // light-sabers that are the pendulum of the metronome. // char pendulum[] = { // Leave P1_0 for the red led 0b00000010, // P1_1 0b00000100, // P1_2 // Leave P1_3 for PUSH2 0b00010000, // P1_4 0b00100000, // P1_5 // Leave P1_6 for the green led 0b10000000 // P1_7 }; char which = 0; unsigned long int times[8]; // We never want to go faster than 100 Hz // Once every 10,000 microseconds is 100 Hz // If the delay is longer than 5 seconds, give up enum { MINIMUM_PERIOD = 10000, MAXIMUM_PERIOD = 5000000 }; unsigned long int average = 0; void get_speed( void ) { pinMode( RED_LED, OUTPUT ); pinMode( GREEN_LED, OUTPUT ); // P1REN = 0b1000; // Pushbutton 2 has an external pullup resistor, so this is unnecessary pinMode( PUSH2, INPUT_PULLUP ); int state = digitalRead( PUSH2 ); char pulse = 0; unsigned long int t = micros(); for( unsigned char i = 0; i < sizeof times / sizeof *times; ) { int s = digitalRead( PUSH2 ); digitalWrite( RED_LED, s ); digitalWrite( GREEN_LED, pulse ); pulse ^= 1; if( s != state && s == LOW ) { times[i] = micros() - t; t = micros(); if( times[i] > MAXIMUM_PERIOD ) break; if( times[i] > MINIMUM_PERIOD ) i++; } state = s; } // Ignore the first one for( unsigned char i = 1; i < sizeof times / sizeof *times; i++ ) { average += times[i]; } average /= (sizeof times / sizeof *times) - 1; average /= 4; // Tick at the left and the right if( average < MINIMUM_PERIOD ) average = 50000; average /= 1000; // Convert microseconds to milliseconds } void setup( void ) { P1OUT = 0; P1DIR = 0b11110111; // Leave P1_3 as an input for PUSH2 P2DIR = 0b1000; // Speaker connected to P2_3 get_speed(); } char dir = 1; void loop( void ) { P1OUT = pendulum[which]; if( which >= sizeof pendulum - 1 ) { dir = -1; P2OUT ^= 0b1000; // click the speaker connected to P2_3 delay( 1 ); P2OUT ^= 0b1000; delay( 50 ); // stay longer on the ends } if( which <= 0 ) { dir = 1; P2OUT ^= 0b1000; delay( 1 ); P2OUT ^= 0b1000; delay( 50 ); } which += dir; delay( average ); }