This page can be quickly reached from the link: http://www.gammon.com.au/timers
The Atmega328 (as on the Arduino Uno) has three timers/counters on-board the chip.
Timer 0 is set up by the init() function (which is automatically called by the code generated by the IDE, before setup() is called). This is used to count approximately every millisecond. This provides you with the figure that the millis() function returns.
You can use these timers easily enough by using the analogWrite function - that just generates a PWM (pulse width modulated) output on the various pins that the timer hardware supports.
But for a more in-depth analysis, let's look at using the timers/counters in our own way. :)
The example code below provides a "frequency counter" which counts the number of events which cause a rising edge on digital pin D5 during a specified interval.
For example, if you put a 5 kHz signal on pin D5, and time it for one second, the count will be 5000. You could also time it for 1/10 of a second (giving you a count of 500) and then multiply the result by 10, again giving you a figure of 5 kHz.
A longer timing period will give higher accuracy, and also average out any small variations during the sample time. However, of course, a longer timing period takes longer to execute.
Counter 1 - used to count pulses
In the code below Timer 1 is configured to count the number of times that a leading edge (rising pulse) is detected on D5. Each event increments the internal counter in the timer. When the 16-bit timer overflows an overflow interrupt is executed which counts the number of overflows.
When the time is up, the number of counts is the current counter contents of timer 1, plus the number of overflows multiplied by 65536.
Timer 2 - used to work out a timing interval
The counts are meaningless unless we know over what interval they occurred, which is what we use Timer 2 for. It is set up to take the internal clock (normally 16 MHz on a Uno), and "pre-scale" it by dividing it by 128. The pre-scaled clock will then "tick" every 8 microseconds (since the clock itself runs with a period of 1/16000000 or 62.5 ns).
So we configure Timer 2 to count up to 125 and then generate an interrupt. This interrupt gives us a chance to see if our counting period is up. Since 8 µs times 125 gives 1000 µs, that means we get interrupted exactly every 1 ms.
Note that Timer 2 has a higher priority than Timers 0 and 1, so neither the millis() timer, nor the Timer 1 counter will take precedence over this interrupt.
In the Timer 2 interrupt we see if time is up (basically whether the required number of milliseconds is up). Is not, we just keep going. If time is up, we turn off both Timers 1 and 2, calculate the total count (by multiplying the number of overflows by 65536 and adding in the remaining counts) and exit.
Frequency Counter sketch for Atmega328
// Timer and Counter example
// Author: Nick Gammon
// Date: 17th January 2012
// Input: Pin D5
// these are checked for in the main program
volatile unsigned long timerCounts;
volatile boolean counterReady;
// internal to counting routine
unsigned long overflowCount;
unsigned int timerTicks;
unsigned int timerPeriod;
void startCounting (unsigned int ms)
{
counterReady = false; // time not up yet
timerPeriod = ms; // how many 1 ms counts to do
timerTicks = 0; // reset interrupt counter
overflowCount = 0; // no overflows yet
// reset Timer 1 and Timer 2
TCCR1A = 0;
TCCR1B = 0;
TCCR2A = 0;
TCCR2B = 0;
// Timer 1 - counts events on pin D5
TIMSK1 = bit (TOIE1); // interrupt on Timer 1 overflow
// Timer 2 - gives us our 1 ms counting interval
// 16 MHz clock (62.5 ns per tick) - prescaled by 128
// counter increments every 8 µs.
// So we count 125 of them, giving exactly 1000 µs (1 ms)
TCCR2A = bit (WGM21) ; // CTC mode
OCR2A = 124; // count up to 125 (zero relative!!!!)
// Timer 2 - interrupt on match (ie. every 1 ms)
TIMSK2 = bit (OCIE2A); // enable Timer2 Interrupt
TCNT1 = 0; // Both counters to zero
TCNT2 = 0;
// Reset prescalers
GTCCR = bit (PSRASY); // reset prescaler now
// start Timer 2
TCCR2B = bit (CS20) | bit (CS22) ; // prescaler of 128
// start Timer 1
// External clock source on T1 pin (D5). Clock on rising edge.
TCCR1B = bit (CS10) | bit (CS11) | bit (CS12);
} // end of startCounting
ISR (TIMER1_OVF_vect)
{
++overflowCount; // count number of Counter1 overflows
} // end of TIMER1_OVF_vect
//******************************************************************
// Timer2 Interrupt Service is invoked by hardware Timer 2 every 1 ms = 1000 Hz
// 16Mhz / 128 / 125 = 1000 Hz
ISR (TIMER2_COMPA_vect)
{
// grab counter value before it changes any more
unsigned int timer1CounterValue;
timer1CounterValue = TCNT1; // see datasheet, page 117 (accessing 16-bit registers)
unsigned long overflowCopy = overflowCount;
// see if we have reached timing period
if (++timerTicks < timerPeriod)
return; // not yet
// if just missed an overflow
if ((TIFR1 & bit (TOV1)) && timer1CounterValue < 256)
overflowCopy++;
// end of gate time, measurement ready
TCCR1A = 0; // stop timer 1
TCCR1B = 0;
TCCR2A = 0; // stop timer 2
TCCR2B = 0;
TIMSK1 = 0; // disable Timer1 Interrupt
TIMSK2 = 0; // disable Timer2 Interrupt
// calculate total count
timerCounts = (overflowCopy << 16) + timer1CounterValue; // each overflow is 65536 more
counterReady = true; // set global flag for end count period
} // end of TIMER2_COMPA_vect
void setup ()
{
Serial.begin(115200);
Serial.println("Frequency Counter");
} // end of setup
void loop ()
{
// stop Timer 0 interrupts from throwing the count out
byte oldTCCR0A = TCCR0A;
byte oldTCCR0B = TCCR0B;
TCCR0A = 0; // stop timer 0
TCCR0B = 0;
startCounting (500); // how many ms to count for
while (!counterReady)
{ } // loop until count over
// adjust counts by counting interval to give frequency in Hz
float frq = (timerCounts * 1000.0) / timerPeriod;
Serial.print ("Frequency: ");
Serial.print ((unsigned long) frq);
Serial.println (" Hz.");
// restart timer 0
TCCR0A = oldTCCR0A;
TCCR0B = oldTCCR0B;
// let serial stuff finish
delay(200);
} // end of loop
[EDIT] Amended 25 April 2012 to make more accurate by allowing for overflows in Timer 1 during the interrupt service routine, and by stopping Timer 0.
[EDIT] Amended 28 June 2013 to fix bug where I was testing for TIFR1 & TOV1 rather than TIFR1 & _BV (TOV1).
[EDIT] Amended 31 August 2013 to change _BV() to bit().
Accuracy
Pumping in a 5 MHz signal from a signal generator, the sketch outputs around 5001204 (give or take a couple of counts). The error (assuming the signal generator is accurate) is therefore 1204/500000 or about 0.02% error.
Trying with a 5 kHz signal, the sketch outputs around 5000 to 5002, an error of 2/5000 or 0.04% error.
So, pretty accurate. Tests on my Arduino clock showed that the clock itself was around 0.2% wrong, so we can't really expect better accuracy than that.
Range
I measured up to 8 MHz with about 0.5% error. At 5 MHz the error was down to 0.02% as described above. At the other end of the scale, it measured down to 10 Hz without any obvious error. Below that errors crept in, particularly as the sample period is only 500 ms.
More examples of timers and interrupts here:
http://gammon.com.au/interrupts
Frequency Counter sketch for Atmega2560
// Timer and Counter example for Mega2560
// Author: Nick Gammon
// Date: 24th April 2012
// input on pin D47 (T5)
// these are checked for in the main program
volatile unsigned long timerCounts;
volatile boolean counterReady;
// internal to counting routine
unsigned long overflowCount;
unsigned int timerTicks;
unsigned int timerPeriod;
void startCounting (unsigned int ms)
{
counterReady = false; // time not up yet
timerPeriod = ms; // how many 1 ms counts to do
timerTicks = 0; // reset interrupt counter
overflowCount = 0; // no overflows yet
// reset Timer 2 and Timer 5
TCCR2A = 0;
TCCR2B = 0;
TCCR5A = 0;
TCCR5B = 0;
// Timer 5 - counts events on pin D47
TIMSK5 = bit (TOIE1); // interrupt on Timer 5 overflow
// Timer 2 - gives us our 1 ms counting interval
// 16 MHz clock (62.5 ns per tick) - prescaled by 128
// counter increments every 8 µs.
// So we count 125 of them, giving exactly 1000 µs (1 ms)
TCCR2A = bit (WGM21) ; // CTC mode
OCR2A = 124; // count up to 125 (zero relative!!!!)
// Timer 2 - interrupt on match (ie. every 1 ms)
TIMSK2 = bit (OCIE2A); // enable Timer2 Interrupt
TCNT2 = 0;
TCNT5 = 0; // Both counters to zero
// Reset prescalers
GTCCR = bit (PSRASY); // reset prescaler now
// start Timer 2
TCCR2B = bit (CS20) | bit (CS22) ; // prescaler of 128
// start Timer 5
// External clock source on T4 pin (D47). Clock on rising edge.
TCCR5B = bit (CS50) | bit (CS51) | bit (CS52);
} // end of startCounting
ISR (TIMER5_OVF_vect)
{
++overflowCount; // count number of Counter1 overflows
} // end of TIMER5_OVF_vect
//******************************************************************
// Timer2 Interrupt Service is invoked by hardware Timer 2 every 1 ms = 1000 Hz
// 16Mhz / 128 / 125 = 1000 Hz
ISR (TIMER2_COMPA_vect)
{
// grab counter value before it changes any more
unsigned int timer5CounterValue;
timer5CounterValue = TCNT5; // see datasheet, (accessing 16-bit registers)
// see if we have reached timing period
if (++timerTicks < timerPeriod)
return; // not yet
// if just missed an overflow
if (TIFR5 & TOV5)
overflowCount++;
// end of gate time, measurement ready
TCCR5A = 0; // stop timer 5
TCCR5B = 0;
TCCR2A = 0; // stop timer 2
TCCR2B = 0;
TIMSK2 = 0; // disable Timer2 Interrupt
TIMSK5 = 0; // disable Timer5 Interrupt
// calculate total count
timerCounts = (overflowCount << 16) + timer5CounterValue; // each overflow is 65536 more
counterReady = true; // set global flag for end count period
} // end of TIMER2_COMPA_vect
void setup () {
Serial.begin(115200);
Serial.println("Frequency Counter");
} // end of setup
void loop () {
// stop Timer 0 interrupts from throwing the count out
byte oldTCCR0A = TCCR0A;
byte oldTCCR0B = TCCR0B;
TCCR0A = 0; // stop timer 0
TCCR0B = 0;
startCounting (500); // how many ms to count for
while (!counterReady)
{ } // loop until count over
// adjust counts by counting interval to give frequency in Hz
float frq = (timerCounts * 1000.0) / timerPeriod;
// restart timer 0
TCCR0A = oldTCCR0A;
TCCR0B = oldTCCR0B;
Serial.print ("Frequency: ");
Serial.println ((unsigned long) frq);
// let serial stuff finish
delay(200);
} // end of loop
[EDIT] Amended 25 April 2012 to make more accurate by allowing for overflows in Timer 1 during the interrupt service routine, and by stopping Timer 0.
[EDIT] Amended 4 September 2013 to change _BV() to bit().
Timer ready reckoner
To help work out what prescaler/count you need for setting up timers, consult this table:

