Using the 555 timer as an external clock for the Arduino

by Jeff Email

The Need for an External Clock

[Update 12/30/09: I have since found out that the Arduino has hardware timers built in. They seem to be hidden away in the API and I didn't see them when I started, but I will write a little sample with them sometime soon. In the mean time, I think there are still reasons why this is a valid approach in some cases -- plus it's got a simple introduction to interrupt handling, and the 555 timer is still a super useful IC, so hopefully you'll find something useful here.]

Often when I’m programming the Arduino, I can be a bit sloppy about time handling. I’ll throw in a delay(1000) without really thinking about it. And, for the most part, that works just fine. The delay() is just to “slow things down a bit”, and I could just easily have written delay(1111) and not really noticed anything different.

There are times, though, when precision counts.

Say you’re timing something against a video recorded at 30 frames a second – even small inaccuracies can add up and pretty soon your timing is off by several frames. Or perhaps you’re recording data from an experiment and you want to record the results every 1/100 seconds – inaccuracies can skew your results. Or if you're controlling the motion of a device, inaccuracies in timing can cause your expected location to be off.

The key here is an ‘external clock’. Rather than have the Arduino keep track of when to perform the next task, you have an outside signal that says “Now!” and fires an interrupt which the Arduino responds to. If your source fires every 100 milliseconds, then 10 times a second, the Arduino will receive an interrupt which will stop any processing currently happening and immediately execute the interrupt handler. For every tick of the clock, the interrupt handler will execute.

In my case, I was looking to build a synthesizer of sorts and wanted to ensure that I would have a 8000 Hz sample rate, so I had to make sure that the Arduino would do my bidding exactly every 125 microseconds. It turns out I was maybe over-optimistic about the what I could ask of the little guy, 125 milliseconds didn’t leave much time for me to do anything between samples. But I think that if you were in the 1/500th second range, this technique would work very well.

Follow up:

Building your clock – The hardware

At high frequencies you might use a crystal oscillator for this sort of thing, but down in the range we’re talking about, I like to go with the good ole’ 555 Timer (Radio Shack Part #276-1723).

There are over a billion of these little guys made every year! Not surprising since they have a ton of uses. For this, we configure the 555 in ‘astable’ mode, as an oscillator. It will flip back and forth between ON and OFF at a given rate creating a square wave.

The circuit diagram to accomplish this is pretty simple, featuring the 555, and then a couple of resistors & capacitors that define the actual frequency of the oscillation. I have taken some liberties with the diagram below – pay close attention to the pin numbers, I changed them to make the circuit easier to read.

In reality, when you build it out, you’ll end up with jumpers and resistors over the chip, here’s a pic of my own setup:

You can see the yellow wire there, connected to the output pin. On the other end, it gets connected to the Arduino board on digital pin 2. For my sample here, I’m using R1=100 Kohm, R2 = 22 K, and C1 = 10 µF.
I said earlier that the frequency of the timer depends on those values, so what frequency would we get for these? Time to get the Arduino involved!

Testing your clock - The software
Start up the Arduino software and create a new file, then use this code:

// since this value is changed in an interrupt handler,
// mark it as volatile.
volatile long lasttime = 0;

void setup()
{
  // Go with faster than normal serial speed
  Serial.begin(115200);

  // Set Interrupt 0 (which is on digital pin 2) to call 'onTick'
  // when the signal rises.
  pinMode(2, INPUT);
  attachInterrupt( 0, onTick, RISING );
}


void loop()
{
  // Note that we're doing anything in the main loop,
  // everything happens in onTick
}


void onTick()
{
  // print out how many milliseconds occurred between the last
  // clock tick and this one.
  long thistime=millis();
  Serial.println(thistime-lasttime);
  lasttime = thistime;
}

Compile it, push it to the board and fire up your Serial Monitor – making sure to set the baud rate to 155200 as well. You should start to see the numbers scrolling by… for me it looks like 1002, 1003, 1003, 1003, 1002, 1004, 1003, 1003… That number is in milliseconds, so we’re getting a timing frequency of right about 1 Hz – one cycle per second.

You can calculate it using this formula:

time = 0.693 × (R1 + 2×R2) × C1

C1 is measured in Farads, R1 & R2 are in Ohms, so for my values:

time = 0.693 × (100000 + 2×22000) × 0.00001 = 0.99792 seconds (or 1.002 Hz)

If you want a different frequency, you would change the values of C1, R1 & R2. Changing the capicitor is the easiest to imagine -- if you go from a 10 µF capacitor to 1 µF, it will take 1/10 the time to charge, so your frequency will go up by a factor of 10.

Since you can end up with some weird resistor values, and you never know what you might have lying around, I've created a calculator which will take your desired frequency/time and give you some possible standard configurations. Hopefully you'll find it useful.

And that's it, using an external clock with the Arduino. I've read a bit about some crazy things you can do with the 555 Timer...I might digress about one of those next, we'll have to see how the next week or so goes because after that, it's off to PDC '09! Woo hoo!