Глубокий сон ESP32: как спать на 10 мкА и просыпаться по делу
В глубоком сне ESP32 по даташиту потребляет около 10 мкА — в тысячи раз меньше, чем в работе. Но просыпается он почти как после сброса, Wi-Fi при этом отключается, а лишние токи через подтяжки легко съедают выигрыш. Разбираем по даташиту Espressif и руководству ESP-IDF режимы сна, источники пробуждения и что делать, чтобы плата действительно жила от батареи.
Обновлено Редакция GAW
У ESP32 пять режимов питания, и по даташиту Espressif они различаются тем, что остаётся включённым. Глубокий сон (deep sleep) — самый ходовой экономный режим: работают только часы реального времени и маленькая память RTC, а ток падает до 10 мкА. Это основа любого датчика на батарейках: проснулся, измерил, отправил, уснул.
Режимы и токи
По таблице 4-2 даташита ESP32:
| Режим | Что работает | Ток |
|---|---|---|
| Active | процессор и радио | Wi-Fi: передача до 240 мА, приём 95–100 мА |
| Modem-sleep | процессор, радио выключено | 20–68 мА в зависимости от частоты 80–240 МГц |
| Light-sleep | процессор остановлен, RTC и ULP работают | 0,8 мА |
| Deep-sleep с ULP | память и периферия RTC, сопроцессор ULP | 150 мкА |
| Deep-sleep, ULP по расписанию 1 % | то же, ULP измеряет периодически | 100 мкА |
| Deep-sleep | таймер RTC и память RTC | 10 мкА |
| Hibernation | только таймер RTC и некоторые RTC GPIO | 5 мкА |
| Выключен | CHIP_PU в нуле | 1 мкА |
Цифры относятся к самому чипу. Всё остальное на плате — стабилизатор, преобразователь USB–UART, светодиод питания, внешние подтяжки — потребляет дополнительно, и на отладочной плате ток сна может быть намного больше табличного. Для батарейного устройства его измеряют на своей плате.
Что сохраняется во сне
По руководству ESP-IDF в глубоком сне выключены процессоры, большая часть оперативной памяти и вся цифровая периферия. Остаются под питанием контроллер RTC, сопроцессор ULP и две области памяти RTC — FAST и SLOW.
Отсюда главное отличие от привычного «сна» микроконтроллера: после пробуждения ESP32 не продолжает программу с места остановки. ESP-IDF описывает это так: при пробуждении выполняется короткий код wake stub, а затем загружается приложение — фактически программа стартует заново, и setup() в Arduino выполняется снова. Данные, которые нужно пронести через сон — счётчик пробуждений, последнее измерение, — объявляют с атрибутом RTC_DATA_ATTR: они лежат в памяти RTC SLOW, и ESP-IDF по умолчанию оставляет её включённой, если там есть переменные.
Wi-Fi и Bluetooth во сне выключены, и соединения не сохраняются. После пробуждения устройство подключается к сети заново, а радио по даташиту потребляет 95–240 мА — время подключения и стоит сокращать.
Источники пробуждения
ESP-IDF перечисляет для ESP32 такие источники; их можно включать одновременно, и чип проснётся от любого:
| Источник | Как работает | Функция ESP-IDF |
|---|---|---|
| Таймер RTC | через заданное время, задаётся в микросекундах | esp_sleep_enable_timer_wakeup |
| ext0 | один RTC GPIO на заданном уровне; периферия RTC во сне остаётся включённой | esp_sleep_enable_ext0_wakeup |
| ext1 | несколько RTC GPIO: любой в единице или все в нуле | esp_sleep_enable_ext1_wakeup_io |
| Касание | прерывание сенсора касания | esp_sleep_enable_touchpad_wakeup |
| ULP | программа сопроцессора решает, когда будить | esp_sleep_enable_ulp_wakeup |
Для внешнего пробуждения годятся только выводы RTC. По даташиту ESP32 это RTC_GPIO0–RTC_GPIO17: GPIO36, 37, 38, 39, 34, 35, 25, 26, 33, 32, 4, 0, 2, 15, 13, 12, 14 и 27. Подтяжку для кнопки включают функциями rtc_gpio_pullup_en и rtc_gpio_pulldown_en до входа в сон. У ext1 есть ограничение: если выводов несколько, уровень пробуждения у всех один. После пробуждения вывод остаётся в режиме RTC, и чтобы снова использовать его как обычный GPIO, ESP-IDF требует вызвать rtc_gpio_deinit.
Причину пробуждения возвращает esp_sleep_get_wakeup_cause(), а для ext1 и касания отдельные функции сообщают, какой именно вывод сработал. Если не включить ни одного источника, чип по ESP-IDF будет спать до внешнего сброса.
Режим Light-sleep будит ещё и любой GPIO, а также UART, но там и ток другой — 0,8 мА против 10 мкА.
Где теряются микроамперы
- Подтяжки на выводах. ESP-IDF приводит пример: на модуле ESP32-WROVER вывод GPIO12 подтянут вверх снаружи и вниз внутри чипа, и через эту пару резисторов во сне течёт ток. Его убирают вызовом
rtc_gpio_isolate(GPIO_NUM_12)передesp_deep_sleep_start(). Так же изолируют другие выводы, к которым во сне подключена внешняя схема. - ext0 и ULP держат периферию RTC. С ext0 и с работающим ULP периферия RTC остаётся включённой, и ток выше, чем с одним таймером: по даташиту 150 мкА с ULP против 10 мкА.
- Флеш-память. По ESP-IDF
esp_deep_sleep_start()всегда выключает внешнюю SPI-флеш, так что о ней в глубоком сне можно не думать. В Light-sleep она по умолчанию остаётся включённой и тратит по ESP-IDF около 10–30 мкА. - Плата. Стабилизатор с большим собственным током, преобразователь USB–UART и светодиод питания потребляют больше самого чипа — для батарей их отключают или выбирают плату без них.
Пример: сколько проработает батарея
Устройство раз в минуту просыпается на 1 с, измеряет датчик без Wi-Fi на 80 МГц и снова засыпает. По даташиту в работе без радио это 20–31 мА, возьмём 25 мА, во сне — 10 мкА. Средний ток:
Батарея ёмкостью 2000 мА·ч при таком токе проработает около 4700 часов — больше полугода, если ток самой платы во сне действительно близок к табличному. Если же каждое пробуждение с подключением к Wi-Fi длится несколько секунд при сотне миллиампер, средний ток вырастет в разы — поэтому данные копят в RTC-памяти и отправляют пачкой.
Измерять напряжение батареи во сне умеет сопроцессор ULP, а о точности измерения — статья «АЦП ESP32». Какие выводы влияют на загрузку после пробуждения — strapping-выводы, остальные чипы Espressif — в разделе ESP32.
Частые вопросы
Сколько потребляет ESP32 в глубоком сне?
По даташиту Espressif — 10 мкА, когда работают только таймер RTC и RTC-память; с работающим сопроцессором ULP — 150 мкА, в режиме Hibernation — 5 мкА. Это ток самого чипа. Отладочная плата со стабилизатором, преобразователем USB–UART и светодиодом питания потребляет во сне больше, поэтому для батарейного устройства ток меряют на своей плате.
Как разбудить ESP32 кнопкой?
Через внешнее пробуждение ext0 или ext1 по одному из выводов RTC_GPIO: у ESP32 это GPIO0, 2, 4, 12–15, 25–27 и 32–39. Для ext0 задают один вывод и уровень, для ext1 — несколько выводов и условие: любой в единице или все в нуле. Подтяжку для кнопки включают функциями rtc_gpio_pullup_en или rtc_gpio_pulldown_en, как описано в ESP-IDF.
Почему после глубокого сна программа начинается сначала?
Потому что в глубоком сне процессоры и почти вся оперативная память выключены. По ESP-IDF после пробуждения выполняется короткий код wake stub, а затем загружается приложение — как после сброса. Переменные, которые нужно сохранить, помечают атрибутом RTC_DATA_ATTR: они хранятся в памяти RTC SLOW, которая во сне остаётся под питанием.
Сохраняется ли подключение к Wi-Fi в глубоком сне?
Нет. По ESP-IDF в режимах Deep-sleep и Light-sleep радио выключено, и соединения Wi-Fi и Bluetooth не сохраняются. После пробуждения устройство подключается заново. Если связь нужно держать, используют Modem-sleep и автоматический Light-sleep: драйвер Wi-Fi сам будит чип для приёма.
Источники
- Espressif. ESP32 Series Datasheet, v5.3 — разд. 4.3.1 — режимы Active, Modem-sleep, Light-sleep, Deep-sleep, Hibernation и что в них работает; табл. 4-2 — Modem-sleep 20–68 мА в зависимости от частоты, Light-sleep 0,8 мА, Deep-sleep 150 мкА с ULP, 100 мкА в режиме ULP-наблюдения при 1 %, 10 мкА с таймером RTC и RTC-памятью, Hibernation 5 мкА, выключение по CHIP_PU 1 мкА; табл. 5-4 — передача Wi-Fi до 240 мА, приём 95–100 мА; разд. 2 — выводы RTC_GPIO0–RTC_GPIO17
- Espressif. ESP-IDF Programming Guide (stable), ESP32: Sleep Modes — в Deep-sleep работают контроллер RTC, ULP и память RTC FAST и SLOW, процессоры, большая часть ОЗУ и цифровая периферия выключены; Wi-Fi и Bluetooth во сне не сохраняются; источники пробуждения: таймер, касание, ext0 (один RTC GPIO, RTC-периферия остаётся включённой), ext1 (несколько RTC GPIO, любой в единице или все в нуле, уровни одинаковые), ULP, GPIO в Light-sleep, UART в Light-sleep; esp_sleep_get_wakeup_cause; переменные RTC_DATA_ATTR в памяти RTC SLOW; после пробуждения выполняется wake stub и загружается приложение; esp_deep_sleep_start всегда выключает SPI-флеш; на ESP32-WROVER GPIO12 подтянут внешне вверх и внутри вниз — rtc_gpio_isolate(GPIO_NUM_12); без источников пробуждения чип спит до внешнего сброса
Нашли ошибку?
Смотрите также
- ESP32ESP32, S2, S3, C2, C3, C5, C6, H2, P4: ядра, радио, USB, GPIO — сравнение и выбор
- АЦП ESP32Каналы ADC1 и ADC2, ослабление, калибровка, нелинейность, Wi-Fi и analogRead
- Strapping-выводы ESP32Какие GPIO читаются при сбросе: загрузка, напряжение флеш-памяти, JTAG — для ESP32, S2, S3, C2, C3, C5, C6, H2, P4
- Режимы снаSleep mode: Idle, Power-down, пробуждение и ток
- RTCСчётчик времени в режимах сна: источники такта, счётчик и календарь
- Ток покояСобственное потребление стабилизатора, IQ