Энергосбережение: deep sleep и батарейное питание

Учим автономное устройство жить на одной батарее месяцами, а не часами.

Deep sleep — режим, в котором ESP32 почти полностью выключается, потребляя микроамперы, и просыпается по таймеру или сигналу на выводе.

Почему важна экономия

Устройство на батарейке (датчик в подвале, на улице) не должно требовать зарядки каждый день. ESP32 в активном режиме с Wi-Fi потребляет 100–250 мА — батарейки хватит на часы. В deep sleep он ест около 10 мкА — в десятки тысяч раз меньше. Стратегия: проснуться, измерить, отправить, заснуть.

Считаем время работы от батареи

Прикинем, насколько хватит аккумулятора при разных стратегиях. Чистый stdlib — пример исполним:

battery_mah = 2000          # ёмкость аккумулятора
active_ma = 120            # ток при работе
sleep_ua = 10              # ток в deep sleep (микроамперы)
active_sec = 10            # секунд работы за цикл
period_min = 30            # просыпаемся раз в 30 минут

# средний ток за цикл
cycle_sec = period_min * 60
active_charge = active_ma * (active_sec / 3600)        # мА*ч за активность
sleep_charge = (sleep_ua / 1000) * ((cycle_sec - active_sec) / 3600)
avg_per_cycle = active_charge + sleep_charge
cycles = battery_mah / avg_per_cycle
days = cycles * cycle_sec / 86400
print("Хватит примерно на", round(days), "дней")

Вывод:

Хватит примерно на 123 дней

Без сна те же 2000 мА·ч при 120 мА кончились бы за ~16 часов. Сон растягивает работу до месяцев.

Код deep sleep

import machine
import time

# ... здесь: проснулись, измерили, отправили по MQTT ...
print("Засыпаю на 30 минут")
time.sleep(1)                       # дать отправке завершиться
machine.deepsleep(30 * 60 * 1000)   # миллисекунды

После deepsleep чип не продолжает программу — он перезапускается по истечении времени и снова выполняет main.py с начала.

Пробуждение по пину

import machine
from machine import Pin

# проснуться, если на GPIO33 появится высокий уровень (датчик)
wake_pin = Pin(33, Pin.IN)
machine.deepsleep()   # без аргумента — спать, пока не разбудит пин/событие

Как работает под капотом

В deep sleep ESP32 отключает основные ядра, Wi-Fi и память. Бодрствует лишь крошечный RTC-контроллер с таймером и парой выводов. Когда срабатывает таймер или меняется уровень на «будящем» пине, RTC включает чип заново — происходит полный перезапуск, как после подачи питания. Поэтому переменные не сохраняются; немного данных можно держать в специальной RTC-памяти, переживающей сон.

Частые ошибки

  • Ждать продолжения после deepsleep. Код после него не выполнится — чип перезагрузится с начала.
  • Не дать сети завершить отправку. Дайте паузу перед сном, иначе сообщение не уйдёт.
  • Держать включёнными светодиоды и периферию. Лишний ток сводит экономию на нет.

Итог

  • Deep sleep снижает потребление с сотен мА до микроампер.
  • Стратегия: проснуться → измерить → отправить → заснуть.
  • После deepsleep чип перезапускается с начала main.py.
  • Будит таймер или сигнал на пине; данные переживают сон лишь в RTC-памяти.
Проверьте себя
1. Что происходит с программой после вызова machine.deepsleep()?
AКод продолжается со следующей строки
BЧип засыпает и при пробуждении ПЕРЕЗАПУСКАЕТСЯ с начала main.py
CПрограмма завершается навсегда
DWi-Fi отключается, но код идёт дальше
2. Насколько deep sleep снижает потребление по сравнению с активным режимом?
AВ 2 раза
BПрактически не меняет
CС сотен миллиампер до микроампер — в тысячи раз
DУвеличивает потребление
3. Что будит ESP32 из deep sleep?
AТолько перезагрузка вручную
BТаймер RTC или сигнал на специальном пробуждающем выводе
CТолько Wi-Fi-пакет
DНичего, он спит вечно