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.