Saltar al contenido principal

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.

JARU Timer Module

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ámetroTipoDescripción
msinteger/floatTiempo de espera en milisegundos
callbackstringNombre de la función a ejecutar
userDatainteger/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ámetroTipoDescripción
msinteger/floatIntervalo en milisegundos entre ejecuciones
callbackstringNombre de la función a ejecutar
userDatainteger/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ámetroTipoDescripción
idintegerID 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ámetroTipoDescripción
idintegerID del timer que disparó el callback
periodicbooltrue si es un timer periódico, false si es de un solo disparo
userDataintegerValor 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
Límite de timers

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.

Tiempo de ejecución del callback

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.

Timers de un solo disparo

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

PlataformaSoporteNotas
ESP32Usa esp_timer con precisión de microsegundos
Windows (SDL2)Usa Timer Queue de Windows
Emscripten (Web)🔶Pendiente de implementación