There is a store called Don Quixote near where I live in Tokyo. However, Donki (as it’s called by locals) is a singularly unique store. The experience of going to Donki is similar to visiting Fry’s Electronics in Silicon Valley — the first time you walk in there and see oscilloscopes next to Ritz crackers it boggles the mind. But after living there for a few years you come to take if for granted that you can pick up baby diapers, a bare PC motherboard and some soldering flux in a single trip.
When I first moved here and asked people where to buy certain things, a common answer was “Amazon or Donkey” (I didn’t understand the “donki” shorthand yet). Because it’s one of those places where you can literally find just about anything. It’ll be the cheap crappy version of whatever you want, but they’ve got the category covered. Also, they are open 24/7 so if you really really need some clean underwear, contact lenses or a rice cooker at 3AM and don’t mind navigating around the drunk foreigners taking pictures, you can hit up donki.
I went there recently (cat food, socks and file folders) when I came upon a shelf full of digital clocks that claim to set themselves when you plug them in. In a country where there are so many completely useless electronic features on everything, including the toilets, this struck me as a terribly useful and practical improvement on the normal digital clock. And the price for this marvel was 900円 which at the time I bought it was about $7.50 USD. I picked one up, plugged it in and sure enough it set itself after a few minutes. Which meant the very next thing I did was tear it apart.
Break it, then Make it
I’ve always liked taking things apart to see how they work. In this case, I knew what I was looking for because the name of the product is “Raiden: Radio Wave Control clock” so it must be using a radio signal of some sort. When I opened it up, the radio antenna was immediately obvious and freakishly huge. In the picture below it’s in the lower left hand corner and consists of a 2 inch ferrite rod wrapped in copper magnet wire.
In an age where everything has gone digital and tiny, I’m used to seeing those little on-chip antennas or maybe just a long copper-clad trace on a board or a short wire whip antenna. But this thing looked like a prop from an old Frankenstein movie or something. It looked rather out of place next to the tiny clock circuit board and I was intrigued…
I found a good Wikipedia article that explains how the so-called JJY radio signal works. Amazingly the signal covers all of Japan with just two transmitters. It consists of a simple low data-rate signal transmitted at what they call a “long wave” frequency of 40kHz or 60kHz (the two transmission sites operate at different frequencies). These long waves do a much better job going through buildings and walls than the high frequency waves used for things like WiFi or cellular phones, which is why they can get away with just the two transmitters.
To put it in perspective, the human ear can hear frequencies up to 20kHz so these waves are transmitted at frequencies just an octave above that! WiFi operates at 2.5 GHz which means you could fit 50,000 cycles of a WiFi signal in a single wavelength of the Japanese national time signal. Thank you, Google for doing the math.
Gimme Gimme Gimme!
At this point all I could think was “I want a JJY receiver module for my clock projects and I WANT IT NOW!” But scouring online most of what I found was people desperately trying to purchase them, but they are kinda scarce and cost around $30 USD. I got a whole damn clock for a quarter of that, so I proceeded to figure out how to scavenge the part from it. The first thing I did was to go back to Donki and buy 4 more clocks because I knew I had a good chance of breaking at least one or two in the process. And of course in the case of success, I’d want more for future projects.
You can clearly see where the two antenna wires attach to the clock’s circuit board. Flipping the board over to the other side we can see they go to an area of the circuit board with an epoxy-covered module of some sort and a few passive components. Given the weak RF signal it’s trying to pull in, the fact that it’s separated from all the digital stuff made me fairly confident this was the time decoder module.
After some Google searching I discovered that Seiko, the company that makes the clock, also makes the SM9501A Radio Controlled Clock Receiver IC which is probably how they manage to sell that clock so cheaply. But I had no way to verify this, as the IC was encased in epoxy. This also meant I had no idea where the interesting signals were on the board. But I did notice there were a few test pads near the RF circuit. If you were going to test these clocks after manufacturing, the self-setting mechanism would probably be important to test. So with nothing more than this semi-educated guess I wrote a small data-logger program for an Arduino and watched the test pad signals for a few minutes.
There was only a single pad that showed signs of data being transmitted. It was initially high, then after a few seconds it went low and then oscillated wildly for about 30 seconds and then finally got into a rhythm of a single pulse every second. What I was seeing was the RF receiver chip going through a cycle of tuning, AGC and filtering trying to get a clean signal from the transmitter. It was looking like it had stabilized and then it went bonkers again sending what appeared to be total noise. This particular clock ships nationwide in Japan and thus switches between the 40kHz signal that is strongest in South Japan and the 60kHz North Japan signal looking for the strongest and cleanest signal. There is a way to tell the chip which to use, but I couldn’t figure out how to access that pin, so I just let the clock do its thing and snooped the signal.
The quality of the signal and the time to acquire a lock varied a LOT based on where in the house the receiver was, time of day, etc. It turns out this is to be expected and the Japanese government ministry in charge of this has data about expected field strength by time of day on their web site. So far, so good. Now I had to figure out how to decode the signal I was pulling off the circuit board.
Just A Minute…
In my attempts to find an off-the-shelf module I read about some American and European versions (it turns out that many countries have such a time signal, although they each have different carrier frequencies and encoding standards) that output the time data as serial protocol data. But the signal I was seeing was super slow and would have effectively been less than 100 baud I believe. So going back to the data sheet for the chip I believed was being used, I saw that the chip doesn’t actually decode the time signal as such. Rather, it handles all the tuning and noise reduction, etc. and then presents the raw signal as digital data. The diagram below from the SM9501A data sheet explains this nicely.
The input is an AM radio signal — 40kHz carrier, with amplitude modulated over time. The chip takes the input wave, which I’m sure bears little resemblance to the beautiful signal shown above, and tries its best to pull a clean digital signal from it. When everything is operating perfectly you receive a single bit of data every second. A bit consists of a low-power pulse of some duration, followed by a full-power signal for the remainder of that given second. This scheme can encode 3 different values: a zero bit, a one bit and a maker bit that is used to frame the data packets. The scheme and the meaning of each of the 60 bits of data is explained well in the Wikipedia entry for the Japan JJY time signal.
Once you have a string of 60 bits, decoding the time is trivial. It turns out the hard part is getting a clean signal. And the method that the SM9501A uses to pass data to the computer is very useful here, because it gives us a lot of insight into what’s going on and even the ability to reconstruct data from a noisy signal.
If the IC hasn’t quite tuned the automatic gain control and filtering, then what you get are spurious transitions between high and low voltage on its output pin. A perfectly clean signal will have exactly one low->high and one high->low transition per second, whereas a noisy signal with spurious transitions will have more than that. My JJY decoder library uses a pin-change interrupt to receive the transitions, and it keeps a count of how many transitions occurred in each of the last 4 seconds. This means with a single number (pulses in the past 4 seconds) we can determine if we have a clean signal or not. Additionally it means that you can see if the signal is trending towards clean (fewer pulses each second) or not.
The chart below shows 60 seconds of signal metrics from a freshly powered-on system. The top graph is of pulses-per-second, where the green range is the perfect 2 pulses per second and yellow and red are increasingly noisier values. I had to clamp the first few values because they were so far above the others — values in the thousands! But as you can see it quickly converged to a good signal after about 15 seconds or so.
The blue portion shows the pulse-width of the AM signal for each second. A long 800ms pulse is a zero bit, a 500ms pulse is a 1 bit and a tiny 200ms pulse is a marker framing bit. If the pulse could be decoded then there is a green bar underneath indicating we received valid data for that second or red otherwise. And finally the actual decoded bit is overlayed on top of the blue pulse for those seconds where we received valid data.
You sync to the signal by finding 2 adjacent marker bits. This indicates the top of the minute, as there is a marker bit at the 59th second and the 0th second of each minute. You can see that this occurred at 33 seconds into the trace above. From there it’s a simple matter of assembling the bits into a number. One odd thing is that the number is encoded in BCD but that’s the only gotcha.
That’s a long time, actually
When you are sitting there staring at a serial debug console waiting for the signal to converge and it finally does, it’s very exciting. But then it must remain clean for an entire minute, which all of a sudden feels like an eternity. The full 60 bits of data contains the year, month, day-of-month and some other data as well. But for my simple clock application all I really need is the hours and minutes.
Thankfully getting the hour and minute requires only 20 seconds of clean signal past the start-of-minute marker, which I’m able to get fairly reliably where I live. For best practice, I should wait for the parity bits that come 37 seconds in which would allow me to validate the hours and minutes but so far it seems to be working well. There’s enough things that have to go right to get the first 20 seconds of data that it seems unlikely for one of the bits to be wrong.
Sometimes the stars just don’t align and the signal is only clean for a few seconds here and there. After a while — seems like maybe 10 minutes or so — the receiver chip gives up and shuts down. Presumably because the clock is powered from 2 AA batteries and it’s trying to conserve power. When that happens, there is a button on the clock you can push to ask it to try again. I haven’t worked this logic into my library yet, but I think it’s just a matter of pulling that line low for a second to simulate the button press.
Once I removed the case, speakers, batteries, etc. the size of the board and antenna are small enough to fit into an Arduino-powered clock. The full clock board is around 3in x 1.5in in size. Theoretically I could cut off all the digital side of the board and just use the module, but I don’t know what magic the CPU does to initialize the receiver IC when it comes out of reset etc. so I’m happy making do with the full board for now.
Like anything I’ve ever written, what on the surface seems simple always ends up accumulating some complexity by the time you’re done. The code here is no exception to that. But as is also typical, the bits that look the least “clean” are the parts that make it actually work robustly.
There are 3 stages to the decoder pipeline:
- dataISR() — a pin-change interrupt stores millisecond input timestamps in a buffer. It also fills in metrics about the number of pulses received in the past 4 seconds
- DecodeInput() — called periodically from the main loop, converts the raw pulse timestamps into a string of bit data. It also does some reconstruction of noisy data when things are almost fine but not quite. The error reconstruction and parsing works best when it has a few seconds of data to work with, so I call this every 4 seconds from my main loop.
- ParseInput() — looks at the accumulated bit string and pulls the time data out of it
There’s also a bit of logging etc. that can be turned on and off to help see what’s going on during board bring-up. The code uses 3 pins, but you can ignore the LED and BUTTON pins as they are only used for debugging and status purposes. PIN_INPUT is the signal coming from the SM9501A decoder IC:
int PIN_LED = 9; // Signal indicator int PIN_BUTTON = 8; // Press to show debug logs int PIN_INPUT = 3; // Data from radio decoder
Want to build your own? Follow these simple steps: