esp32-timers

Cómo usar los timers del ESP32

Un Timer es un contador que puede medir el tiempo transcurrido en unidades de reloj del sistema. Permiten ejecutar funciones o interrupciones en momentos específicos o después de cierto tiempo transcurrido.

Estos dispositivos permiten medir intervalos de tiempo y ejecutar tareas en momentos precisos, lo que resulta especialmente útil en aplicaciones que requieren sincronización, control de eventos o ejecución de tareas periódicas.

Sin embargo es importante que no abuses de ellos, y usarlos únicamente en situaciones donde la precisión del tiempo es crucial.

El 99% de las tareas donde se usan un timer se podrían hacer con un soft timer (un timer por software), con un simple “blink sin delay”.

Ventajas y Aplicaciones de los Timers

Algunas aplicaciones donde sí te pondrías plantear de Timers en el ESP32 incluyen:

  • Generación de Señales: Generar señales de onda cuadrada, PWM (modulación por ancho de pulso) u otras señales periódicas.
  • Control de Actuadores: Activar y desactivar actuadores (como motores o relés) en intervalos muy muy precisos.
  • Medición de Tiempos: Medir la duración de eventos, como la velocidad de un objeto o el tiempo entre pulsos.
  • Comunicación Sincrónica: Coordinar comunicaciones en tiempo real entre dispositivos.

Uso de Timers en ESP32

El ESP32 ofrece varios Timers internos, que pueden ser utilizados para diversas aplicaciones. En función del modelo de ESP32 encontraremos 2 a 4 timers, pero el uso es idéntico en todos los modelos.

Para utilizar Timers en el ESP32 bajo el entorno de Arduino, se siguen pasos generales:

Inicialización del Timer

Primero, se debe inicializar el Timer deseado. Esto se hace utilizando la función timerBegin() que toma como argumentos el número del Timer (0, 1, 2, etc.), el divisor del reloj y si el Timer se reinicia después de alcanzar el valor de comparación.

Adjuntar la Interrupción

Se adjunta la función de manejo de interrupción al Timer usando timerAttachInterrupt(). Esta función establece cuál función será ejecutada cuando el Timer alcance el valor de comparación.

Configuración del Valor de Comparación

Con timerAlarmWrite() se establece el valor al que el Timer debe contar antes de generar una interrupción o ejecutar una acción.

Habilitar el Timer

Finalmente, se habilita el Timer usando timerAlarmEnable().

Ejemplo de código

A continuación se muestra un ejemplo de cómo utilizar un Timer en el ESP32

hw_timer_t *timer = NULL;

volatiel void has_expired = false;
void IRAM_ATTR timerInterrupcion() {
 has_expired = true;
}

void setup() {
  Serial.begin(9600);
  pinMode(LED_BUILTIN, OUTPUT);

  timer = timerBegin(0, 80, true); // Timer 0, divisor de reloj 80
  timerAttachInterrupt(timer, &timerInterrupcion, true); // Adjuntar la función de manejo de interrupción
  timerAlarmWrite(timer, 1000000, true); // Interrupción cada 1 segundo
  timerAlarmEnable(timer); // Habilitar la alarma
}

void loop() {
  if(has_expired)
  {
     // Tareas a realizar cuando se activa la interrupción del Timer
    digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN)); // Alternar el estado del LED
    has_expired = false; 
  }
  
}

En este ejemplo, se configura un Timer que genera una interrupción cada segundo. Cuando se activa la interrupción, la función timerInterrupcion() se ejecuta, alternando el estado del LED incorporado.