A Timer is a counter that can measure elapsed time in system clock units. They allow functions or interrupts to be executed at specific moments or after a certain elapsed time.
These devices allow measuring time intervals and executing tasks at precise moments (which is especially useful in applications that require synchronization, event control, or periodic task execution).
However, it is important not to abuse them and to use them only in situations where time accuracy is crucial.
99% of tasks where a timer is used could be done with a soft timer (a software timer), with a simple “blink without delay”.
Advantages and Applications of Timers
Some applications where you might consider using Timers in the ESP32 include:
- Signal Generation: Generating square wave signals, PWM (pulse width modulation), or other periodic signals.
- Actuator Control: Activating and deactivating actuators (like motors or relays) at very precise intervals.
- Time Measurement: Measuring the duration of events, such as the speed of an object or the time between pulses.
- Synchronous Communication: Coordinating real-time communications between devices.
Using Timers in ESP32
The ESP32 offers several internal Timers that can be used for various applications. Depending on the ESP32 model, you will find 2 to 4 timers (but the usage is identical across all models).
To use Timers in the ESP32 under the Arduino environment, general steps are followed:
Timer Initialization
First, the desired Timer must be initialized. This is done using the timerBegin()
function, which takes the Timer number (0, 1, 2, etc.), the clock divisor, and whether the Timer resets after reaching the comparison value as arguments.
Attach the Interrupt
The interrupt handling function is attached to the Timer using timerAttachInterrupt()
. This function sets which function will be executed when the Timer reaches the comparison value.
Setting the Comparison Value
With timerAlarmWrite()
, the value to which the Timer must count before generating an interrupt or executing an action is set.
Enable the Timer
Finally, the Timer is enabled using timerAlarmEnable()
.
Example Code
Below is an example of how to use a Timer in the ESP32.
hw_timer_t *timer = NULL;
volatile void has_expired = false;
void IRAM_ATTR timerInterrupt() {
has_expired = true;
}
void setup() {
Serial.begin(9600);
pinMode(LED_BUILTIN, OUTPUT);
timer = timerBegin(0, 80, true); // Timer 0, clock divisor 80
timerAttachInterrupt(timer, &timerInterrupt, true); // Attach the interrupt handling function
timerAlarmWrite(timer, 1000000, true); // Interrupt every 1 second
timerAlarmEnable(timer); // Enable the alarm
}
void loop() {
if(has_expired)
{
// Tasks to perform when the Timer interrupt is activated
digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN)); // Toggle the state of the LED
has_expired = false;
}
}
In this example,
- A Timer is configured to generate an interrupt every second.
- When the interrupt is activated, the
timerInterrupt()
function is executed, toggling the state of the built-in LED.