Controlling a clock with an Arduino

Update: The Arduino system is fine; the only thing you have to take into consideration is the 9.54 hour rollover event, which Rob Faludi has provided an excellent solution for here. I made up a nice little over-analysis of the issue, available here.

I have been wanting to make a variable-speed clock for a while, so this weekend I picked up a cheapish clock unit (thrift stores are a great source!), and played around with using the Arduino to control it. In summary, I was able to get everything going, but there are some issues with the Arduino software that are going to prevent making it a really accurate clock. Explanation, source code after the break.
Clock controller circuit

Part 1 – Hardware
The mechanical bit is quite simple. The clock functions in a similar fashion to a stepper motor, in the sense that you charge an electric coil to get the mechanical bit to move forward a precise amount. In this case, each firing moves the second hand one second position forward (and makes the familiar tick noise). To ‘fire’ the electric coil, you simply put a voltage across it. The only complicated bit is that you actually have to reverse this voltage to advance the clock to the next step. This is accomplished by using two of the Arduino pins, and switching their polarity. (note: click on the picture to view the embedded notes). On the clock I dismantled, there was a little embedded controller. I used a razor blade to cut the copper lines between that and the connections to the electromagnet so that the original chip would be disconnected, and left it alone.
Detail

When we engage the coil by putting a voltage across it, it starts to draw current which then sets up a magnetic field through the coil. This magnetic field then applies a force to a permanent magnet that is attached to a gear, causing it to rotate and line up with the electromagnet. This gear turns exactly 180 degrees, and is connected to a series of gears that translate the 180 degree rotation into a 6 degree rotation (a 1:30 gear reduction). For the next cycle, we have to reverse the voltage that we apply so that the magnetic field we create will be in the opposite direction, and cause the permanent magnet to rotate again. One could also imagine a mechanism using a spring and a ratchet to pull the permanent magnet back into position, but that is not how these clocks work.
Profile of the gear works

So, knowing all this, we should be able to connect up each end of the electromagnet to the Arduino and have it working. Because it is such a low power device (they are made to run on a single battery for months, if not years), it can be powered directly from the Arduino ports. There are only two things we have to consider in the circuit. First, a resistor should be placed in series with the coil to limit the amount of current it can draw. I chose two resistors with a value in the range of 50 ohms, and placed one at each end of the coil. You may need to experiment with these values to see what works. Second, discharging and charging the magnet can create high voltage spikes (it is basically an inductor), so it is recommended to place diodes from ground to each of the electromagnet. This will help prevent the voltage from going any lower than the diode drop, which is probably around .7 volts for the diodes I chose.
Schematic

Part 2 – Software
Here is an example routine demonstrating how to get the clock to work. The doTick() function does all of the hard work, keeping track of which way the clock has to be pulsed next. This example driver is intended to simulate a standard clock. The speed that the clock ticks at can be adjusted by modifying the 1000 ms delay in the loop() function. This is actually where my project is going- I want to try out some fun things with innocent looking clocks that are completely bogus.

Unfortunately, there seem to be a few issues with the millis() command as I am using it, especially for clock control. The first problem is that it doesn’t look like it is actually ticking at a rate of 1ms. Based on the clock division that is being used (and assuming the system clock is 16 MHz), it appears that it is ticking slightly fast, with a period of .976ms. This is possibly not a big issue for most applications, but it is a showstopper for a clock- that is simply way too much error. It looks like there is also an issue with the millis() command producing strange output near the end of its range, but I am still looking into that one. Based on these points, I think I am going to pick up a real-time clock chip and use that as a timebase for my clock. I have seen them for around $4 so they should not be to big of a deal to integrate into a project.

// Clock Tick Demonstration
//
// By Matt Mets, completed in 2008
//
// This code is released into the public domain.  Attribution is appreciated.
//
// This is a demonstration on how to control a cheapo clock mechanism with an Arduino.
// The clock mechanism works by using an electromagnet to pull a little fixed magnet,
// similar to how a DC motor works.  To control this with the Arduino, we need to hook a
// wire up to each side of the electromagnet (disconnect the exisiting clock circuity if
// possible).  Then, hook each of the wires to pins on the Arduino.  I chose pins 2 and 3
// for my circuit.  It is also a good idea to put a resistor (I chose 500 ohms) in series
// (between one of the wires and an Arduino pin), which will limit the amount of current
// that is applied.  Once the wires are hooked up, you take turns turning on one or the
// other pin momentarily.  Each time you do this, the clock 'ticks' and moves forward one
// second.  I have provided a doTick() routine to do this automatically, so it just needs
// to be called each time you want the clock to tick.
//
 
 
////// Board Setup /////////////////////////////////////////////////////////////////////////
extern unsigned long timer0_overflow_count;
 
