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

Em um artigo anterior, abordamos os modos de suspensão no ESP8266. ESP32 é outra placa de desenvolvimento Wi-Fi popular da Expressif Systems. É mais rico em recursos do que o ESP8266, mas também consome mais energia. O consumo de energia do ESP32 pode chegar a 790 mA quando o Wi-Fi e o Bluetooth estão operacionais – quase o dobro do ESP8266, que atinge o máximo de cerca de 400 mA quando altamente ativo. Os componentes da placa breakout também podem adicionar algumas centenas de mAs ao consumo líquido de energia.

Muitos desenvolvedores de IoT preferem usar o SoC repleto de recursos em seus aplicativos para que sejam necessários componentes externos mínimos na placa. É por isso que ESP32 é a escolha ideal para muitos que escolhem entre as duas placas Expressif. No entanto, o consumo de energia do ESP32 pode representar um desafio para dispositivos IoT alimentados por bateria. Felizmente, oferece várias opções de gerenciamento de energia que ajudam.

A seguir, discutiremos os modos de energia e suspensão do ESP32, cobrindo as diferentes fontes de ativação e como ambas (as fontes de suspensão e ativação) são gerenciadas na estrutura do MicroPython. O uso dos modos de suspensão adequados do ESP32 em um aplicativo de rede alimentado por bateria torna possível reduzir o consumo de energia do sistema de centenas para alguns mAs.

Modos de suspensão no ESP32
No ESP32, existem cinco modos de energia disponíveis: modos ativo, suspensão do modem, suspensão leve, suspensão profunda e hibernação.

Sono ativo é o modo padrão do ESP32, onde todos os periféricos, incluindo Wi-Fi, módulo Bluetooth, CPU, relógio do sistema e RTC estão ligados. O consumo típico de energia do SoC neste modo é de 240 mA, embora possa aumentar para 790 mA quando o Wi-Fi e o Bluetooth funcionam juntos no pico de operação. No entanto, o consumo de energia no modo ativo pode ser ajustado definindo as configurações de Wi-Fi.

Normalmente, quando o módulo Wi-Fi transmite uma saída entre 13 e 21dBm, o SoC consome entre 160 a 260 mAs. A potência de saída é a soma da potência de transmissão de rádio e do ganho da antena menos as perdas do cabo.

Se a saída Wi-Fi estiver configurada para 0dBm, o consumo é reduzido para 120 mA. Se o aplicativo receber dados apenas pela rede, o módulo Wi-Fi poderá ser configurado para o modo de recepção e escuta. Nesta configuração, o consumo do SoC em modo ativo é reduzido para 80~90 mA.

No suspensão do modem modo, a CPU, o relógio do sistema e o RTC estão ligados enquanto o Wi-Fi, o Bluetooth e o rádio estão desligados. O consumo neste modo é de 20 mA se a CPU funcionar em alta velocidade e pode chegar a 3 mA se a CPU funcionar mais lentamente.

Neste modo, o SoC utiliza o mecanismo de beacon DTIM para permanecer conectado à rede. O Wi-Fi é desativado entre os dois intervalos de beacon e é ligado antes da chegada do próximo. O tempo de suspensão é determinado pelo intervalo de beacon DTIM do roteador Wi-Fi, que varia entre 100 e 1000 ms. O módulo Wi-Fi do ESP32 pode ser configurado para publicar um DTIM após um, três ou 10 intervalos de beacon. O valor DTIM padrão é três.

Em Sono leve modo, a CPU entra em um estado pendente, o que significa que ela é interrompida desligando os pulsos de clock. O Wi-Fi, o Bluetooth e o rádio também estão desligados. O Wi-Fi permanece conectado à rede pelo mecanismo de beacon DTIM, onde entra periodicamente nos modos de suspensão e ativação e se reconecta ao modem.

O estado atual da RAM é preservado antes de entrar no modo de suspensão leve, que é retomado quando o chip é ativado. O RTC é a única coisa que permanece ligada, necessária para manter a data e hora. O consumo de energia do SoC do ESP32 é reduzido para 0,8 mA neste modo.

