Saltar al contenido principal

Módulo Power

El módulo Power proporciona funciones para gestionar el consumo de energía del ESP32, permitiendo implementar modos de bajo consumo (light sleep) y configurar las fuentes de despertar.

JARU Power Module

Este módulo es especialmente útil para aplicaciones IoT alimentadas por batería o energía solar, donde minimizar el consumo energético es crucial para prolongar la autonomía del dispositivo.

Uso

use Power

Para utilizar el módulo Power, debes importarlo en tu programa JARU. Luego, configuras una o más fuentes de despertar y ejecutas sleep() para que el ESP32 entre en modo de bajo consumo.

Funciones

wakeOnTimer

La función wakeOnTimer(microsegundos) configura un temporizador como fuente de despertar. El ESP32 se despertará automáticamente después del tiempo especificado.

use Power

// Despertar después de 5 segundos (5,000,000 microsegundos)
Power.wakeOnTimer(5000000)
Power.sleep()

println("¡Despertado por el timer!")

Parámetros:

  • microsegundos: Tiempo en microsegundos antes de despertar (entero o flotante)

Retorna: true si la configuración fue exitosa, false en caso contrario.

Consejo

Para tiempos en segundos, multiplica por 1,000,000. Por ejemplo, 30 segundos = 30,000,000 microsegundos.

wakeOnPin

La función wakeOnPin(pin, nivel) configura un pin RTC como fuente de despertar. El ESP32 se despertará cuando el pin alcance el nivel especificado.

use Power

// Despertar cuando el pin 33 pase a HIGH
Power.wakeOnPin(33, HIGH)
Power.sleep()

println("¡Despertado por el pin!")

Parámetros:

  • pin: Número de pin GPIO (debe ser un pin RTC válido)
  • nivel: Nivel que activa el despertar (HIGH o LOW)

Retorna: true si la configuración fue exitosa, false en caso contrario.

Pines RTC válidos

Solo ciertos pines GPIO pueden usarse como fuente de despertar RTC (ext0). En el ESP32 estándar, los pines RTC válidos son: 0, 2, 4, 12, 13, 14, 15, 25, 26, 27, 32, 33, 34, 35, 36, 37, 38, 39.

wakeOnGPIO

La función wakeOnGPIO() habilita el despertar por GPIO general. Esta opción es menos eficiente energéticamente que wakeOnPin(), pero permite usar más pines.

use Power
use GPIO

// Primero configurar el pin con gpio_wakeup_enable
GPIO.pinmode(4, GPIO.INPUT)
// (Requiere configuración adicional a nivel de sistema)

Power.wakeOnGPIO()
Power.sleep()

Retorna: true si la configuración fue exitosa, false en caso contrario.

Nota

Esta función requiere que los GPIOs hayan sido configurados previamente con gpio_wakeup_enable() a nivel del sistema. Es más común usar wakeOnPin() para casos simples.

sleep

La función sleep() ejecuta el modo light sleep del ESP32. El dispositivo entrará en un estado de bajo consumo hasta que se active una de las fuentes de despertar configuradas.

use Power

// Configurar despertar por timer
Power.wakeOnTimer(10000000) // 10 segundos

println("Entrando en modo sleep...")
Power.sleep()
println("¡Despertado!")

Retorna: true si el sleep se ejecutó correctamente, false en caso contrario.

Diferencia entre Light Sleep y Deep Sleep

El light sleep mantiene el estado de la CPU y la RAM, por lo que el programa continúa exactamente donde se quedó. El deep sleep reinicia completamente el programa. El módulo Power implementa light sleep.

wakeReason

La función wakeReason() devuelve la causa del último despertar. Esto permite al programa tomar diferentes acciones dependiendo de qué activó el despertar.

use Power

// Verificar la causa del despertar
var razon = Power.wakeReason()

if (razon == Power.WAKE_TIMER) then
println("Despertado por timer")
elif (razon == Power.WAKE_EXT0) then
println("Despertado por pin RTC")
elif (razon == Power.WAKE_GPIO) then
println("Despertado por GPIO")
else
println("Razón desconocida o primer arranque")
end

Retorna: Un valor entero que corresponde a una de las constantes de causa de despertar.

Constantes

WAKE_UNDEFINED

Indica que la causa del despertar no está definida o es el primer arranque del dispositivo.