All these figures assume a 16 MHz clock, and thus a clock period of 62.5 ns.
The "count" column is the number of counts you use for the Output Compare Register (eg. for OCR2A, OCR2B and so on) when counting up to a "compare" value. The count of 256 can also be used to see how long until Timer 0 and Timer 2 overflow (Timer 1 is a 16-bit timer and overflows after 65536 counts).
Remember that the count registers are zero-relative, so to get 100 counts, you actually put 99 into the register.
So for example, with a prescaler of 64, Timer 0 will overflow every 1.024 ms (which in fact it normally does for use by the millis() function).
To set some other frequency choose a prescaler which appears reasonably close, and then apply this formula:
count = frequency_from_table / target_frequency
For example, if we wanted to flash an LED at 50 Hz using a prescaler of 1024:
count = 15625 / 50 = 312.5
Since 312.5 is greater than 256 we could only do that with Timer 1 which is a 16-bit timer. Note that 312.5 has a decimal place, and therefore the flash would not occur every 50 Hz (as it would be rounded down). You could choose a prescaler of 256 instead:
count = 62500 / 50 = 1250
Now, we have a whole number, so the frequency would be accurate.
Bear in mind, too, that if you are using the hardware to toggle a pin, it needs to get toggled at twice the target frequency (because 100 Hz is counting 100 times a complete cycle, not half a cycle).
Timer hardware input/output
The table below shows the relationship between various pins (with the Arduino pin number in brackets) and the respective timers.
For example, to count an external source with Timer 1, you connect that to Arduino pin D5 (pin 11 on the Atmega328).
Timer 0
input T0 pin 6 (D4)
output OC0A pin 12 (D6)
output OC0B pin 11 (D5)
Timer 1
input T1 pin 11 (D5)
output OC1A pin 15 (D9)
output OC1B pin 16 (D10)
Timer 2
output OC2A pin 17 (D11)
output OC2B pin 5 (D3)