No sono profundo modo, o Wi-Fi, Bluetooth, rádio, relógio do sistema, CPU e RAM são desligados. O único periférico ligado é o módulo RTC. Os dados da conexão Wi-Fi e Bluetooth são preservados na memória RTC, pois a memória principal é apagada sempre que o SoC entra em hibernação profunda.

O coprocessador ULP também permanece ativo e continua agregando dados do sensor. Os dados do sensor são usados ​​para despertar o chip de um sono profundo. O consumo de energia do ESP32 em sono profundo é reduzido para 0,15 mA ~ 10 uA, dependendo das atividades do coprocessador ULP.

No hibernação modo, tudo está desligado, incluindo Wi-Fi, Bluetooth, rádio, relógio do sistema, CPU, coprocessador ULP e RTC. Apenas o temporizador RTC é mantido em relógio lento. O consumo de energia do ESP32 é reduzido para 2,5 uA neste modo.

Por padrão, o MicroPython oferece suporte apenas aos modos de suspensão leve e profunda para portas suportadas. Estes são os únicos dois modos suportados ao usar ESP32 no MicroPython.

Fontes de despertar do ESP32
Existem quatro fontes de ativação no ESP32: temporizador, externo, pinos de toque e processador ULP.

No despertar com temporizador, o RTC integrado é usado para despertar o SoC de um sono profundo após um período especificado. No despertar externo, o SoC entra em sono profundo indefinido até que um sinal seja detectado pelo RTC GPIO. Existem dois “despertares” externos no ESP32: ext0 e ext1.

No ext0, apenas um RTC GPIO é usado para despertar o SoC de um sono profundo. No ext1, dois RTC GPIO são usados ​​para ativar o chip. Na ativação do pino de toque, o chip desperta de um sono profundo por um de seus pinos de toque capacitivos. O coprocessador ULP é usado para ativar o processador principal por meio dos dados do sensor.

Consumo de energia do ESP32 em diferentes modos de suspensão.

MicroPython suporta a ativação do ESP32 usando um temporizador, sinais externos e pinos de toque. O que não é suportado é a ativação do coprocessador ULP. Existem funções disponíveis para acessar o coprocessador ULP, carregar um binário no coprocessador ULP, executar o ULP a partir de um ponto de entrada ou ativar o coprocessador ULP em intervalos periódicos. Essas funções não estão relacionadas ao despertar dos modos de sono profundo ou leve. Isso significa que embora o coprocessador ULP possa ser usado para ativar o ESP32, ele não está atualmente acessível no MicroPython.

Como o sono profundo é usado no ESP32
Como mencionado, o ESP32 é um chip que consome muita energia. Portanto, seu modo de suspensão profunda é particularmente útil em aplicações de rede alimentadas por bateria. Ele permite que o chip permaneça principalmente em estado de suspensão profunda ou inativo, despertando periodicamente para executar as tarefas atribuídas. Essas tarefas incluem fazer leituras de um sensor, enviar os dados do sensor para um servidor por meio de um protocolo IoT (como MQTT ou CoAP) e/ou executar uma ação no local com base em leituras de sensores ou insights recebidos pela rede.

Após executar uma tarefa pela aplicação do usuário, o chip retorna ao sono profundo por um período especificado. Mesmo em sono profundo, os detalhes da rede Wi-Fi e Bluetooth são armazenados na memória RTC. Isso permite que a placa se reconecte facilmente à rede sempre que acordar de um sono profundo. O ciclo de sono profundo, despertar, executar tarefas incorporadas/IoT e voltar a dormir continua indefinidamente.

Funções relacionadas à energia do MicroPython
O módulo de máquina do MicroPython fornece as seguintes funções para o gerenciamento de energia das placas suportadas.

máquina.lightsleep((time_ms)): coloca a porta em modo de suspensão leve. Se o tempo em milissegundos for especificado como argumento, o modo de suspensão leve durará o tempo especificado. A porta pode ser ativada antes do horário definido, acionada por uma fonte. Se nenhum argumento for passado, o modo de suspensão leve dura indefinidamente ou até ser interrompido por uma fonte de despertar.

máquina.deepsleep((time_ms)): coloca a porta em modo de hibernação profunda. Se o tempo em milissegundos for especificado como argumento, o modo de suspensão profunda durará o tempo especificado. A porta pode ser ativada antes do horário definido, acionada por uma fonte. Se nenhum argumento for passado, o modo de suspensão profunda dura indefinidamente, até ser interrompido por uma fonte de despertar. Acordar do modo de suspensão profunda é o mesmo que uma reinicialização de hardware.

