Como usar os modos de suspensão e despertar do ESP32 no MicroPython

Cómo usar los modos de suspensión y activación de ESP32 en MicroPython

En un artículo anterior, cubrimos los modos de suspensión en ESP8266. ESP32 es otra placa de desarrollo Wi-Fi popular de Expressif Systems. Tiene más funciones que el ESP8266, pero también consume más energía. El consumo de energía del ESP32 puede alcanzar los 790 mA cuando Wi-Fi y Bluetooth están operativos, casi el doble que el del ESP8266, que alcanza un máximo de alrededor de 400 mA cuando está muy activo. Los componentes de la placa de ruptura también pueden agregar unos cientos de mA al consumo neto de energía.

Muchos desarrolladores de IoT prefieren utilizar el SoC rico en funciones en sus aplicaciones para que se requieran componentes externos mínimos en la placa. Es por eso que ESP32 es la opción ideal para muchos que eligen entre las dos tarjetas Expressif. Sin embargo, el consumo de energía del ESP32 puede representar un desafío para los dispositivos IoT que funcionan con baterías. Afortunadamente, ofrece varias opciones de administración de energía que ayudan.

A continuación, analizaremos los modos de alimentación y suspensión de ESP32, cubriendo las diferentes fuentes de activación y cómo ambas (las fuentes de suspensión y activación) se administran en el marco de MicroPython. El uso de los modos de suspensión adecuados del ESP32 en una aplicación de red alimentada por batería permite reducir el consumo de energía del sistema de cientos a unos pocos mA.

Modos de suspensión en ESP32
En el ESP32, hay cinco modos de energía disponibles: modo activo, suspensión de módem, suspensión suave, suspensión profunda y suspensión.

La suspensión activa es el modo predeterminado de ESP32 donde todos los periféricos, incluido Wi-Fi, módulo Bluetooth, CPU, reloj del sistema y RTC, están encendidos. El consumo típico de energía del SoC en este modo es de 240 mA, aunque puede aumentar a 790 mA cuando Wi-Fi y Bluetooth funcionan juntos en su máximo funcionamiento. Sin embargo, el consumo de energía en modo activo se puede ajustar configurando los ajustes de Wi-Fi.

Normalmente, cuando el módulo Wi-Fi transmite una salida entre 13 y 21dBm, el SoC consume entre 160 y 260 mAs. La potencia de salida es la suma de la potencia de transmisión de radio y la ganancia de la antena menos las pérdidas del cable.

Si la salida Wi-Fi se configura en 0dBm el consumo se reduce a 120 mA. Si la aplicación recibe datos solo a través de la red, el módulo Wi-Fi se puede configurar para recibir y escuchar. En esta configuración, el consumo de SoC en modo activo se reduce a 80~90 mA.

En el modo de suspensión del módem , la CPU, el reloj del sistema y el RTC están encendidos mientras que Wi-Fi, Bluetooth y la radio están apagados. El consumo en este modo es de 20 mA si la CPU funciona a alta velocidad y puede llegar a 3 mA si la CPU funciona a menor velocidad.

En este modo, el SoC utiliza el mecanismo de baliza DTIM para permanecer conectado a la red. El Wi-Fi se apaga entre los dos intervalos de baliza y se enciende antes de que llegue la siguiente. El tiempo de suspensión está determinado por el intervalo de baliza DTIM del enrutador Wi-Fi, que varía entre 100 y 1000 ms. El módulo Wi-Fi ESP32 se puede configurar para publicar un DTIM después de uno, tres o 10 intervalos de baliza. El valor DTIM predeterminado es tres.

En el modo Light Sleep , la CPU entra en un estado pendiente, lo que significa que se interrumpe al apagar los pulsos del reloj. Wi-Fi, Bluetooth y radio también están apagados. Wi-Fi permanece conectado a la red a través del mecanismo de baliza DTIM, donde periódicamente ingresa a los modos de suspensión y activación y se vuelve a conectar al módem.

El estado actual de la RAM se conserva antes de entrar en el modo de suspensión suave, que se reanuda cuando el chip se activa. El RTC es lo único que permanece encendido, necesario para mantener la fecha y hora. El consumo de energía del ESP32 SoC se reduce a 0,8 mA en este modo.