if (Power.wakeReason() == Power.WAKE_UNDEFINED) then
println("Primer arranque o causa desconocida")
end

Valor: 0

WAKE_TIMER

Indica que el despertar fue causado por el temporizador configurado con wakeOnTimer().

if (Power.wakeReason() == Power.WAKE_TIMER) then
println("Timer expirado")
end

Valor: 2

WAKE_EXT0

Indica que el despertar fue causado por una fuente externa RTC (ext0), configurada con wakeOnPin().

if (Power.wakeReason() == Power.WAKE_EXT0) then
println("Pin RTC activado")
end

Valor: 3

WAKE_EXT1

Indica que el despertar fue causado por una fuente externa RTC (ext1). Esta opción permite múltiples pines simultáneos.

if (Power.wakeReason() == Power.WAKE_EXT1) then
println("Múltiples pines RTC activados")
end

Valor: 4

WAKE_GPIO

Indica que el despertar fue causado por un GPIO configurado con wakeOnGPIO().

if (Power.wakeReason() == Power.WAKE_GPIO) then
println("GPIO activado")
end

Valor: 6

WAKE_UART

Indica que el despertar fue causado por actividad en el puerto UART.

if (Power.wakeReason() == Power.WAKE_UART) then
println("Actividad UART detectada")
end

Valor: 7

Ejemplo completo: Sensor de temperatura con ahorro de energía

use Power
use GPIO
use Display

// Configuración inicial
Display.open(320, 240)
var draw = Display.draw

// Pin del sensor (simulado)
GPIO.pinmode(34, GPIO.INPUT)

// Intervalo de lectura: 30 segundos
var intervalo = 30000000

fun mostrarTemperatura(temp)
draw.cls(0x000000)
draw.setcolor(0x00FF00)
draw.text(60, 100, "Temperatura: " + temp + "°C")
Display.update()
end

fun leerSensor()
// Simular lectura de temperatura
return 20 + (GPIO.aread(34) / 100)
end

// Bucle principal
while (true)
// Verificar causa del despertar
var razon = Power.wakeReason()

if (razon == Power.WAKE_TIMER) then
println("Lectura programada")
elif (razon == Power.WAKE_EXT0) then
println("Lectura manual solicitada")
end

// Leer y mostrar temperatura
var temp = leerSensor()
mostrarTemperatura(temp)

// Esperar 2 segundos para ver la pantalla
pause(2000)

// Configurar fuentes de despertar
Power.wakeOnTimer(intervalo)
Power.wakeOnPin(33, HIGH) // Botón para lectura manual

// Apagar display y entrar en sleep
Display.backlight(0)
Power.sleep()

// Al despertar, encender display
Display.backlight(1)
end

Ejemplo: Detector de movimiento con notificación

use Power
use GPIO
use MQTT

// Pin del sensor PIR
var pinPIR = 27

// Configurar MQTT
MQTT.connect("mqtt://broker.local", "detector_01")

// Configurar despertar por sensor
Power.wakeOnPin(pinPIR, HIGH)

while (true)
// Verificar si despertamos por movimiento
if (Power.wakeReason() == Power.WAKE_EXT0) then
println("¡Movimiento detectado!")
MQTT.publish("casa/alarma", "movimiento")

// Esperar a que el sensor se estabilice
pause(5000)
end

// Volver a dormir
Power.wakeOnPin(pinPIR, HIGH)
Power.sleep()
end

Consideraciones de consumo

Consumo energético

El modo light sleep del ESP32 reduce el consumo de aproximadamente 240 mA (activo con WiFi) a aproximadamente 0.8 mA. Esto puede extender significativamente la vida útil de dispositivos alimentados por batería.

EstadoConsumo aproximado
Activo con WiFi~240 mA
Activo sin WiFi~20-30 mA
Light Sleep~0.8 mA
Deep Sleep~10 µA

Plataformas soportadas

PlataformaSoporte
ESP32✅ Completo
ESP32-S3✅ Completo
Windows (VM)⚠️ Simulado
RISC-V⚠️ Stubs
Simulación en Windows

En la máquina virtual de Windows, sleep() simula el comportamiento usando Sleep() del sistema. wakeReason() siempre devuelve WAKE_TIMER. Esto permite desarrollar y probar la lógica del programa antes de desplegarlo en hardware real.