It is fairly simple to build a digital metronome using an ATmega328 AVR chip and some minimal programming using the Arduino libraries. The main challenge though is to display the tempo information conveniently.
Of course, we could use an LCD to display tempo, but it would add significant cost to the build. As an alternative, we can use LEDs to display such information. Since most digital metronomes have more than thirty discrete tempo settings, it would be impractical to use one LED for each tempo setting. In my design, I used 16 LEDs to represent 32 predefined tempos. The idea is that the 32 tempos are divided into two groups (high and low) and two additional LEDs are used to indicate which group the current setting belongs to. This can be seen in the photo below:
I used two 74LS138 3-8 line decoders to drive the 16 LEDs. As you can see from the following schematic, 4 control lines are needed:
Since we are selecting amongst 32 different tempos, we need 5 bits of information. The circuit above uses the least-significant 4 bits of information to drive the 16 LEDs and the most significant bits is used to indicate the current range (either range 1 or range 2).
The following code snippets shows how the LED display works:
/** * Light the LED at idx location (out of the 16 LEDs). */ void lightLED(int idx) { digitalWrite(PIN_LED_CTR_4, (idx >> 3) & 0x1); digitalWrite(PIN_LED_CTR_3, (idx >> 2) & 0x1); digitalWrite(PIN_LED_CTR_2, (idx >> 1) & 0x1); digitalWrite(PIN_LED_CTR_1, idx & 0x1); } /** * When the tempo index is 0-15, range indicator 1 is lit. * When the tempo index is 16-31, range indicator 2 is lit. */ void setRangeIndicator(int index) { int hi = (int) (index / TEMPO_DISPLAY_RANGE); if (hi == 0) { digitalWrite(PIN_LED_TEMPO_RANGE_1, HIGH); digitalWrite(PIN_LED_TEMPO_RANGE_2, LOW); } else { digitalWrite(PIN_LED_TEMPO_RANGE_1, LOW); digitalWrite(PIN_LED_TEMPO_RANGE_2, HIGH); } }
When the circuit is powered on, it defaults to note A 440 to facilitate tuning.
The full Arduino code can be downloaded here: Metronome.tar.gz.