int clockA = 2;          // Set these to the pin numbers you have attached the clock wires
int clockB = 3;          // to.  Order is not important.
 
int tickPin = clockA;    // This keeps track of which clock pin should be fired next.
 
 
// Initialize the IO ports
void setup()
{
  pinMode(clockA, OUTPUT);
  pinMode(clockB, OUTPUT);
 
  digitalWrite(clockA, LOW);
  digitalWrite(clockB, LOW);
 
  Serial.begin(9600);
}
 
 
// Move the second hand forward one position (one second on the clock face).
void doTick() {
 
  // Energize the electromagnet in the correct direction.
  digitalWrite(tickPin, HIGH);
  delay(10);
  digitalWrite(tickPin, LOW);  
 
  // Switch the direction so it will fire in the opposite way next time.
  if (tickPin == clockA)
  {
    tickPin = clockB;
  } else {
    tickPin = clockA;
  }
}
 
 
// Main loop
void loop()
{
  unsigned long startTime = millis();
  unsigned long temp;
 
  // Pretend to be a regular clock, and tick once a second.
  while (true)
  {
    startTime += 1000;
 
    // Wait until a second has passed.  Note that this will do ugly things when millis()
    // runs over, so we only have about 9 hours before this version will stop working.
    while (startTime - millis() > 0) {}
 
    doTick();
  }
}
This entry was posted in tech. Bookmark the permalink.