En el modo de suspensión profunda , el Wi-Fi, Bluetooth, la radio, el reloj del sistema, la CPU y la RAM están apagados. El único periférico conectado es el módulo RTC. Los datos de conexión Wi-Fi y Bluetooth se conservan en la memoria RTC ya que la memoria principal se borra cada vez que el SoC entra en suspensión profunda.

El coprocesador ULP también permanece activo y continúa agregando datos del sensor. Los datos del sensor se utilizan para despertar al chip de un sueño profundo. El consumo de energía del ESP32 en sueño profundo se reduce a 0,15 mA ~ 10 uA dependiendo de las actividades del coprocesador ULP.

En el modo de hibernación , todo está apagado, incluido Wi-Fi, Bluetooth, radio, reloj del sistema, CPU, coprocesador ULP y RTC. Sólo el temporizador RTC se mantiene lento. El consumo de energía del ESP32 se reduce a 2,5 uA en este modo.

De forma predeterminada, MicroPython solo admite modos de suspensión suave y profunda para los puertos compatibles. Estos son los únicos dos modos admitidos cuando se usa ESP32 en MicroPython.

Fuentes de activación ESP32
Hay cuatro fuentes de activación en el ESP32: temporizador, externo, pines táctiles y procesador ULP.

En la activación con temporizador, el RTC integrado se utiliza para despertar el SoC de un modo de suspensión profundo después de un período específico. Al despertarse externamente, el SoC entra en suspensión profunda indefinida hasta que el RTC GPIO detecta una señal. Hay dos "despertadores" externos en ESP32: ext0 y ext1.

En ext0, solo se utiliza un RTC GPIO para despertar el SoC de un sueño profundo. En ext1, se utilizan dos RTC GPIO para activar el chip. Al activar el pin táctil, uno de sus pines táctiles capacitivos despierta el chip de un sueño profundo. El coprocesador ULP se utiliza para activar el procesador principal a través de datos del sensor.

Consumo de energía ESP32 en diferentes modos de suspensión.

MicroPython admite la activación del ESP32 mediante un temporizador, señales externas y pines táctiles. Lo que no se admite es habilitar el coprocesador ULP. Hay funciones disponibles para acceder al coprocesador ULP, cargar un binario en el coprocesador ULP, ejecutar ULP desde un punto de entrada o activar el coprocesador ULP a intervalos periódicos. Estas funciones no están relacionadas con el despertar de los modos de sueño profundo o ligero. Esto significa que, aunque el coprocesador ULP se puede utilizar para habilitar ESP32, actualmente no es accesible en MicroPython.

Cómo se utiliza el sueño profundo en ESP32
Como se mencionó, el ESP32 es un chip que consume mucha energía. Por lo tanto, su modo de suspensión profunda es particularmente útil en aplicaciones de red que funcionan con baterías. Permite que el chip permanezca principalmente en un estado de sueño profundo o inactivo, despertándose periódicamente para realizar las tareas asignadas. Estas tareas incluyen tomar lecturas de un sensor, enviar datos del sensor a un servidor a través de un protocolo de IoT (como MQTT o CoAP) y/o tomar una acción en el sitio basada en lecturas de sensores o información recibida a través de la red.

Después de realizar una tarea mediante la aplicación del usuario, el chip vuelve al modo de suspensión profunda durante un período de tiempo específico. Incluso en modo de sueño profundo, los detalles de la red Wi-Fi y Bluetooth se almacenan en la memoria RTC. Esto permite que la tarjeta se vuelva a conectar fácilmente a la red cada vez que se despierta de un sueño profundo. El ciclo de sueño profundo, despertar, realizar tareas integradas/IoT y volver a dormir continúa indefinidamente.

Funciones relacionadas con la energía de MicroPython
El módulo de la máquina MicroPython proporciona las siguientes funciones para la administración de energía de las placas compatibles.

machine.lightsleep((time_ms)) : pone el puerto en modo de suspensión ligera. Si se especifica el tiempo en milisegundos como argumento, el modo de suspensión suave dura el tiempo especificado. La puerta se puede activar antes del tiempo programado, accionada por una fuente. Si no se pasan argumentos, el modo de suspensión suave dura indefinidamente o hasta que lo interrumpa una fuente de activación.

