Timers in Arduino

Every microcontroller has one or more timers that help the users perform tasks at precise intervals. Arduino Uno, for example, has 3 timers: Timer0, Timer1 and Timer2. Other boards may have the same or different number of timers, which you can find from the datasheet of that board/ microcontroller. 

What are timers?

Timers are essentially counters. Let me give you a simple example. Say you want to trigger a task every 5 seconds. Now, if you have a counter which can count from 0 to 255, then if you somehow adjust the rate of counting such that it finishes counting exactly in 5 seconds, then you can get an accurate interval of 5 seconds. Now, you can do this in two ways −

  • You adjust the speed at which it counts (1 count every 19 milliseconds, or a counting frequency of 51.2 Hz will give you an interval of 5 seconds).
  • Alternatively, you can adjust the stop point. So instead of counting from 0 to 255, you can make the timer count from 0 to 100, or from 155 to 255, and then the required frequency will be 20 Hz (which is a much nicer number than 51.2).

However, all these settings require several changes to the internal registers of Arduino. Luckily, libraries have been built that take care of all these settings themselves. All we need to do is define the time period for which we want the timer to run. A popular example is the TimerOne library: https://github.com/PaulStoffregen/TimerOne

We’ve covered the usage of TimerOne library in another post on Timer Interrupts in Arduino.

Why use timers when you have the delay function?

This is a question you may be having right now. If you want some task to be performed every 1 second, then simply add a delay of 1 second and run the task in a loop. The problem is that this doesn’t take into consideration the time taken for the task to execute.

Suppose the task you are executing takes 100ms of execution time. Thus, there will be a gap of (100ms execution time + 1 second delay = 1.1 seconds) between two consecutive instances of the task. This will mess up the frequency. The timer keeps running in the background. After counting from 0 to 255, it will again start counting from 0, while your task is running. This way, you can be sure that you are having the correct interval between two instances of the task, irrespective of the execution time of the task.

The only thing you need to ensure is that the function which is called when the interrupt is triggered doesn’t have an execution time higher than the interval period. In general, interrupt functions are supposed to return as soon as possible.