63 Responses to Controlling a clock with an Arduino

  1. Becky says:

    Who says the clock has to be accurate? Could be cool to use as an April Fool’s joke or to tell some other kind of information besides time, depending on what graphics you put behind the face. I’m thinking you could divide the face up into pie slices and label them with different things like the meals of the day or perhaps something more like the wheel of fortune.

  2. mahto says:

    Hi Becky,

    Yeah, it doesn’t have to be accurate, however I would prefer to control the inaccuracy. I guess a fudge factor would work because I know what the difference is. It really seems like there is a bigger problem with the millis() function though, besides it being some percentage off. I promised myself I would sleep tonight, though, so maybe I will check it out tomorrow.

    Also I like the idea of changing the information displayed- one idea I had was to hook it up to a heart monitor, to have a real beating heart clock. Making the clock show what function you are supposed to do (like sleep, eat) seems pretty interesting as well.

  3. spiffed says:

    Apparently you can replace the 16MHz oscillator with a 32.768kHz crystal, run from the internal-RC oscillator and use the crystal to power the timer for RTC purposes. http://forums.ladyada.net/viewtopic.php?t=4418

  4. mahto says:

    Hey Spiffed,
    Thanks for the link! I was thinking of hooking up a clock that will divide nicely into 1ms intervals into one of the interrupt inputs, and generating my own ticks off of that. The clock’s original circuit could be a good source for that. Presumably the crystal that came in the clock could be used for the method you mentioned as well.

  5. Joe R says:

    Oh my god!! Man you are the best!!!!!! I love you! This is exactly what I have been looking for!! Thank you! Thank you! I’m not worthy!I’m not worthy!I’m not worthy!
    Thanks so much man!
    Thanks
    Joe

  6. mahto says:

    Thanks Joe :-). Let me know when you get your project going!

  7. s says:

    check out the real time clock ds1307 it works over I2C

  8. mahto says:

    Thanks for the tip- the ds1307 seems nice, however I really would like a part that generates a 1KHz reference signal that I can use to drive an interrupt on the Arduino. All of the ones I have seen will only do 1024 Hz, though :-(. Perhaps I need to re-engineer my idea…

  9. mahto says:

    Hi S-

    Thanks for the tip about Rob Faludi’s post. I finally sat down and took a good look at the millis() function, and realized that I spoke too soon. I’m not entirely happy with having to have a workaround, but it will certainly work. I was wrong about the system being inaccurate, and I will update this post to reflect this…

    Cheers,
    Matt

  10. pynn says:

    Thank you for a nice project and information!
    I have built an accurate clock but in digital display (check my blog http://picnote.blogspot.com).
    Now, I am thinking of making near atomic clock acuracy in analog display.

  11. mahto says:

    Hi pynn,

    Very cool! Keep up the good work!

    Cheers,
    Matt

  12. Mike says:

    Thanks for the clock info. I can’t believe I happen to run across this (I was looking for TOTALLY unrelated info) yet it fills a need in model railroading (MRR)that perhaps none of you have heard of: a fast clock.

    When MRRs are running an operating session they often use a special clock that’s called a fast clock that can be set to run from 6 to 12 times normal speed. This compresses the time it takes to run through train schedules as model trains don’t take nearly as long to move between points as real trains. A “cheap” fast clock runs at least US$80 and they go WAY UP from there.

    This project is a real bargain at $34 for an Arduino and less than $10 for a clock. Of course, the code would need tweaking to do the speed ratios but that’s no big deal. I can already see how a DIP switch package could be used to set various clock ratios.

    To the Bat Cave to dig out the Humpty Dumpty wall clock with the broken frame! It’s project time…

    Thanks again,
    Mike

  13. mahto says:

    Hi Mike,

    You’re welcome. That is a really cool idea, and I hadn’t heard of it. Please let me know how it turns out for you :-).

  14. Roger says:

    Rather than code around the ms rollover, could you use the clocks own timer circuit to provide a once per second trigger? I am thinking of a project I would like to do where the analog clock will tick every other second for 16 hours per day and then catch up for the other 8. In my case, for the 16 hours, I would skip every other second from the clock. When I am catching up, I would advance the clock when I am triggered and also do it again a half second later. Now I only have to keep a state for the slow rate (skip/not skip) and a 500ms delay for the fast rate.

    I am a beginner here. What do you think? Would I be better off just doing it all inside the arduino or using the quartz clock as a reference.

    thanks,
    Roger

  15. mahto says:

    Hi Roger,

    Yeah, I believe you could control the clock that way. I did it this way because I wanted control in the ms range, so that I could slow down or speedup the clock without it being readily apparent.

    Cheers,
    Matt

  16. Roger says:

    Could you tell me exactly which diodes you used. I know nothing about electronics. I’m a software guy. I have the Arduino, I wired the clock. I will have the resistors this afternoon. All I need is the exact diodes.

    thanks,
    Roger

  17. mahto says:

    Hi Roger,

    I’m actually not sure what I used, I scrounged them off of another motor controller :-(. You could probably skip them… I’ll see if I can dig up a good reference number here.

    Cheers,
    Matt

  18. Rob D says:

    I built a touch-sensitive chess clock a while back, and was trying to work out a way to make it reset itself. This, in conjunction with a hall effect switch, would do it!

    NB – I wouldn’t skip the diodes, even for a low-powered motor like this one. The voltage spikes will eventually damage the output pins. Fortunately, any diodes would work, as long as they weren’t zeners :-) I’d look for fast-recovery diodes, to make sure they catch all of the spike.

  19. Tom Adams says:

    One neat idea would be to make a clock that keeps Mars time, or one that keeps sidereal time.

  20. Tim says:

    Lol, I love the electronic hobos! Someone use this to make a reggae clock!

  21. J says:

    Or you could have it up on the wall in a classroom and when you give a test slow it down so that time would seem to drag on to the test taker :)

    • mahto says:

      Thanks everyone!

      @Tim: :-D

      @J: yeah, I actually wanted to use it at the office to slow down right before lunchtime. It could be a fun psychology experiment to play on test-takers as well :-).

  22. Bought a clock today, aiming to make the hands go nuts! Thanks for the inspiration and the electronic hobos.

  23. Yay, works perfectly! I found that I had to up the delay in the doTick() function to suit my particular gear configuration, otherwise the clock would just jump erratically backwards and forwards. 16 milliseconds seems to be the sweet spot.

    Putting only a call to doTick() into the loop() function is fun, too. Makes the clock go quite fast. The second hand does about a revolution per second. And if you hold your finger in the way of the second hand, it makes the clock go backwards and forwards, changing direction each time it hits your finger.

    I’m thinking it could be a cool indicator. E.g. the warmer it gets, the faster the clock goes.

    Thanks again for the detailed write up :)

  24. mahto says:

    Sweet! however, that doesn’t sound like a ‘cool’ indicator at all :-D

  25. Dave G says:

    Hey this is what i have been looking for for a project im doing but im trying to use a pocket watch instead! Though im finding it really hard trying to find where i solder to! Any chance you give some pointers to a newbie who can do more software than hardware stuff :)?

    Dave

  26. Dr. Bob Bob says:

    You could avoid the whole issue with the milli function if you wrote your own timer interrupt. Basically the timer interrupt would fire at a precise interval and then you would count the number of timer interrupts and set a flag for the main to tick the clock. I am not sure how to setup interrupts on an arduino (I have much more experience with PICs) but I know it is possible.

    The interrupt body will be something like
    ticks++;
    if(ticks > TICKS_PER_SECOND)
    {
    clockPulse = true;
    ticks = 0;
    }
    The main loop will be
    while( true )
    {
    if(clockPulse)
    {
    doTick();
    clockPulse = false;
    }
    }

    This would also allow you to do other things with the main loop rather than just burn clock cycles. If you properly calculate the timer interrupt you will be able to have much more accurate time values. This will also be free of the 9 hour limit from the milis funciton which is caused by the overflow of a value. With this you will reset the ticks with every pulse of the clock so it won’t have any overflow issues.

    • mahto says:

      Yeah, this would certainly work, especially (as you noted) if you need the Arduino to do anything else at the same time.

  27. francis says:

    hey wat is that circuit connected to the arduino ?????not the clock the other ciruit with the chip??????????????

    • mahto says:

      Hey Francis,

      The extra circuit is a serial converter board to connect my Bare Bones Board Arduino to the computer for programming. I made it using a MAX232 chip, since I didn’t have an FTDI cable at the time.

      Cheers,
      Matt

  28. Pingback: Arduino boards control cheap clockworks via coil injection - Hack a Day

  29. Pingback: Controlling Clock using Arduino | Povilas Uogintas

  30. Pingback: Another way of Controlling Clock | Povilas Uogintas

  31. Istvan says:

    This is a very good idea. Would it be possible to move two arms independently? The hour arm could be like yours and the minute arm could show the time in the current month, so it would go at a different pace each month.

    • mahto says:

      It would be difficult to do without modifying the clock significantly. You could, however, move the clock hands to any position by quickly advancing the minute hand around and around quickly, to get the hour hand to the correct hour, but they are always linked together unless you somehow add a second motor.

  32. Thanson says:

    @J-That is Genius! I have a history teacher who always tells corny jokes,ect. who would love something like that! Would be really cool with an IR remote to control it.

  33. Edgar Bonet says:

    Hi!

    This is a great article! I need to specially thank you because you gave me the information I needed to build my own project: a 24 hour, single hand wall clock. Starting from your schematic and code, I did the following modifications:

    – replace the Arduino by a “bare” ATmega48A MCU, clocked by its own internal RC oscillator, in order to save on consumed power
    – use SLEEP_MODE_PWR_SAVE to further save energy
    – plug the quartz crystal of the original clock movement into the TOSC pins of the ATmega
    – program the TCNT2 timer/counter to drive the quartz and interrupt the core every 8 seconds
    – program the MCU to pulse the motor every 24 seconds, in order for the minutes hand to do one revolution per day
    – power the whole thing with 2 AA cells.

    Here is the page:

    https://www.logre.eu/wiki/Horloge_analogique_24h

    Sorry, the page is in French, but the code and comments are in English.

    Regards, — Edgar.

  34. Tjeu B says:

    What clock mechanism did you use? I have bought a few clocks, but if I want to reach the PCB, I also have to open the gear compartment, so all the gears fall out…

    • mahto says:

      The clock mechanism came from some random clock I had around, I don’t remember exactly which one. Bummer that all of yours have been difficult to take apart

  35. Martin Rigby says:

    Hi, many thanks for this wonderful project, it has significantly helped me along with mine. There is only one thing that is confusing me, and that is the Resistor values for the coil wires. In the diagram it states 50 Ohms, but in the code header comments it states 500 Ohms. I’m sure in the grand scheme of things it doesn’t matter that much, but I’d like to know which one you used. Regards, and Many Thanks again.

    • mahto says:

      Awesome, glad it is of use to you! I honestly don’t remember which resistor I used. I’d recommend starting with a larger one (500+) ohms, and then decreasing it until you get the movement that you want.

  36. Dave Rugby says:

    Which type of Arduino did you use for this? The basic or the leonardo?

    Great work. Thanks for sharing.

  37. Carlos Peres says:

    Hey, nice tutorial! I envision a spare bedroom full of clocks. The Clock Room. When you have guests, around 0200, have all the clocks start spinning, willy-nilly, cuckoos cuckooing, leds flashing, chimes chiming, then all reset to actual time. Swear YOU didn’t hear a thing the next morning.

  38. Mike says:

    Hi, nice article – I used it as reference for a little clock Tick library made for a project I’m working on.

    https://github.com/mikedotalmond/arduino-tick

    Thanks!

  39. Gómez says:

    Hey… its a great project but i still dont get how to “fire” the coil, where exactly should i fire it…

  40. Hi!
    This is exactly what I was looking for too. Although I had/have some minor problems:

    1) I wanted the clock to go backwards. To achieve this I had to turn the whole coil about 180 degrees. Unfortunately just turning the magnet doesn’t do the trick. See http://en.wikipedia.org/wiki/Lavet_type_stepping_motor for more information on the functioning of this type of clocks.

    2) I’m not the best in electronics, but shouldn’t there be a way to calculate the value for the resistors? My coil has a resistance of 557 Ohms. At 1.5V this makes 2.7mA.
    Inverting the calculation I have a total of 1857 Ohms at 5V for 2.7mA. Shouldn’t I rather eat up the difference with 1300 Ohms instead of 50 or 500? Although using no resistors at all would still pull less than 10mA…

    3) How big is the importance of the diodes? Can’t I just let the current drop through the negative pole of my arduino (by letting this pin a little longer on low)?

    I know, much time passed, since you blogged this…

  41. Pingback: Another way of Controlling Clock | Povilas Uogintas

  42. Pratik says:

    Hi …thanks for sharing this. I’ve been looking to do something like this for a while. I have a very basic question though – Which Arduino board should I get?

    thanks

  43. John D. says:

    Very interesting site! I have a rather old German railway station clock, pendulum operated with a chain and weight to drive it, but also an electric self-winding mechanism, which must have been connected to a central power supply. I’ve been told it’s possible to set up an Arduino controller to “tell” the self-winder to move the mechanism back and forth a specified number of times so as to wind the clock each day, but I am completely ignorant of electronics. The clock runs beautifully but has to be re-wound manually every day. Has anyone done anything like this? (I realize this is probably a very primitive and simple-minded use for an Arduino controller!)

  44. John Reynolds says:

    Another clock-related idea I’ve had is making a “Phase of the Moon” display. The hour and minute hands are not need. The seconds hand would be pulsed to make one rotation every ~28 days. The face of the clock would show the phases from “new moon” to “full moon.”

  45. Pingback: Controlling time with arduino | James Miller Portfolio

  46. lizzie says:

    What type of board do I need to get to do this?

  47. Keith says:

    If you want it to be accurate, use the original clock driver as an interrupt. If you just use one side of the original clock driver, you will get an accurate pulse every two seconds. If you are using a pinchange interrupt, the high then low gives a total of 60 pulses, but high to low is only 30ms from my $1 clock.

  48. jayf says:

    You can forget the resistors if you use PWM pins. I have a NANO running this off of pins 5 and 11, and pass a value of 127 to them. My clock is a little retarded as it requires the coil to be energized at all times in order to run the correct direction. So, instead of 127, delay, 0, I have to do 0, delay, 127.

  49. James Lauser says:

    Interesting design, and I’m intrigued by this.

    I see in your code you have an on-time of 10ms. Another poster mentioned needing to tune his to implementation to 16. In your experience, is something around this amount of time sufficient to “jog” the clock? i.e. if I pulse the oscillator back and forth at 60Hz (16ms), will the clock reliably run at 60x speed?

    • mahto says:

      That’s a good question! I unfortunately don’t have this setup any longer to test it, however I was able to run it at much higher than the regular speed. I think the main issue would be with whether the assembly can handle the heat generated by running it so quickly and at a constant duty cycle.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>