machine.deepsleep((time_ms)) : pone el puerto en modo de suspensión profunda. Si se especifica el tiempo en milisegundos como argumento, el modo de suspensión profunda dura el tiempo especificado. La puerta se puede activar antes del tiempo programado, accionada por una fuente. Si no se pasan argumentos, el sueño profundo dura indefinidamente, hasta que lo interrumpe una fuente de vigilia. Despertar del modo de suspensión profunda es lo mismo que un reinicio completo.

machine.wake_reason : Devuelve la fuente de activación. El valor devuelto puede ser machine.WLAN_WAKE, machine.PIN_WAKE o machine.RTC_WAKE, dependiendo de si la fuente de activación es WLAN, cambio de pin o RTC. Este método puede registrar un motivo de activación en una variable o imprimirlo en la consola.

La fuente de activación debe configurarse antes de solicitar un sueño ligero o profundo. Y solo se puede llamar a machine.wake_reason después de solicitar un sueño ligero o profundo.

machine.idle es otra función útil para la administración de energía del puerto. Cuando se llaman, los puertos de reloj (a la CPU) hacen que el puerto entre en modo de suspensión, donde el puerto se activa si recibe una interrupción.

Implementación de MicroPython de modos de suspensión en ESP32
MicroPython solo admite modos de suspensión ligera y profunda en ESP32. Se implementan mediante los métodos machine.lightsleep y machine.deepsleep. Hay un módulo específico de ESP32, esp32, en MicroPython que proporciona funciones adicionales para configurar la fuente de activación.

Estos métodos son:

esp32.wake_on_touch(awakening) : configura si el “toque” despertará o no el ESP32. Se necesita un argumento booleano. Si se establece en '1', el ESP32 se activa al tocarlo. Si se establece en '0', el ESP32 no se activará cuando se toque.

esp32.wake_on_ext0(pin, nivel) : configura el despertador externo, EXT0. Este despertar se puede aplicar a un pin, que debe ser RTC GPIO. Requiere dos argumentos: un objeto pin y un nivel. El nivel se puede configurar en esp32.WAKEUP_ALL_LOW o esp32.WAKEUP_ANY_HIGH.

esp32.wake_on_ext1(pins, nivel) : configura el despertador externo, EXT1. Este despertar se puede aplicar a varios pines, siempre que sean RTC GPIO. Requiere dos argumentos: una lista o tupla de objetos pin y un nivel. El nivel se puede configurar en esp32.WAKEUP_ALL_LOW o esp32.WAKEUP_ANY_HIGH.

esp32.gpio_deep_sleep_hold(enable) : determina si la configuración del pin GPIO no RTC se mantiene o no para los bloques retenidos durante el modo de suspensión profunda. Se necesita un argumento booleano, que se puede establecer en '0' o '1'.

Despierta con temporizador en ESP32
El despertador ESP32 no requiere ningún arreglo especial. Simplemente llame a los métodos de sueño profundo o sueño ligero con un tiempo específico en milisegundos para poner el ESP32 en sueño profundo o ligero.

Para este proyecto, usaremos el temporizador de activación del ESP32 para hacer parpadear un LED. Para hacer esto, conecte un LED al ESP32 en GPIO2 como se muestra en la imagen a continuación.

Este script MicroPython pone el ESP8266 en modo de suspensión suave. Hace parpadear un LED, que está conectado al pin GPIO2, cada vez que el ESP8266 se despierta del temporizador.

máquina de importación
Pin de importación de máquina
del tiempo importa dormir
led = Pin (2, Pin.OUT) #GPIO2 como salida para LED
led.value(1) #LED está encendido
dormir(1) #1 segundo de retraso
led.value(0) #LED está apagado
dormir(1) #1 segundo de retraso

# espere 5 segundos para que pueda activar el ESP para establecer comunicación en serie más tarde
# debes eliminar esta línea de suspensión en tu script final
dormir(5) #10 segundos de retraso
print('Entrando en modo de suspensión suave')
machine.lightsleep(10000) #10000ms de tiempo de sueño

El siguiente script de MicroPython pone el ESP8266 en modo de suspensión profunda. Hace parpadear un LED, que está conectado al pin GPIO2, cada vez que el ESP8266 se despierta del temporizador.

máquina de importación
Pin de importación de máquina
del tiempo importa dormir
led = Pin (2, Pin.OUT) #GPIO2 como salida para LED
led.value(1) #LED está encendido
dormir(1) #1 segundo de retraso
led.value(0) #LED está apagado
dormir(1) #1 segundo de retraso

