Pages

Saturday, 25 February 2017

Arduino "analog" (analogue!!) clock.

I conceived this daft project a while back, after being given a box of surplus moving coil meters...

An Arduino driving three analogue meter movements to show hours, minutes and seconds.

There are lots of designs on the net, so here's another.

Now, I'd seen several clock designs on the net, whereby the Arduino's PWM signal is used to keep accurate time. I must say, whilst the idea is sound, most of the stuff I got hold of and downloaded didn't work for one reason or another.

The idea goes like this...

We couple the PWM output of a pin to an interrupt. We set the PWM output going with a mark to space ratio of 50%. The PWM frequency is governed by the internal architecture of the ATMEGA328, and is derived by some programmable timers, which divide down the clock frequency of the micro. The clock frequency on "posh" arduino boards is generated by a nice crystal (on not-so-posh boards, it may be a ceramic resonator, not so accurate). 16MHz. So dividing down this 16MHz should give quite a low error. Good news. So all we need to do is set up an interrupt, so that every time it sees a rising edge of our PWM signal, it increments a counter.

I measured the frequency of the PWM signal, and on a crystal clocked board, with a ATMEGA328P at 16MHz, it's 490.36Hz. (Due's/ Mega's etc will vary as the micro/clock frequency is different).


Excellent, so all we need to do is add a second on every time our counter hits 490 (Let's forget about the 0.36, shall we?). It should keep reasonable time.


After running for a day or so, the drift (caused by the 0.36 Hz left over) does become noticeable, but I recon it's no worse than a DS1307 RTC. So, to correct for this drift, I'll add in a 433MHz radio receiver module, and make it updatable from the GPS Master Clock project. Excellent.

So after a bit of tinkering this was born...


I've added three momentary push buttons, which allows the time to be set manually, and a "Cal" button. Once cal is pressed, the PWM output is switched off for 10 seconds, and then set to 100% for 10 seconds. This allows the user to set the zero mechanically on the meters, and the FSD (Full scale deflection) on the meter using the three pots, R7,R9 and R11. All three of my meters require 1mA for FSD, yours may vary, and you can alter the value of R7, R9 and R11 to suit your meters.

Each meter is driven by a small transistor. With my meters needing just 1mA, there's absolutely no reason why I couldn't just eliminate the transistor and drive the meters directly from the output of the micro to ground. I've added them in, just in case I need some more current, or decide to drive them from a higher voltage source than 5V. 

There's two toggle switches too... 

The 24 hour select switch changes the hour display from 0-24 hours to 0-12 (actually 12:00 or 0:00 is 0 on the meter, but it'll make sense in a minute)

The smooth select switch I'm rather pleased with. I started out wanting the seconds meter to move smoothly, rather that "tick" once a second. I coded this, and then thought I'd apply the same to the hours and minutes. This has one very pleasing effect. All the meters are moving smoothly. so the hour meter will read halfway between 1 and 2 when it's 1:30 ... same with the minutes. It also means that FSD on the hours meter occurs at 23:59 (in 24h mode or 11:59 in 12h mode), rather than going straight from 23 to 0 ..... 

Now, one big issue is daylight saving time. My master clock transmits GMT. I've added a routine that detects BST (British Summer Time) and adds an hour on if required. I've blatantly stolen this routine from here, , and modified it because I'm avoiding the time.h library (although I've no reason too!).

So a prototype is created....

Some meters selected, and calibrated ...












... and a clock created!...



Here's the code ...

No comments:

Post a Comment