3.29. Modos de baixo consumo e de suspensão¶
Câmaras alimentadas por bateria e sensores ativos intermitentemente não precisam que a CPU funcione a plena velocidade o tempo todo. O módulo machine expõe quatro estados de poupança de energia progressivamente mais profundos – active, idle(), lightsleep() e deepsleep(). Cada nível mais profundo desliga mais componentes do chip e poupa mais energia, à custa de um tempo de arranque mais longo. Escolher o estado correto é um equilíbrio entre a poupança de energia da câmara e a velocidade com que pode reagir quando algo acontece.
3.29.1. Ativo¶
O estado predefinido. A CPU está a executar Python, todos os periféricos têm clock, e o consumo de corrente está no máximo – dezenas de miliamperes no rail lógico da câmara, mais o que quaisquer acessórios ligados consumirem.
3.29.2. idle()¶
machine.idle() suspende o clock da CPU até que qualquer interrupção dispare (um periférico, um temporizador, uma IRQ de pino). A RAM está ativa, os periféricos permanecem ligados, os clocks continuam a funcionar – apenas a própria CPU é pausada, e acorda em microssegundos quando há trabalho a fazer.
Utilize-o dentro de qualquer ciclo de interrogação que esteja à espera que algo externo aconteça:
import machine
while not button_pressed():
machine.idle()
A CPU deixa de gastar ciclos na própria verificação do while e acorda naturalmente quando chega o próximo evento – uma pequena poupança que se acumula ao longo de um ciclo que executa milhões de vezes.
3.29.3. lightsleep()¶
machine.lightsleep() é o nível seguinte. A CPU é completamente parada e a maioria dos clocks internos do chip são desligados, mas a RAM e o estado dos periféricos são preservados. Quando a fonte de arranque dispara, o script retoma exatamente onde chamou lightsleep – variáveis, handles abertos e dados pendentes todos intactos – ordem de grandeza de milissegundos depois.
import machine
from machine import Pin
wake_pin = Pin("P0", Pin.IN, Pin.PULL_UP)
wake_pin.irq(lambda _: None, trigger=Pin.IRQ_FALLING, wake=machine.SLEEP)
while True:
do_work()
machine.lightsleep() # wakes on a falling edge on P0
A fonte de arranque – uma IRQ de pino neste caso – deve ser configurada antes da chamada de suspensão. O consumo de energia cai significativamente em relação ao modo ativo; o valor exato depende da placa e dos periféricos que ainda estão configurados.
3.29.4. deepsleep()¶
machine.deepsleep() é o estado mais profundo. A CPU para, os periféricos são desligados e o conteúdo da RAM pode ser perdido. As únicas coisas que ainda consomem energia são o circuito de arranque e uma pequena lógica sempre ativa.
Quando a fonte de arranque dispara, o chip arranca desde o início do script principal – deepsleep não retorna. O script distingue um arranque de deepsleep de um arranque limpo ou reset forçado usando machine.reset_cause():
import machine
if machine.reset_cause() == machine.DEEPSLEEP_RESET:
# Woke from deepsleep -- restore state from non-volatile storage,
# take a measurement, etc.
pass
else:
# Fresh boot
pass
do_work()
machine.deepsleep(60_000) # arm RTC wake for 60 s, sleep, then restart
O argumento em milissegundos passado a deepsleep() arma internamente o alarme RTC do chip – o RTC é o que mantém o timing de arranque durante o sono, uma vez que a maioria dos outros temporizadores são desligados. Chamar deepsleep() sem argumento deixa o arranque para qualquer fonte que tenha configurado separadamente (uma IRQ de pino, um alarme RTC armado externamente).
Uma vez que o script reinicia, tudo o que a próxima iteração necessitar tem de ser reconstruído no início de main.py ou persistido em flash (ou nos registos de backup do RTC, nas partes que os têm). O deepsleep proporciona a maior poupança de energia, mas impõe a maior reestruturação de programa – a aplicação tem de funcionar como uma série de curtas «rajadas de medição» separadas por períodos de suspensão, em vez de um ciclo de longa duração com estado em RAM.
3.29.5. Escolher um estado¶
O estado correto depende do que a câmara está à espera:
Ciclo de interrogação apertado, à espera de milissegundos. Use
idle(). As poupanças são pequenas por ciclo mas grandes no total, e o arranque é invisível.Inativo durante segundos ou minutos entre eventos. Use
lightsleep(). O estado é preservado, o arranque é rápido e o consumo de energia é uma fração do modo ativo.Inativo durante minutos ou mais entre curtas rajadas de trabalho. Use
deepsleep(). O chip está efetivamente desligado entre eventos, e a estrutura do script muda para um ciclo de arranque, medição e suspensão.
Seja qual for o estado, a fonte de arranque é tão importante quanto o estado em si – um deepsleep que arranca apenas por temporizador é um ciclo de medição por duty cycle; um lightsleep que arranca numa IRQ de pino é um sensor orientado por eventos. As funções de suspensão do módulo machine, os alarmes RTC e irq() juntos fornecem os blocos de construção.