# espere 5 segundos para que pueda activar el ESP para establecer comunicación en serie más tarde
# debes eliminar esta línea de suspensión en tu script final
dormir(5) #10 segundos de retraso
print('Entrando en modo de suspensión profunda')
machine.deepsleep(10000) #10000ms de tiempo de sueño

Activación externa EXT0 en ESP32
La activación externa se activa mediante un cambio de pin. Hay dos fuentes externas de activación en el ESP32. EXT0 aplica la activación de cambio de pin solo a uno de los GPIO del RTC. Los GPIO RTC en el ESP32 se muestran a continuación.

A continuación, haremos parpadear el LED cuando EXT0 se despierte. Para hacer esto, conecte el LED a GPIO2 y luego un botón a GPIO14, levantado como se muestra a continuación.

El siguiente script de MicroPython pone el ESP8266 en modo de suspensión suave. Hace parpadear un LED, que está conectado al pin GPIO2, cada vez que el ESP8266 se despierta de un cambio de pin externo.

máquina de importación
importar esp32
Pin de importación de máquina
del tiempo importa dormir

led = Pin (2, Pin.OUT) #GPIO2 como salida para LED
led.value(1) #LED está encendido
dormir(1) #1 segundo de retraso
led.value(0) #LED está apagado
dormir(1) #1 segundo de retraso

# comprueba si el dispositivo se despertó del sueño ligero
si máquina.reset_cause == máquina.DEEPSLEEP_RESET:
print('Me desperté de un sueño ligero')

push_button = Pin(14, modo = Pin.IN) #definiendo push_button como fuente de activación
esp32.wake_on_ext0(pin = push_button, nivel = esp32.WAKEUP_ANY_HIGH) #inicializando el despertar

dormir (5)
print('Entrando en modo de suspensión suave')
máquina.sueño ligero

El siguiente script de MicroPython pone el ESP8266 en modo de suspensión profunda. Hace parpadear un LED, que está conectado al pin GPIO2, cada vez que el ESP8266 se despierta de un cambio de pin externo.

máquina de importación
importar esp32
Pin de importación de máquina
del tiempo importa dormir

led = Pin (2, Pin.OUT) #GPIO2 como salida para LED
led.value(1) #LED está encendido
dormir(1) #1 segundo de retraso
led.value(0) #LED está apagado
dormir(1) #1 segundo de retraso

# comprueba si el dispositivo se despertó de un sueño profundo
si máquina.reset_cause == máquina.DEEPSLEEP_RESET:
print('Me desperté de un sueño profundo')

push_button = Pin(14, modo = Pin.IN) #definiendo push_button como fuente de activación
esp32.wake_on_ext0(pin = push_button, nivel = esp32.WAKEUP_ANY_HIGH) #inicializando el despertar

dormir (5)
print('Entrando en modo de suspensión profunda')
máquina.sueñoprofundo

Nota: Los métodos machine.lightsleep y machine.deepsleep se llaman sin un argumento para la activación externa.

Activación externa EXT1 en ESP32
Para la activación externa EXT1, se puede configurar más de un GPIO RTC como fuente de activación.

Para nuestro proyecto, haremos parpadear un LED en la llamada de atención EXT1. Para hacer esto, conecte el LED a GPIO22. Además, conecte un botón a GPIO2 y un segundo botón a GPIO4, ambos levantados como se muestra a continuación.

Este script MicroPython pone el ESP8266 en modo de suspensión suave. Un LED conectado a GPIO2 parpadea cada vez que el ESP8266 se despierta de un cambio de pin externo en más de uno de los GPIO RTC.

máquina de importación
importar esp32
Pin de importación de máquina
del tiempo importa dormir

led = Pin (22, Pin.OUT) #GPIO22 como salida para LED
led.value(1) #LED está encendido
dormir(1) #1 segundo de retraso
led.value(0) #LED está apagado
dormir(1) #1 segundo de retraso

# comprueba si el dispositivo se despertó del sueño ligero
si máquina.reset_cause == máquina.DEEPSLEEP_RESET:
print('Me desperté de un sueño ligero')

push_button1 = Pin(2, modo = Pin.IN) #definiendo push_button1 como fuente de activación
push_button2 = Pin(4, modo = Pin.IN) #definiendo push_button2 como fuente de activación
esp32.wake_on_ext1(pins = (push_button1, push_button2), nivel = esp32.WAKEUP_ANY_HIGH) #inicializando ext1

