Introduction: Make an Accurate Arduino Clock Using Only One Wire - NO External Hardware Needed!

How to make an Arduino clock - without using external oscillators or clock chips:

(more of my projects on our research website - click the arduino logo top of home page)


You will need:

An Arduino board (just about any flavor will work fine) and software
1 LED
1 Jumper Wire


(Wiring Example Updated Below...)

I'm an Electrical Engineer of 20+ years and just discovered the Arduino platform a few months ago.  Needless to say I fell in love with it and am now hooked on projects.  For Christmas this year, I wanted to make some very heart-felt, one-of-a-kind gifts for my parents.  For my Mother, it was definately a 'one-of' clock design.  I was not concerned with keeping up with daylight savings time or leap years - simply accurately keep the day of week and time.  

How to generate the clock pulses in a unique but accurate manner though?  Sure I could use a fancy embedded clock IC or the common 32,768 crystal oscillator, but I wanted something different than the rest.  I started using a 555 timer to output a steady 100Hz square wave.  This worked pretty well but I was losing about 1 second per hour.  No problem - I just wrote an algorithm to correct the missing second in software.  I was happy.  Then I discovered that although the Arduino's internal timer was not totally reliable for time keeping, the analog PWM outputs did have a very steady square wave of 490Hz.  The duty cycle is determined by the value written to the analog pin.  (i.e. - 0 is zero volts, 127 is a 50% duty cycle, 255 is a logic high/5V).

I decided to try the PWM analog output wired directly to the interrupt pin  2 and it worked great!  Plus, it kept up perfectly with my computer's real time clock to the second without need for software compensation.  I've been running it for days now and it continues to perform just as I had hoped....all with one wire and some code.

The finished gift will have Eagle CAD custom PCB's for the power supply and logic, housed in a plexiglass enclosure.  The entire theme is ice blue LED lighting to simulate an analog clock.  While the enclosure has a white on blue LCD displaying the day, time, and room temperature, a serial cable connects from the project box to the actual clock.  Using a 12 bit decade counter, a servo, and lots of blue LED's I am lighting the appropriate hour segments on a custom-designed analog clock face printed on plexiglass.  The servo is mounted in the center of the clock face and has an armature attached with an LED mounted to light up the minutes behind the glass.  (each minute the servo turns 6 degrees, lighting up the appropriate minute).  I hope to have it finished soon and will make a video of the final product....I hope she loves it !!

Simple Arduino wiring diagram and demo code to make your own clock using this method.  Also a link to Circuit Lab demonstrating how to use the 555 timer @ 100Hz method if you so choose.

Code and links below...

555 Timer Oscillator Circuit (if you wish to try this method)
https://www.circuitlab.com/circuit/b575r9/555-100hz-oscillator/

Clock Demo Code:


/*  Simple internal clock demo: by Joseph Unik aka Relic1974
    Uses analog PWM output of 490Hz with a 50% duty cycle to
    keep very accurate time ;).  Connect an LED to pin 13 to
    watch seconds blink.  Connect a jumper from Analog pin 0
    to Digital Pin 2 (interrupt 0). Minutes output to serial
    monitor.  http://www.planetxresearch.com 'Arduino' logo
    for more projects and tricks...


    (Feel free to use this code to expand into a fully-functional
    clock or other project under Creative Commons ;)
*/

int clockInt = 0;            // digital pin 2 is now interrupt 0
int masterClock = 0;         // counts rising edge clock signals
int seconds = 0;             // variable
int minutes = 0;             // variable
int ledPin = 13;

void setup()
{
  attachInterrupt(clockInt, clockCounter, RISING);
      //  clockInt is our interrupt, clockCounter function is called when
      //  invoked on a RISING clock edge
  analogReference(DEFAULT);
  pinMode(ledPin, OUTPUT);
  Serial.begin(57600);
  analogWrite(0, 127);   // this starts our PWM 'clock' with a 50% duty cycle
}

void clockCounter()      // called by interrupt
{
  masterClock ++;        // with each clock rise add 1 to masterclock count
  if(masterClock == 489) // 490Hz reached     
  {                         
    seconds ++;          // after one 490Hz cycle add 1 second ;)
    masterClock = 0;     // Reset after 1 second is reached
    tone(13, 100, 500);  // using tone to pulse LED without delay call ;)
   }
  return;
}

void loop()
{
  if(seconds == 60)      // NOW GETTING IN TO REAL TIME KEEPING
  {
    minutes ++;          // increment minutes by 1
    seconds = 0;         // reset the seconds variable
    Serial.print("Minutes = ");
    Serial.println(minutes);
  }
}

Demo of my project in the works here