3.29. Režimy nízké spotřeby a spánku

Kamery napájené z baterie a senzory aktivní jen občas nepotřebují, aby CPU běželo neustále na plný výkon. Modul machine zpřístupňuje čtyři postupně hlubší stavy úspory energie – active, idle(), lightsleep() a deepsleep(). Každý hlubší krok vypne větší část čipu a ušetří více energie za cenu delšího probuzení. Volba toho správného je kompromisem mezi tím, kolik energie kamera ušetří, a tím, jak rychle dokáže zareagovat, když se něco stane.

3.29.1. Active

Výchozí stav. CPU běží Python, každá periferie je hodinovaná a odběr proudu je nejvyšší – desítky miliampér na logické napájecí větvi kamery plus cokoli, co jejím prostřednictvím odebírá připojené příslušenství.

3.29.2. idle()

machine.idle() pozastaví hodiny CPU, dokud nenastane jakékoli přerušení (periferie, časovač, IRQ pinu). RAM je živá, periferie zůstávají zapnuté, hodiny běží dál – pozastaveno je pouze samotné CPU a probudí se v řádu mikrosekund, jakmile je třeba něco udělat.

Použijte jej uvnitř jakékoli těsné dotazovací smyčky, která čeká, až se stane něco vnějšího:

import machine

while not button_pressed():
    machine.idle()

CPU přestane spalovat cykly na samotné kontrole while a přirozeně se probudí, jakmile dorazí další událost – malá úspora, která se ve smyčce běžící milionkrát nasčítá.

3.29.3. lightsleep()

machine.lightsleep() je dalším krokem níže. CPU je zcela zastaveno a většina vnitřních hodin čipu je vypnuta, ale stav RAM a periferií je zachován. Když se aktivuje zdroj probuzení, skript pokračuje přesně od místa, kde zavolal lightsleep – proměnné, otevřené handle a čekající data zůstávají nedotčené – v řádu milisekund později.

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

Zdroj probuzení – zde IRQ pinu – musí být nakonfigurován před voláním spánku. Odběr proudu výrazně klesne oproti aktivnímu režimu; přesná hodnota závisí na desce a na tom, které periferie jsou stále nakonfigurované.

3.29.4. deepsleep()

machine.deepsleep() je nejhlubším stavem. CPU se zastaví, periferie se vypnou a obsah RAM může být ztracen. Jediné, co stále odebírá energii, je probouzecí obvod a malá část trvale zapnuté logiky.

Když se aktivuje zdroj probuzení, čip nabootuje od začátku hlavního skriptudeepsleep se nevrací. Skript rozliší probuzení z deepsleep od čerstvého zapnutí nebo tvrdého resetu pomocí 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

Argument v milisekundách funkce deepsleep() interně nastaví alarm vestavěného RTC – právě RTC nese časování probuzení skrz spánek, protože většina ostatních časovačů je vypnuta. Volání deepsleep() bez argumentu ponechá probuzení na jakémkoli zdroji, který jste nakonfigurovali samostatně (IRQ pinu, externě nastavený alarm RTC).

Protože se skript restartuje, vše, co příští iterace potřebuje, musí být buď znovu sestaveno na začátku main.py, nebo uloženo do flash paměti (nebo do záložních registrů RTC u součástek, které je mají). Deepsleep poskytuje největší úsporu energie, ale vyžaduje největší přestrukturování programu – aplikace se musí chovat jako série krátkých „měřicích dávek“ oddělených spánky, nikoli jako dlouho běžící smyčka se stavem v RAM.

3.29.5. Volba stavu

Správný stav závisí na tom, na co kamera čeká:

  • Těsná dotazovací smyčka čekající milisekundy. Použijte idle(). Úspory jsou na jeden cyklus malé, ale v součtu velké, a probuzení je neviditelné.

  • Nečinnost po sekundy nebo minuty mezi událostmi. Použijte lightsleep(). Stav je zachován, probuzení je rychlé a odběr proudu je zlomkem aktivního režimu.

  • Nečinnost po minuty či déle mezi krátkými dávkami práce. Použijte deepsleep(). Čip je mezi událostmi prakticky vypnutý a struktura skriptu se přesune na smyčku probuď se, změř, spi.

Ať je stav jakýkoli, zdroj probuzení je stejně důležitý jako stav samotný – deepsleep, který se probouzí jen na časovač, je měřicí smyčka s pevným pracovním cyklem; lightsleep, který se probouzí na IRQ pinu, je událostmi řízený senzor. Funkce spánku modulu machine, alarmy RTC a irq() společně poskytují stavební kameny.