máquina.wake_reason : retorna a fonte de ativação. O valor retornado pode ser machine.WLAN_WAKE, machine.PIN_WAKE ou machine.RTC_WAKE — dependendo se a fonte de ativação é WLAN, alteração de pino ou RTC. Este método pode registrar um motivo de ativação em uma variável ou imprimi-lo no console.

A fonte de despertar deve ser configurada antes de solicitar sono leve ou profundo. E a máquina.wake_reason só pode ser chamado depois pedindo sono leve ou profundo.

O máquina.idle é outra função útil para o gerenciamento de energia da porta. Quando chamadas, as portas do relógio (para a CPU) fazem com que a porta entre em modo de suspensão, onde a porta acorda se receber uma interrupção.

Implementação MicroPython de modos de suspensão no ESP32
MicroPython oferece suporte apenas aos modos de suspensão leve e profunda no ESP32. Eles são implementados pelos métodos machine.lightsleep e machine.deepsleep . Há um módulo específico do ESP32, esp32, no MicroPython que fornece funções adicionais para configurar a fonte de ativação.

Esses métodos são:

esp32.wake_on_touch(despertar): configura se o “toque” despertará ou não o ESP32. Ele usa um argumento booleano. Se definido como '1', o ESP32 é ativado ao toque. Se definido como '0', o ESP32 não ativa ao ser tocado.

esp32.wake_on_ext0(pino, nível): configura o despertar externo, EXT0. Este wake-up pode ser aplicado em um pino, que deve ser RTC GPIO. Requer dois argumentos: um objeto pin e um nível. O nível pode ser definido como esp32.WAKEUP_ALL_LOW ou esp32.WAKEUP_ANY_HIGH.

esp32.wake_on_ext1(pinos, nível): configura o despertar externo, EXT1. Este wake-up pode ser aplicado em vários pinos, desde que sejam RTC GPIO. Requer dois argumentos: uma lista ou tupla de objetos pin e um nível. O nível pode ser definido como esp32.WAKEUP_ALL_LOW ou esp32.WAKEUP_ANY_HIGH.

esp32.gpio_deep_sleep_hold(habilitar): determina se a configuração de pinos GPIO não RTC é mantida ou não para blocos retidos durante o modo de hibernação profunda. Ele usa um argumento booleano, que pode ser definido como '0' ou '1'.

Despertar com temporizador no ESP32
O despertador do ESP32 não requer nenhum arranjo especial. Basta chamar os métodos deepsleep ou Lightsleep com um tempo especificado em milissegundos para colocar o ESP32 em sono profundo ou leve.

Para este projeto, usaremos o timer wake-up do ESP32 para piscar um LED. Para isso, conecte um LED aos ESP32 no GPIO2 conforme imagem abaixo.

Este script MicroPython coloca o ESP8266 em um modo de suspensão leve. Ele pisca um LED, que está conectado ao pino GPIO2, cada vez que o ESP8266 desperta do temporizador.

máquina de importação
do Pin de importação da máquina
do tempo importar sono
led = Pino (2, Pin.OUT) #GPIO2 como saída para LED
led.value(1) #LED está LIGADO
sleep(1) #atraso de 1 segundo
led.value(0) #LED está DESLIGADO
sleep(1) #atraso de 1 segundo

# espere 5 segundos para que você possa acordar o ESP para estabelecer uma comunicação serial mais tarde
# você deve remover esta linha de suspensão no seu script final
sleep(5) #atraso de 10 segundos
print('Entrando no modo de suspensão leve')
machine.lightsleep(10000) #10000ms tempo de suspensão

O script MicroPython a seguir coloca o ESP8266 em modo de suspensão profunda. Ele pisca um LED, que está conectado ao pino GPIO2, cada vez que o ESP8266 desperta do temporizador.

máquina de importação
do Pin de importação da máquina
do tempo importar sono
led = Pino (2, Pin.OUT) #GPIO2 como saída para LED
led.value(1) #LED está LIGADO
sleep(1) #atraso de 1 segundo
led.value(0) #LED está DESLIGADO
sleep(1) #atraso de 1 segundo

