Language: EN

esp32-timers

How to use ESP32 timers

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.