This project was inspired by the Metronalmost project done by Mike Coats. I found his submission to the Hackaday One Hertz Challenge Contest to be delightfully irritating and oddly interesting. I particularly liked the idea that you could use a mapping of values across a distribution as the basis for skewing the randomness to accuracy over time. It also demanded that I create something to 'fix' it.

Project Goals

  • Preserve the spirit of the Metronalmost constraint "This device, by design, will never, ever, tick exactly once per second"
  • Provide an accurate time reference to help the Metronalmost tick as close to once per second, but never exactly.
  • Use the Metronalmost as a synchronization signal to accurately set the time on a clock.

How Does It Work?

Thankfully, we are constantly being bombarded by RFI that gives us nanosecond accurate time and date information. There are plenty of options for GPS disciplined oscillators, but a GPS disciplined metronome would be absurd. So let's make one...

A GPS module can pick up the satellite signals that will give us the current date and time. Using this, we can set the time on the metronome controller accurately as a basis for our clock signal. Many of the GPS modules can also provide a highly accurate PPS (Pulse Per Second) signal that could be used to very accurately drive the metronome. That is beside the point...

What we can do is use the GPS messages and the PPS signal to determine when any given minute starts. This is the basis for the data that we want send to the clock. We can now create a 60 bit IRIG-H timecode, in the style of radio station WWVB, which can be sent to to any receiver that requires synchronization. Just to demonstrate the this is not just some wibbly wobbly, timey wimey whimsy, we can throw in things like Daylight Savings Time, error correction, and date and still have some bits left over for flavor.

Sending the Signal

Drawing the rest of the owl will require that we find a way to use the almost once per second ticks of the metronome as a carrier for the 60 bits of data we need to send each minute. But first, let's talk about how we propagate the signal. In the interest of time, I'm just going to hard wire a connection between the metronome and the clock. The signal will be indicated by a HIGH output for the same duration of time of each tick of the metronome. The clock can measure the duration of each pulse to determine what is being sent. Future versions for the project will include as many signaling options as possible so we can share our time with as many devices as we can dream up.

  • ISM band
  • Audio
  • Infrared
  • Ultrasonic
  • Physical triggers

So now that we know the date and time (thanks, GPS!), we have to figure out how to get our time code modulated over the tell-tale heartbeat of the metronome. Since we're never ticking at exactly once per second, we can break the ticks into less than one second and more than one second. With that, we can manipulate each sequence of 60 ticks such that we can send our time code. There are a few problems with this that we need to solve...

With all that on the table, we can create our sixty bit time code, use our distribution mapping to create sixty less than/greater than one second pulses, trigger the servo for the metronome, and send our signal across the wire. Here are some details on the WWVB Timecode format.

The clock itself is as straightforward as the rest of this project. We receive the signal, detect the data frame, decode the data, and set the clock. Everything is amazingly complete, consistent, and well documented across the ESP32, MicroPython, and CYD (Cheap Yellow Display) ecosystem so what could possibly go wrong?

There are Problems

What time do we start?

If we don't put our time code in some kind of data frame, it will just look like a series of ones and zeroes and can not be interpreted. To get around this, the time code uses a third signal as a MARK between...

Read more »