3.29. Режими низького споживання та сну¶
Камерам із батарейним живленням та датчикам, що активуються лише час від часу, не потрібно постійно тримати процесор на повній швидкості. Модуль machine надає чотири режими заощадження енергії з наростаючою глибиною: active, idle(), lightsleep() та deepsleep(). Кожен наступний крок вимикає більше частин чіпа та економить більше енергії, але збільшує час пробудження. Вибір правильного режиму – це компроміс між тим, скільки енергії заощаджує камера, і тим, як швидко вона може відреагувати на подію.
3.29.1. Активний¶
Стан за замовчуванням. Процесор виконує Python, кожен периферійний пристрій тактується, а споживання струму максимальне – десятки міліамперів на логічній шині камери плюс будь-яке навантаження від підключених аксесуарів.
3.29.2. idle()¶
machine.idle() зупиняє тактування процесора до спрацювання будь-якого переривання (периферійного пристрою, таймера, IRQ виводу). Оперативна пам’ять залишається активною, периферійні пристрої продовжують роботу, тактування продовжується – лише сам процесор призупиняється, і він прокидається за мікросекунди, коли з’являється робота.
Використовуйте його всередині будь-якого щільного циклу опитування, який очікує на зовнішню подію:
import machine
while not button_pressed():
machine.idle()
Процесор перестає витрачати цикли на саму перевірку while та природно прокидається при настанні наступної події – невелика економія, яка накопичується в циклі, що виконується мільйони разів.
3.29.3. lightsleep()¶
machine.lightsleep() – наступний рівень. Процесор повністю зупиняється, більшість внутрішніх тактових сигналів чіпа вимикається, але оперативна пам’ять і стан периферійних пристроїв зберігаються. Коли спрацьовує джерело пробудження, скрипт відновлюється з того місця, де було викликано lightsleep – змінні, відкриті дескриптори та незавершені дані залишаються незмінними – приблизно через кілька мілісекунд.
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
Джерело пробудження – тут IRQ виводу – необхідно налаштувати до виклику сну. Споживання енергії значно знижується порівняно з активним режимом; точне значення залежить від плати та налаштованих периферійних пристроїв.
3.29.4. deepsleep()¶
machine.deepsleep() – найглибший стан. Процесор зупиняється, периферійні пристрої вимикаються, і вміст оперативної пам’яті може бути втрачено. Єдине, що продовжує споживати енергію, – це схема пробудження та невелика логіка, яка завжди залишається увімкненою.
Коли спрацьовує джерело пробудження, чіп завантажується з початку основного скрипту – deepsleep не повертається. Скрипт відрізняє пробудження з глибокого сну від звичайного увімкнення живлення або апаратного скидання за допомогою 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
Аргумент у мілісекундах для deepsleep() внутрішньо активує будильник вбудованого RTC – саме RTC забезпечує таймінг пробудження під час сну, оскільки більшість інших таймерів вимкнено. Виклик deepsleep() без аргументу передає ініціативу пробудження тому джерелу, яке ви налаштували окремо (IRQ виводу, зовнішній будильник RTC).
Оскільки скрипт перезапускається, все, що потрібно наступній ітерації, слід або відновлювати на початку main.py, або зберігати у флеш-пам’яті (або в резервних регістрах RTC, якщо вони є на даній мікросхемі). Глибокий сон забезпечує найбільшу економію енергії, але вимагає найбільшої реструктуризації програми – застосунок має поводитися як серія коротких «вимірювальних сплесків», розділених сном, а не як тривалий цикл зі станом у оперативній пам’яті.
3.29.5. Вибір стану¶
Правильний стан залежить від того, на що чекає камера:
Щільний цикл опитування, очікування мілісекунд. Використовуйте
idle(). Економія на один цикл невелика, але в сукупності значна, а пробудження непомітне.Простій протягом секунд або хвилин між подіями. Використовуйте
lightsleep(). Стан зберігається, пробудження швидке, а споживання енергії – лише частина активного режиму.Простій протягом хвилин або довше між короткими сплесками роботи. Використовуйте
deepsleep(). Між подіями чіп фактично вимкнено, а структура скрипту переходить до циклу «пробудитися, виміряти, заснути».
Яким би не був стан, джерело пробудження має таке ж значення, як і сам стан – глибокий сон, що прокидається лише за таймером, це цикл вимірювань із регульованим навантаженням; легкий сон, що прокидається за IRQ виводу, – це датчик, керований подіями. Функції сну модуля machine, будильники RTC та irq() разом утворюють будівельні блоки.