Módulo Timer
El módulo Timer permite crear temporizadores que ejecutan funciones callback en JARU después de un tiempo específico o de forma periódica. Es ideal para tareas programadas, animaciones, polling de sensores, o cualquier lógica que necesite ejecutarse en intervalos regulares.

Los timers funcionan de forma asíncrona mediante un sistema de interrupciones, lo que significa que tu código principal puede continuar ejecutándose mientras los timers operan en segundo plano.
Uso
use Timer
Funciones
after
La función Timer.after(ms, callback, [userData]) crea un timer de un solo disparo que ejecuta la función callback una vez transcurrido el tiempo especificado.
use Timer
func miCallback(id, periodic, data)
println("Timer disparado!")
println(" ID: ", id)
println(" Periódico: ", periodic)
println(" Datos: ", data)
end
// Ejecutar miCallback después de 2 segundos
var timerId = Timer.after(2000, "miCallback")
println("Timer creado con ID: ", timerId)
| Parámetro | Tipo | Descripción |
|---|---|---|
ms | integer/float | Tiempo de espera en milisegundos |
callback | string | Nombre de la función a ejecutar |
userData | integer/float | (Opcional) Valor personalizado que se pasa al callback |
Retorno
Devuelve el ID del timer (entero positivo) si se creó correctamente, o un error si no hay slots disponibles.
Ejemplo con userData
use Timer
func procesoRetrasado(id, periodic, codigo)
println("Procesando código: ", codigo)
// Hacer algo con el código...
end
// Pasar un código personalizado al callback
Timer.after(5000, "procesoRetrasado", 42)
every
La función Timer.every(ms, callback, [userData]) crea un timer periódico que ejecuta la función callback repetidamente en el intervalo especificado.
use Timer
var contador = 0
func tick(id, periodic, data)
contador = contador + 1
println("Tick #", contador)
// Detener después de 5 ticks
if (contador >= 5) then
Timer.clear(id)
println("Timer detenido")
end
end
// Ejecutar tick cada segundo
var timerId = Timer.every(1000, "tick")
println("Timer periódico creado con ID: ", timerId)
| Parámetro | Tipo | Descripción |
|---|---|---|
ms | integer/float | Intervalo en milisegundos entre ejecuciones |
callback | string | Nombre de la función a ejecutar |
userData | integer/float | (Opcional) Valor personalizado que se pasa al callback |
Retorno
Devuelve el ID del timer (entero positivo) si se creó correctamente, o un error si no hay slots disponibles.
Ejemplo: Sensor polling
use Timer
use GPIO
func leerSensor(id, periodic, pin)
var valor = GPIO.read(pin)
println("Sensor (pin ", pin, "): ", valor)
end
// Leer el sensor en el pin 34 cada 500ms
Timer.every(500, "leerSensor", 34)
clear
La función Timer.clear(id) detiene y elimina un timer activo.
use Timer
func miCallback(id, periodic, data)
println("Esto solo se ejecutará una vez")
Timer.clear(id) // Se auto-cancela
end
var timerId = Timer.every(1000, "miCallback")
// También puedes cancelarlo desde fuera
// Timer.clear(timerId)
| Parámetro | Tipo | Descripción |
|---|---|---|
id | integer | ID del timer a eliminar |
Retorno
Devuelve true siempre (la operación es silenciosa si el ID no existe).
Función callback
Todas las funciones callback de timer reciben tres parámetros:
| Parámetro | Tipo | Descripción |
|---|---|---|
id | integer | ID del timer que disparó el callback |
periodic | bool | true si es un timer periódico, false si es de un solo disparo |
userData | integer | Valor personalizado pasado al crear el timer (0 por defecto) |
func miCallback(id, periodic, userData)
// id: identificador único del timer
// periodic: true = Timer.every(), false = Timer.after()
// userData: valor pasado como tercer parámetro
end
Ejemplo completo: Sistema de luces
use Timer
use GPIO
// Configuración de pines LED
const LED_ROJO = 2
const LED_VERDE = 4
const LED_AZUL = 5
var estado = 0
func inicializar()
GPIO.mode(LED_ROJO, GPIO.OUTPUT)
GPIO.mode(LED_VERDE, GPIO.OUTPUT)
GPIO.mode(LED_AZUL, GPIO.OUTPUT)
end
func cicloLuces(id, periodic, data)
// Apagar todos
GPIO.write(LED_ROJO, 0)
GPIO.write(LED_VERDE, 0)
GPIO.write(LED_AZUL, 0)
// Encender el siguiente
if (estado == 0) then
GPIO.write(LED_ROJO, 1)
elif (estado == 1) then
GPIO.write(LED_VERDE, 1)
else
GPIO.write(LED_AZUL, 1)
end
estado = (estado + 1) % 3
end
func apagarTodo(id, periodic, data)
GPIO.write(LED_ROJO, 0)
GPIO.write(LED_VERDE, 0)
GPIO.write(LED_AZUL, 0)
println("Sistema apagado")
end
// Programa principal
inicializar()
// Ciclo de luces cada 500ms
var cicloId = Timer.every(500, "cicloLuces")
// Apagar todo después de 10 segundos
Timer.after(10000, "apagarTodo")
Ejemplo: Debounce de botón
use Timer
use GPIO
use Input
const BOTON = 0
var debounceActivo = false
var timerId = -1
func onDebounceComplete(id, periodic, data)
debounceActivo = false
end
func procesarBoton()
if (debounceActivo) then
return // Ignorar durante debounce
end
println("¡Botón presionado!")
debounceActivo = true
// Esperar 200ms antes de aceptar otra pulsación
timerId = Timer.after(200, "onDebounceComplete")
end
// En tu loop principal
func loop()
if (Input.pressed(BOTON)) then
procesarBoton()
end
end
El sistema soporta hasta 32 timers simultáneos. Si necesitas más, considera reutilizar timers existentes o usar un único timer periódico que gestione múltiples tareas.
Los callbacks de timer deben ser rápidos. Si un callback tarda demasiado en ejecutarse, puede afectar la precisión de otros timers y el rendimiento general del sistema.
Los timers creados con Timer.after() se eliminan automáticamente después de ejecutar su callback. No necesitas llamar a Timer.clear() para ellos.
Plataformas soportadas
| Plataforma | Soporte | Notas |
|---|---|---|
| ESP32 | ✅ | Usa esp_timer con precisión de microsegundos |
| Windows (SDL2) | ✅ | Usa Timer Queue de Windows |
| Emscripten (Web) | 🔶 | Pendiente de implementación |