Metronalmost

metronalmost (noun): A metronome that beats at almost, but never quite exactly, 60 beats per minute.

A printed metronalmost.

This infuriating object is designed to thwart the goals of Hackaday's One Hertz Challenge contest.

we want you to design a device where something happens once per second

This device, by design, will never, ever, tick exactly once per second. The metronalmost will sometimes tick once in every two seconds, or twice in every one second, but never exactly once in one second.


Ad astra per alia porci - Last place, or bust! - Ceci n'est pas un métronome


The core component this project is designed around is a TowerPro MG946R servo motor. It's weighty enough that it will stay where it's placed - even when the servo's horn is waving our metronome-hand around. I built a prototype of the electronics and placed a case made from scrap cardboard over the servo and circuitry, like a cloche.

A wiring digram for the metronalmost. A scrap cardboard prototype metronalmost.

The servo is quite happy to operate from the 5 volts supplied by the USB connector on the NodeMCU DevKit. It doesn't seem to draw enough amps to trip the supply or brown-out the microcontroller. The 3.3 volts supplied by the ESP8266's GPIO pin is high enough to be considered "on" by the servo's control board, so we don't need to do any level shifting.

The only problem in assembling the metronalmost's electronics is there are no adjacent pins on the DevKit to allow Ground, Power and Signal to be directly connected to the servo's socket. Instead, we can use a 1x1 right-angled header pin to create a "false pin" and connect it to one of the GPIO pins with a short jump wire.

A right-angled header in a servo motor connector. The right-angled header adjacent to the ground and 5 v pins.

The ESP8266 can now be flashed with MicroPython, and we can test the Servo's range of motion with a small script.

from machine import PWM, Pin
from time import sleep

out_pin = PWM(Pin(2, mode=Pin.OUT))
out_pin.freq(50)
out_pin.duty(35)

while True:
    out_pin.duty(30)
    sleep(1)
    out_pin.duty(40)
    sleep(1)    

Up to this point we've done everything we would need to build a true, accurate, metronome. It's time to break out the maths and build a model for our metronalmost that can be proved to never return Hackaday's target 1 Hz tick rate.

A normal, or Gaussian, distribution can be used to build a mean-weighted random number generator. Numbers will be clustered around the middle and only rarely appear towards the edges of the range.

If we take a notch out of the middle, the distribution will not generate numbers within that smaller range.

A normal distribution. A normal distribution with a much smaller standard deviation. The result of subtracting the second distribution from the first.

If we look at this notched-out function's cumulative distribution function instead of its probability distribution function, we can see a flat spot over the notch. This means that numbers are not being generated within this flattened range. Transposing the axes allows us to turn this in to a mapping function that turns a uniform random number (0.0–1.0) in to a centrally weighted, but stepped, number generator.

The cumulative distribution function of the result of the previous subtraction. The mapping function that gives us every number between 0.0 and 1.0 except 0.5.

This new number mapping function maps 0.0 to 0.0 and 1.0 to 1.0 as normal, but maps 0.49 to 0.45 and 0.50 to 0.54. The discontinuity means a value of 0.5 can never be generated. Applying this mapping over a period of between 0.5 and 1.5 seconds will give us our almost, but never quite, 1 Hz metronome.

Now our code's generating an almost-1 Hz rhythm; we need a suitable case to house it in. Taking inspiration from our cardboard prototype earlier, I designed the following papercraft net that can be produced on any home colour printer. Faux-woodgrain is the hallmark of the best cheap-and-nasty electronics!

The papercraft net for building a metronalmost case.

Real metronomes often have a list of tempos such as Largo, Adagio and Allegro to mark how far out you should move the weight to moderate the ticking. I've included some suitably silly tempos for our display.

Putting the electronics, the code and the papercraft case together gives us our finished metronalmost.

It's funny, but leaving the metronalmost running for any length of time really seems to put your nerves on edge. You can't quite get a handle on when the next tick will occur, and that seems to make you feel especially uneasy. It feels like my heart actually starts to race when I'm in the room with it for more than a few minutes.

2025-07-07

Leave a comment