I thought about building a clock module for Kosmodrome Phase 1, then decided I didn’t really need one at the time because Phase 1 had no modules that would need a clock. But now I’ve built the G.E.A.R. Sequencer and YASH. Clock needed for Phase 2!
At one time my attitude was that it was laughable so many available clock modules were microcontroller based. Seemed like overkill to me, using an MCU just to go “honk honk honk”. Why not just a square wave oscillator? Well, as someone pointed out to me, microcontrollers have very accurate clocks. You can get 120.00 Hz and if you record one track now and another one next month, you can get the same 120.00 Hz next month. A 555 oscillator, on the other hand, is not so reliable, and if you need a precise speed, good luck dialing it in with a pot. And while you can do binary clock division with a binary counter, or division by up to 10 with a decimal counter, a microcontroller can do division by anything. You may not want to divide a clock by 29 very often, but if you do, how are you going to do it analog?
Besides, if you have a microcontroller, you can display the clock speed on a 7-segment display or an OLED, which is definitely cool.
So I’ve gone 180° and put together a very much microcontroller (Nano) based clock module.
First let’s consider speed and tempo. You can talk about clock speed in terms of clock or pulses per minute. But in music it’s common to talk about tempo in terms of beats per minute (BPM). A beat is a fundamental unit of rhythm, with the duration of a quarter note usually (not always) corresponding to a beat. Of course there are shorter notes than quarter notes, and so it’s good to have a clock that produces multiple pulses per beat (PPB) — 4 of them, maybe (usually corresponding to sixteenth notes), or 8, or whatever. More about that below.
This module has one knob, a tactile push button, and a 1.3″ OLED. Six jacks: A beat output (one gate per beat), a clock output (one gate per clock pulse), a “Div 2” for the clock divided by 2 (a gate at every other clock pulse), Div 4, Div 8, and… Div N? More about that below, too. Each jack has an LED to indicate when that output is on. (To reduce big steps in the current draw, I used what might be called super bright LEDs — but could also be called super low current LEDs, for reasonable brightness levels. With large series resistors, each is drawing less than 0.5 mA and isn’t blinding anyone.)
When using this module, mostly you’re in “run mode,” where the OLED displays the tempo in BPM, in a big font, as well as PPB and PPM (pulses per minute). Also either “MM” or “INC” in the corner, about which (again) more below, and a dot flashing once per beat. In run mode, turning the encoder raises or lowers the tempo. You can also tap the button a couple times to set the tempo. Push the encoder and the clock stops, push it again and it restarts.
If you long push the encoder, the “MM” in the corner changes to “INC”, or vice versa. In the INC (increment) submode, you can change the tempo to any whole number BPM: Turning the encoder one notch changes it up or down by 1 BPM, and tapping sets the tempo to the nearest whole number BPM. You can set any whole number from 8 to 208 BPM. 8 BPM? Yes, that’s very slow, but you can get it.
But turning the knob through 168 notches to get from 40 BPM to 208 is a pain, and while the difference between 119 BPM and 120 BPM is probably too small to worry about, if you need such slow tempos as 10 BPM at all, 10 to 11 BPM may be too large a leap, relatively speaking.
So enter the MM — Maelzel Metronome — submode. Metronomes (mechanical ones at least) do not give every possible tempo, but only certain particular, standard ones: 40 BPM, 42, 44, 46… (going up by 2) to 60, 63, 66, 69… (up by 3) to 72, 80, 84, 88… (up by 4) and so on, up to 184, 192, 200, 208 (up by 8). The size of the tempo increment is roughly 5% of the tempo itself — it’s a little like E48 resistor values — and it only takes 38 steps to get from 40 to 208, instead of 168.
While the standard values cover 40 to 208 BPM, the pattern is easy enough to generalize further by dividing by 2, 4, or 8. In the clock module’s MM submode, turning the encoder goes to the next or previous generalized MM value, and tapping gives you the nearest generalized MM value, in the range from 7.5 (= 60 ÷ 8) to 208 BPM.
Long pressing on the tactile button switches you from run mode to “set mode” (and back again). In set mode you can use the encoder to change:
- The “/N amount”, that is, the number the clock is divided by for the Div N output. Set this to 17, if you really want to, to get a gate on that output every 17 clock pulses.
- The “/N offset”. If the offset is 0, and if for instance the Div N amount is 4, then you get a Div N gate at the same time as each Div 4 gate. But change the offset to 1 or 2 or 3 and the Div N gates come 1 or 2 or 3 clock pulses after each Div 4 gate. You can think of Div 4 as being on the beat and Div N as off the beat.
- Pulses per beat (PPB). You can set any value from 1 to 24. This doesn’t change the beat output (BPM stays the same), but it changes the undivided and divided clock outputs.
- Width. This is the duty cycle of the (undivided) clock output. You can set any value from 5% to 95% in increments of 5%. (The other outputs have the same absolute width as the undivided clock.)
Finally, if you don’t press the button or press or turn the encoder for 60 seconds, the screen goes blank. This is to extend the OLED’s lifetime. The next press or turn will bring the screen back.
One other change from SM Tik-Tak is internal and you’re not likely to notice, but it is essential to get the fastest speeds. The original module used a timer library that just polls the millisecond timer in the program loop. That’s fine with a simple user interface and slower clock speeds (the original’s range is 60 to 500 clock pulses per minute), but with the OLED and encoder and all that, the program loop could potentially slow down too much for a polling timer to keep up, especially at high values of PPB. So I switched to using an interrupt timer library — and an interrupt based encoder handler too, because the timer interrupts were blocking encoder events. It adds a little complication to the code (only a little, the library makes it pretty easy) but it keeps the clock speed rock steady. At 24 PPB and 208 BPM the maximum clock speed is just under 5000 clock pulses per minute. At 95% duty cycle there’s a gap of only 600 µs between pulses. And yet it keeps up, not losing any gaps!
More details including schematics, design files, Gerbers, BOM, etc. in the repo.

