Introduction to RTOS Part 8 - Software Timer | Digi-Key Electronics
¿Cómo utilizar temporizadores en microcontroladores?
Introducción a los temporizadores
- Los temporizadores son herramientas útiles en la programación, permitiendo retrasar la ejecución de funciones o ejecutarlas periódicamente.
- En microcontroladores, tareas comunes como parpadear un LED o enviar pulsos a un servo motor requieren control preciso del tiempo.
Ejecución de funciones periódicas
- Para ejecutar una función de muestreo periódicamente, se puede crear una tarea separada que use
vtask delay, aunque esto implica un alto costo de recursos.
- Alternativamente, se puede usar
x task get tick countpara verificar el tiempo transcurrido y decidir cuándo ejecutar la función.
Limitaciones y alternativas
- La precisión del temporizador por defecto es de un milisegundo; para mayor precisión se necesitarían temporizadores de hardware, que son limitados y no portables.
- FreeRTOS ofrece temporizadores software que permiten llamar funciones arbitrarias al expirar, pero su precisión también está limitada al intervalo del tick timer.
Funcionamiento de los temporizadores en FreeRTOS
- Al incluir la biblioteca de temporizadores en FreeRTOS, se crea una tarea única llamada "timer service task" que gestiona los temporizadores.
- Esta tarea no corre continuamente; se activa cuando el tick timer alcanza uno de los tiempos programados.
Implementación y configuración
- Las funciones callback asociadas a los temporizadores deben ser rápidas y no bloquearse; evitar el uso de funciones como
delay.
- Se utilizan colas y API para enviar comandos a la tarea del servicio del temporizador sin bloquearse si la cola está llena.
Configuración específica para ESP32
- Para habilitar el soporte a temporizadores en ESP32 con Arduino, hay que ajustar el archivo
freertos config.hestableciendouse timersa 1.
- Se pueden modificar otros parámetros como prioridad del servicio del timer y longitud de la cola; por defecto son 1 (prioridad), 10 (longitud), y 2 KB (profundidad).
Funciones API disponibles
- FreeRTOS permite crear, eliminar, iniciar y detener timers. Existen funciones específicas para ISR que evitan bloqueos al enviar comandos desde rutinas interrumpidas.
Introducción a los temporizadores de software en FreeRTOS
Configuración inicial y creación de un temporizador de un solo disparo
- Se comenzará con un boceto en blanco utilizando FreeRTOS. Es necesario incluir
timers.hpara usar las funciones del API de temporizadores, aunque ya está incluido en el paquete de Arduino ESP32.
- Se creará un manejador para un temporizador de un solo disparo que llamará a una función arbitraria después de un período específico, ejecutándose solo una vez.
- La función callback del temporizador no debe devolver nada y aceptará como parámetro el manejador del temporizador, lo que permite identificar cuál se ha llamado si hay múltiples temporizadores.
Creación y configuración del temporizador
- En la configuración (
setup), se configurará el puerto serie e imprimirá un mensaje de bienvenida. Luego se llamará axTimerCreate, asignando su valor devuelto al manejador.
- El primer parámetro es el nombre del temporizador; el segundo es la longitud en ticks (no menos de uno). Para milisegundos, se divide por la constante
portTICK_PERIOD_MS.
Parámetros adicionales y manejo de errores
- Se puede crear un ID único para el temporizador usando punteros. Por ahora, se establecerá este parámetro en cero y se convertirá a puntero vacío.
- Antes de continuar, es importante verificar que el manejador no sea nulo tras la creación del temporizador. Si falla, se imprimirá un mensaje simple.
Ejecución y comportamiento del temporizador
- Después de iniciar los temporizadores con
xTimerStart, se especifica cuánto tiempo esperar si la cola está llena usandoportMAX_DELAY.
- Al eliminar las tareas
setupyloop, se demostrará que los temporizadores funcionan sin otras tareas corriendo.
Comparación entre diferentes tipos de temporizadores
- Se añadirá otro manejador global para comparar con el anterior. Este será un timer auto-reload que ejecuta su callback repetidamente tras expirar.
- Se cambiarán parámetros como el periodo a 1000 ms y habilitará auto-reload estableciendo su valor a
pdTRUE.
Identificación única y ejecución simultánea
- En la función callback, se identificará qué timer llamó al callback usando
pvTimerGetTimerID. Esto permitirá diferenciar entre ambos timers durante su ejecución.
- Al ejecutar ambos timers en ESP32, primero expirará el auto-reload seguido por el timer de un solo disparo. El primero seguirá ejecutándose cada segundo mientras que el segundo parará.
Desafío práctico: Implementación realista
- Como desafío final, se propone implementar una funcionalidad donde una luz LED simule retroiluminación automática apagándose tras cinco segundos sin actividad.
- La tarea consistirá en encender la luz cuando haya entrada serial activa y utilizar un timer para apagarla después del tiempo establecido desde la última entrada.