# espere 5 segundos para que você possa acordar o ESP para estabelecer uma comunicação serial mais tarde
# você deve remover esta linha de suspensão no seu script final
sleep(5) #atraso de 10 segundos
print('Entrando no modo de suspensão profunda')
machine.deepsleep(10000) #10000ms tempo de suspensão

Ativação externa EXT0 no ESP32
A ativação externa é acionada por uma mudança de pino. Existem duas fontes externas de ativação no ESP32. EXT0 aplica ativação com mudança de pino em apenas um dos GPIOs RTC. Os GPIOs RTC no ESP32 são mostrados abaixo.

A seguir, vamos piscar o LED ao despertar do EXT0. Para fazer isso, conecte o LED ao GPIO2 e, em seguida, um botão ao GPIO14 – puxado para cima conforme mostrado abaixo.

O script MicroPython a seguir coloca o ESP8266 em um modo de suspensão leve. Ele pisca um LED, que está conectado ao pino GPIO2, cada vez que o ESP8266 acorda de uma mudança de pino externo.

máquina de importação
importar esp32
do Pin de importação da máquina
do tempo importar sono

led = Pino (2, Pin.OUT) #GPIO2 como saída para LED
led.value(1) #LED está LIGADO
sleep(1) #atraso de 1 segundo
led.value(0) #LED está DESLIGADO
sleep(1) #atraso de 1 segundo

# verifica se o dispositivo acordou de um sono leve
se máquina.reset_cause == máquina.DEEPSLEEP_RESET:
print('acordei de um sono leve')

push_button = Pin(14, mode = Pin.IN) #definindo push_button como fonte de despertar
esp32.wake_on_ext0(pin = push_button, level = esp32.WAKEUP_ANY_HIGH) #inicializando despertar

dormir (5)
print('Entrando no modo de suspensão leve')
máquina.lightsleep

O script MicroPython a seguir coloca o ESP8266 em modo de suspensão profunda. Ele pisca um LED, que está conectado ao pino GPIO2, cada vez que o ESP8266 acorda de uma mudança de pino externo.

máquina de importação
importar esp32
do Pin de importação da máquina
do tempo importar sono

led = Pino (2, Pin.OUT) #GPIO2 como saída para LED
led.value(1) #LED está LIGADO
sleep(1) #atraso de 1 segundo
led.value(0) #LED está DESLIGADO
sleep(1) #atraso de 1 segundo

# verifica se o dispositivo acordou de um sono profundo
se máquina.reset_cause == máquina.DEEPSLEEP_RESET:
print('acordei de um sono profundo')

push_button = Pin(14, mode = Pin.IN) #definindo push_button como fonte de despertar
esp32.wake_on_ext0(pin = push_button, level = esp32.WAKEUP_ANY_HIGH) #inicializando despertar

dormir (5)
print('Entrando no modo de suspensão profunda')
máquina.deepsleep

Observação: os métodos machine.lightsleep e machine.deepsleep são chamados sem um argumento para a ativação externa.

Ativação externa EXT1 no ESP32
Para a ativação externa EXT1, mais de um GPIO RTC pode ser configurado como fonte de ativação.

Para o nosso projeto, piscaremos um LED na chamada de despertar do EXT1. Para fazer isso, conecte o LED ao GPIO22. Além disso, conecte um botão ao GPIO2 e um segundo botão ao GPIO4, ambos puxados para cima, conforme mostrado abaixo.

Este script MicroPython coloca o ESP8266 em um modo de suspensão leve. Ele pisca um LED conectado ao GPIO2 cada vez que o ESP8266 acorda de uma mudança de pino externo em mais de um dos GPIOs RTC.

máquina de importação
importar esp32
do Pin de importação da máquina
do tempo importar sono

led = Pino (22, Pin.OUT) #GPIO22 como saída para LED
led.value(1) #LED está LIGADO
sleep(1) #atraso de 1 segundo
led.value(0) #LED está DESLIGADO
sleep(1) #atraso de 1 segundo

# verifica se o dispositivo acordou de um sono leve
se máquina.reset_cause == máquina.DEEPSLEEP_RESET:
print('acordei de um sono leve')

