1. Режимы глубокого сна в ESP32
ESP32 предлагает три основных режима энергосбережения:
Режим | Потребление | Что отключено? | Как можно разбудить? |
---|---|---|---|
Modem Sleep | ~20 mA | Wi-Fi/BT | Любое прерывание |
Light Sleep | ~0.8 mA | CPU, периферия | Таймер, GPIO, UART |
Deep Sleep | ~5–150 µA | CPU, Wi-Fi/BT, RAM | Таймер, TouchPad, EXT0/EXT1, ULP-процессор |
Deep Sleep — самый экономичный режим, при котором:
-
Отключается основной процессор (CPU).
-
Очищается оперативная память (RAM) (сохраняются только RTC-регистры).
-
Работает только RTC-блок (для пробуждения).
-
ULP-процессор (Ultra Low Power) может работать и мониторить датчики.
2. Как включить Deep Sleep на ESP32
2.1. Пробуждение по таймеру (через esp_sleep_enable_timer_wakeup
)
Микроконтроллер просыпается через заданное время (в микросекундах).
#include <esp_sleep.h> void setup() { Serial.begin(115200); Serial.println("ESP32 в Deep Sleep на 10 секунд..."); // Настройка пробуждения по таймеру (в микросекундах) esp_sleep_enable_timer_wakeup(10 * 1000000); // 10 секунд // Переход в Deep Sleep esp_deep_sleep_start(); } void loop() {} // Не используется в Deep Sleep
2.2. Пробуждение по кнопке (EXT0 / EXT1)
-
EXT0 — пробуждение по одному пину (например, кнопка на GPIO2).
-
EXT1 — пробуждение по нескольким пинам (логическое ИЛИ/И).
Пример (пробуждение по GPIO2):
#include <esp_sleep.h> void setup() { Serial.begin(115200); Serial.println("ESP32 в Deep Sleep. Нажмите кнопку на GPIO2 для пробуждения."); // Настройка пробуждения по GPIO2 (HIGH-уровень) esp_sleep_enable_ext0_wakeup(GPIO_NUM_2, HIGH); // Переход в Deep Sleep esp_deep_sleep_start(); } void loop() {} // Не используется
2.3. Пробуждение по сенсору TouchPad
ESP32 может просыпаться от прикосновения к сенсорным пинам (TouchPad).
#include <esp_sleep.h> #include <driver/touch_pad.h> void setup() { Serial.begin(115200); Serial.println("ESP32 в Deep Sleep. Коснитесь TouchPad для пробуждения."); // Настройка TouchPad (например, GPIO4 - Touch0) touch_pad_init(); touch_pad_config(TOUCH_PAD_NUM0); // Touch0 на GPIO4 // Настройка пробуждения по TouchPad esp_sleep_enable_touchpad_wakeup(); // Переход в Deep Sleep esp_deep_sleep_start(); } void loop() {} // Не используется
2.4. Пробуждение от ULP-процессора
ULP (Ultra Low Power) — сопроцессор, который может работать в Deep Sleep и будить ESP32 по событию (например, по данным с датчика).
#include <esp_sleep.h> #include <driver/rtc_io.h> #include <ulp_main.h> // Требуется прошивка ULP extern const uint8_t ulp_main_bin_start[] asm("_binary_ulp_main_bin_start"); extern const uint8_t ulp_main_bin_end[] asm("_binary_ulp_main_bin_end"); void setup() { Serial.begin(115200); Serial.println("ESP32 в Deep Sleep. ULP может разбудить."); // Загрузка программы ULP ulp_load_binary(0, ulp_main_bin_start, (ulp_main_bin_end - ulp_main_bin_start)); // Настройка пробуждения от ULP esp_sleep_enable_ulp_wakeup(); // Переход в Deep Sleep esp_deep_sleep_start(); } void loop() {} // Не используется
3. Как сохранить данные между сном и пробуждением?
Поскольку в Deep Sleep ОЗУ очищается, нужно использовать:
-
RTC Slow Memory (сохраняется между циклами сна).
-
EEPROM (если нужно долговременное хранение).
-
Флеш-память (но это медленно и изнашивает память).
Пример сохранения переменной в RTC-память:
RTC_DATA_ATTR int bootCount = 0; // Сохраняется между пробуждениями void setup() { Serial.begin(115200); bootCount++; Serial.printf("Пробуждение #%d\n", bootCount); esp_sleep_enable_timer_wakeup(5 * 1000000); // 5 секунд esp_deep_sleep_start(); } void loop() {}
4. Потребление энергии в Deep Sleep
Режим | Потребление (µA) | Условия |
---|---|---|
Deep Sleep | 5–150 µA | В зависимости от пробуждения |
Light Sleep | 800 µA | CPU остановлен |
Modem Sleep | 20 mA | Wi-Fi/BT отключены |
Как снизить потребление?
-
Отключите неиспользуемые GPIO (
rtc_gpio_isolate()
). -
Убедитесь, что питание датчиков отключено.
-
Используйте ULP-процессор вместо основного CPU.
5. Вывод
ESP32 гораздо гибче ATmega2560 в плане энергосбережения:
-
Пробуждение по таймеру, кнопке, TouchPad, UART, ULP.
-
Можно сохранять данные в RTC-память.
-
Потребление в Deep Sleep — всего 5–150 мкА.
Если нужно максимально снизить энергопотребление, используйте Deep Sleep + ULP.
Если нужно быстро просыпаться, но экономить энергию — Light Sleep.
Хотите пример для конкретного сценария? Уточните задачу — помогу настроить! 🚀
Deep Sleep + ULP
1. Что такое ULP-процессор?
-
ULP — это сверхэкономичный сопроцессор, работающий даже в Deep Sleep.
-
Потребляет ~10–150 мкА (в зависимости от частоты и задач).
-
Может:
-
Читать аналоговые (ADC) и цифровые (GPIO) сигналы.
-
Работать с RTC-памятью (сохранение данных между пробуждениями).
-
Будить основной CPU по событию (например, при превышении порога датчика).
-
2. Как настроить Deep Sleep + ULP?
2.1. Необходимые компоненты
-
Прошивка ULP (пишется на ассемблере или через макросы).
-
Загрузчик ULP в основной код ESP32.
-
Настройка пробуждения от ULP.
2.2. Пример: ULP + ADC (чтение датчика)
Шаг 1: Создаем прошивку ULP (ассемблер)
Создаем файл ulp_adc.S
:
/* ulp_adc.S - чтение ADC1 (канал 6, GPIO34) */ #include "soc/rtc_cntl_reg.h" #include "soc/soc_ulp.h" .bss /* Сегмент неинициализированной памяти */ .global adc_reading /* Переменная для хранения значения ADC */ .text /* Сегмент кода */ .global entry /* Точка входа */ entry: move r3, 0 /* Счетчик (опционально) */ /* Чтение ADC1 (канал 6 - GPIO34) */ adc r1, 0, 6 // r1 = adc1_channel6 (0-8191 при 12 битах) /* Сохраняем значение в RTC-память */ move r0, adc_reading // Адрес переменной st r1, r0, 0 // Сохраняем значение ADC /* Будим основной CPU */ wake /* Завершаем работу ULP (если не будим) */ halt
→ Скомпилируйте этот код в бинарный файл (ulp-adc.bin
).
Шаг 2: Загрузка ULP в ESP32 (Arduino/PlatformIO)
#include <esp_sleep.h> #include <driver/rtc_io.h> #include <ulp_main.h> // Автогенерируется при компиляции // Объявления для бинарника ULP extern const uint8_t ulp_main_bin_start[] asm("_binary_ulp_adc_bin_start"); extern const uint8_t ulp_main_bin_end[] asm("_binary_ulp_adc_bin_end"); RTC_DATA_ATTR uint32_t adc_value; // Переменная для хранения ADC void setup() { Serial.begin(115200); // Загрузка программы ULP ulp_load_binary(0, ulp_main_bin_start, (ulp_main_bin_end - ulp_main_bin_start) / sizeof(uint32_t)); // Запуск ULP ulp_run(&ulp_entry - RTC_SLOW_MEM); // Настройка пробуждения от ULP esp_sleep_enable_ulp_wakeup(); Serial.println("Переход в Deep Sleep + ULP..."); esp_deep_sleep_start(); // Уходит в сон } void loop() {} // Не используется
Шаг 3: Чтение данных после пробуждения
Добавьте в setup()
перед сном:
if (esp_sleep_get_wakeup_cause() == ESP_SLEEP_WAKEUP_ULP) { Serial.printf("Пробуждение от ULP! ADC value: %d\n", adc_value); }
2.3. Пример: ULP + GPIO (мониторинг кнопки)
Если нужно мониторить цифровой сигнал (например, кнопку):
/* ulp_gpio.S - мониторинг GPIO2 (кнопка) */ #include "soc/rtc_io_reg.h" #include "soc/soc_ulp.h" .set gpio_num, 2 /* GPIO2 */ .bss .global button_pressed .text .global entry entry: /* Настройка GPIO2 как входа */ WRITE_RTC_REG(RTC_GPIO_ENABLE_W1TC_REG, RTC_GPIO_ENABLE_W1TC_S + gpio_num, 1, 1) /* Чтение GPIO2 */ READ_RTC_REG(RTC_GPIO_IN_REG, RTC_GPIO_IN_NEXT_S + gpio_num, 1) move r1, r0 /* Если GPIO2 = LOW (кнопка нажата) */ jumpr on_press, 1, lt /* Иначе - спать */ halt on_press: move r0, button_pressed move r1, 1 st r1, r0, 0 wake halt
→ Аналогично загружаем в ESP32 и настраиваем пробуждение.
3. Оптимизация энергопотребления
-
Отключите все лишние GPIO:
rtc_gpio_isolate(GPIO_NUM_2); // Отключает GPIO2
-
Уменьшите частоту ULP:
ulp_set_wakeup_period(0, 100000); // 100 мс между запусками ULP
-
Используйте RTC-память вместо глобальных переменных:
RTC_DATA_ATTR int sensor_data[10];
4. Потребление энергии
Режим | Потребление (µA) | Условия |
---|---|---|
Deep Sleep + ULP (ADC) | ~120 µA | Чтение ADC каждые 100 мс |
Deep Sleep + ULP (GPIO) | ~50 µA | Мониторинг кнопки |
Pure Deep Sleep | ~5 µA | Без ULP |
5. Плюсы и минусы ULP
✅ Плюсы:
-
Крайне низкое энергопотребление.
-
Возможность мониторинга датчиков без включения CPU.
❌ Минусы:
-
Ограниченный набор команд (ассемблер).
-
Нет доступа к Wi-Fi/Bluetooth.
6. Вывод
Deep Sleep + ULP — идеальное решение для батарейных проектов, где нужно:
-
Долгое время работы (месяцы/годы от батареи).
-
Периодический опрос датчиков (температура, влажность, кнопки).
Если нужно сложное поведение, но с экономией энергии, рассмотрите Light Sleep.