Friday, 7 December 2012
Simple LED Clock
For the last 25 years or so, I've had an old LED bedside clock by my bed. It was discarded by my parent's after they'd used it for a good few years as the radio broke, so is probably about 30 years old in total. I think I fixed the radio, but I never used that anyway, At some point, I replaced the alarm-triggered radio with a relay to turn on first a light and later (ironically) a radio. But for most of those years, it simply stood there with 3 1/2 seven segment led displays showing me the time. It was a 12 hour clock with an LED to indicate PM. I personally prefer a 24 hour format, but I put up with that as I suspect the leftmost digit can only display a 1 (i.e. is missing the segments to do 20:00). Also a couple of the segments occasionally flicker at half brightness when they are meant to be off, but again that wasn't a major issue.
However, last week I noticed it was out by a few hours. I readjusted it and later found it was out again. It seemed to be ok for a day or two, then I was it was about 6 hours out again. I reset it and then saw it was incrementing the minutes about every 30 seconds! A quick check with a meter showed the mains frequency was 49.95Hz, so it couldn't be that. At this point, I decided it might be time to replace it.
I have designed and made a number of clocks over the years, many using a 40 pin PIC (16F874), multiplexing the displays with a high side driver (ULN2803) an open collector driver (7407). I also liked to use tri-colour LED's which faded through the colours from red to green as part of the display multiplexing.
The PIC based ones main clock was derived from a 4.194304 MHz crystal which can be divided that down to get a 1 Hz counter (4194304 = 2^22). For this, I'd decided to go for the easier option and use one of the DS1307 real time clocks. This should have sufficient accuracy and a battery backup. This is a nice simple DS1307 module from adafruit.
I went through a few designs for various display options, the favourite using I2C IO expanders (MCE23008 or MCE23016) with direct drive. I finally went for something even simpler. An I2C controller 4x7 segement display module, also from adafruit.
The code with then almost trivial as well. Ask the rtc what time it is, update the display. sit around doing not very much for a while. Then start again. I went back and added a 2 Hz flash of the colon so that the Arduino didn't get too bored.
I didn't even bother with setting buttons as the adafruit library made it easy to sync the RTC to the PC time, and because of the battery it maintains that time. The date is also set (although not displayed - something I might think about for the future?) so I could expand the code to adjust for daylight saving.
So there it is, about as simple as I could make it. Lets hope I get 30 years out of this one!