push_button1 = Pin(2, mode = Pin.IN) #definindo push_button1 como fonte de despertar
push_button2 = Pin(4, mode = Pin.IN) #definindo push_button2 como fonte de despertar
esp32.wake_on_ext1(pinos = (push_button1, push_button2), nível = esp32.WAKEUP_ANY_HIGH) #initializing ext1

dormir (5)
print('Indo para o modo de suspensão leve')
máquina.lightsleep

Este script MicroPython coloca o ESP8266 em modo de hibernação profunda. Ele pisca um LED conectado ao GPIO2 cada vez que o ESP8266 acorda de uma mudança de pino externo em mais de um dos GPIOs RTC.

máquina de importação
importar esp32
do Pin de importação da máquina
do tempo importar sono

led = Pino (22, Pin.OUT) #GPIO22 como saída para LED
led.value(1) #LED está LIGADO
sleep(1) #atraso de 1 segundo
led.value(0) #LED está DESLIGADO
sleep(1) #atraso de 1 segundo

# verifica se o dispositivo acordou de um sono profundo
se máquina.reset_cause == máquina.DEEPSLEEP_RESET:
print('acordei de um sono profundo')

push_button1 = Pin(2, mode = Pin.IN) #definindo push_button1 como fonte de despertar
push_button2 = Pin(4, mode = Pin.IN) #definindo push_button2 como fonte de despertar
esp32.wake_on_ext1(pinos = (push_button1, push_button2), nível = esp32.WAKEUP_ANY_HIGH) #initializing ext1

dormir (5)
print('Indo para o modo de suspensão profunda')
máquina.deepsleep

Ativação do pino de toque no ESP32
O ESP32 possui pinos sensíveis ao toque que podem ser usados ​​para despertar.

Você pode usar GPIO4 ou Touch0 para detecção de toque. Faça isso conectando um fio ou jumper ao GPIO4 e prendendo um pedaço de papel alumínio para detecção de toque. O fio ou jumper deve ser o mais curto possível.

O script MicroPython a seguir coloca o ESP8266 em um modo de suspensão leve. Ele pisca um LED conectado ao GPIO22 cada vez que o ESP8266 desperta do sensor de toque.

da importação da máquina Pin, TouchPad, deepsleep
hora de importação
importar esp32

led = Pino (22, Pin.OUT) #GPIO22 como saída para LED
led.value(1) #LED está LIGADO
sleep(1) #atraso de 1 segundo
led.value(0) #LED está DESLIGADO
sleep(1) #atraso de 1 segundo

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

hora.sono(5)
sono leve (5000)

O script MicroPython a seguir coloca o ESP8266 em modo de suspensão profunda. Ele pisca um LED conectado ao GPIO22 cada vez que o ESP8266 desperta do sensor de toque.

da importação da máquina Pin, TouchPad, deepsleep
hora de importação
importar esp32

led = Pino (22, Pin.OUT) #GPIO22 como saída para LED
led.value(1) #LED está LIGADO
sleep(1) #atraso de 1 segundo
led.value(0) #LED está DESLIGADO
sleep(1) #atraso de 1 segundo

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

hora.sono(5)
sono profundo (5000)

Conclusão
ESP32 é um chip que consome muita energia. Quando usado com aplicativos de rede alimentados por bateria, é importante usar os modos de suspensão do ESP32 para preservar a vida útil da bateria. No entanto, o MicroPython suporta apenas os modos de suspensão leve e profunda do ESP32. As funções para implementar qualquer um dos modos vêm do módulo da máquina. Estas funções são compartilhadas por todas as portas suportadas.

Ao contrário do ESP8266, o ESP32 possui várias fontes de ativação. Isso inclui o temporizador RTC, mudança de pino externo, pinos de toque e o coprocessador ULP. O módulo específico do ESP32 do MicroPython é o esp32, que permite configurar o temporizador, EXT0, EXT1 e toque como fontes de ativação.

O firmware original do ESP32 suporta a configuração do coprocessador ULP como fonte de ativação, mas o MicroPython atualmente não permite o uso do coprocessador ULP como fonte de ativação.

Related Content

Back to blog

Leave a comment

Please note, comments need to be approved before they are published.