dormir (5)
print('Pasando al modo de suspensión suave')
máquina.sueño ligero

Este script MicroPython pone el ESP8266 en modo de suspensión profunda. Un LED conectado a GPIO2 parpadea cada vez que el ESP8266 se despierta de un cambio de pin externo en más de uno de los GPIO de RTC.

máquina de importación
importar esp32
Pin de importación de máquina
del tiempo importa dormir

led = Pin (22, Pin.OUT) #GPIO22 como salida para LED
led.value(1) #LED está encendido
dormir(1) #1 segundo de retraso
led.value(0) #LED está apagado
dormir(1) #1 segundo de retraso

# comprueba si el dispositivo se despertó de un sueño profundo
si máquina.reset_cause == máquina.DEEPSLEEP_RESET:
print('Me desperté de un sueño profundo')

push_button1 = Pin(2, modo = Pin.IN) #definiendo push_button1 como fuente de activación
push_button2 = Pin(4, modo = Pin.IN) #definiendo push_button2 como fuente de activación
esp32.wake_on_ext1(pins = (push_button1, push_button2), nivel = esp32.WAKEUP_ANY_HIGH) #inicializando ext1

dormir (5)
print('Pasando al modo de suspensión profunda')
máquina.sueñoprofundo

Activación de pin táctil en ESP32
El ESP32 tiene pines sensibles al tacto que se pueden usar para despertarse.

Puede utilizar GPIO4 o Touch0 para la detección táctil. Haga esto conectando un cable o puente al GPIO4 y colocando un trozo de papel de aluminio para la detección táctil. El cable o puente debe ser lo más corto posible.

El siguiente script de MicroPython pone el ESP8266 en modo de suspensión suave. Un LED conectado a GPIO22 parpadea cada vez que el ESP8266 se activa desde el sensor táctil.

Pin de importación de máquina, TouchPad, sueño profundo
tiempo de importación
importar esp32

led = Pin (22, Pin.OUT) #GPIO22 como salida para LED
led.value(1) #LED está encendido
dormir(1) #1 segundo de retraso
led.value(0) #LED está apagado
dormir(1) #1 segundo de retraso

despertar = Pin(4, modo = Pin.IN)
toque = TouchPad (despertar)
toque.config(500)
esp32.wake_on_touch (Verdadero)

hora de dormir(5)
sueño ligero (5000)

El siguiente script de MicroPython pone el ESP8266 en modo de suspensión profunda. Un LED conectado a GPIO22 parpadea cada vez que el ESP8266 se activa desde el sensor táctil.

Pin de importación de máquina, TouchPad, sueño profundo
tiempo de importación
importar esp32

led = Pin (22, Pin.OUT) #GPIO22 como salida para LED
led.value(1) #LED está encendido
dormir(1) #1 segundo de retraso
led.value(0) #LED está apagado
dormir(1) #1 segundo de retraso

despertar = Pin(4, modo = Pin.IN)
toque = TouchPad (despertar)
toque.config(500)
esp32.wake_on_touch (Verdadero)

hora de dormir(5)
sueño profundo (5000)

Conclusión
ESP32 es un chip que consume mucha energía. Cuando se utiliza con aplicaciones de red alimentadas por batería, es importante utilizar los modos de suspensión del ESP32 para preservar la vida útil de la batería. Sin embargo, MicroPython solo admite los modos de suspensión ligera y profunda ESP32. Las funciones para implementar cualquiera de los modos provienen del módulo de la máquina. Estas funciones son compartidas por todos los puertos compatibles.

A diferencia del ESP8266, el ESP32 tiene múltiples fuentes de activación. Estos incluyen el temporizador RTC, el cambio de pin externo, los pines táctiles y el coprocesador ULP. El módulo ESP32 específico de MicroPython es esp32, que le permite configurar el temporizador, EXT0, EXT1 y el tono de llamada como fuentes de activación.

El firmware ESP32 original admite la configuración del coprocesador ULP como fuente de activación, pero MicroPython actualmente no permite usar el coprocesador ULP como fuente de activación.

contenido relacionado

Regresar al blog

Deja un comentario

Ten en cuenta que los comentarios deben aprobarse antes de que se publiquen.