Энергосбережение (Sleep modes). Как сделать, чтобы робот не "жрал" батарею
Представьте: ваш робот-исследователь должен неделю работать в поле от одной зарядки. Он не может всё время быть активным. Он должен спать, просыпаться, сделать дело, и снова спать — как медведь зимой.
Почему это важно?
Без оптимизации:
- Arduino Uno всегда включен: 50 мА
- ESP32 с Wi-Fi: 100-200 мА
- Мобильный робот: 200-1000 мА
Батарея 2000 мАч проработает:
- 2000 мАч ÷ 200 мА = 10 часов (и это без моторов!)
С оптимизацией:
- Спящий режим: 0.01-0.1 мА
- Тот же робот: 99% времени спит
- Работает не 10 часов, а недели или месяцы!
1. Сначала упростите железо
Что “жрет” энергию в Arduino/ESP32:
Arduino Uno (50 мА = слишком много!):
• Светодиод "ON" (LED) → 2 мА
• Регулятор напряжения (LDO) → 8 мА
• USB-чип → 20 мА
• Сам микроконтроллер → 20 мА
ESP32 с Wi-Fi:
• Wi-Fi модуль → 80-200 мА!
• Bluetooth → 50-100 мА
• Основной процессор → 40 мА
Что делать:
Используйте голые платы:
- Arduino Pro Mini (без USB) вместо Uno
- ESP32-S2/S3 (лучше спят)
- ESP8266 (дешевле, меньше потребляет)
Отключайте ненужное:
// Отключить синий светодиод на ESP32 pinMode(2, OUTPUT); digitalWrite(2, LOW); // Отключить неиспользуемые пины pinMode(неиспользуемый_пин, INPUT_PULLDOWN);Снижайте частоту процессора:
// ESP32: снижение частоты с 240 МГц до 80 МГц setCpuFrequencyMhz(80); // Потребление упадет на 30-40%
2. Режимы сна микроконтроллеров
Сравнение режимов сна:
| Режим | Потребление | Что работает | Просыпается от |
|---|---|---|---|
| Активный | 50-200 мА | Всё | - |
| Idle (Дремота) | 10-20 мА | CPU спит, таймеры работают | Любое прерывание |
| Light Sleep | 1-5 мА | CPU и часть периферии спят | Таймер, кнопка |
| Deep Sleep | 0.01-0.1 мА | Только RTC/таймер | Таймер, кнопка, внешнее событие |
| Hibernation | 0.001-0.01 мА | Ничего, только ячейка памяти | Кнопка (перезагрузка) |
3. ESP32 Deep Sleep — самый эффективный
Как работает:
ESP32 выключает почти всё:
- Основной процессор
- Wi-Fi и Bluetooth
- Большинство датчиков
- Память (данные теряются!)
Остается работать только:
- RTC (Real Time Clock) — сверхэкономичный таймер
- ULP-сопроцессор — может читать датчики даже во сне
Код для ESP32 Deep Sleep:
// ВАЖНО: После пробуждения код начнется СНАЧАЛА (с setup)!
#define TIME_TO_SLEEP 3600 // Спать 1 час (3600 секунд)
void setup() {
Serial.begin(115200);
Serial.println("Робот проснулся!");
// 1. СДЕЛАТЬ ВСЁ НУЖНОЕ (быстро!)
checkSensors();
sendDataIfNeeded();
makeDecision();
// 2. Настроить причину пробуждения
esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * 1000000);
// Можно добавить другие причины:
// • От кнопки: esp_sleep_enable_ext0_wakeup(GPIO_NUM_0, 0);
// • От датчика: esp_sleep_enable_ext1_wakeup(bitmask, режим);
// 3. Сохранить данные в RTC памяти (чтобы не потерялись)
RTC_DATA_ATTR int bootCount = 0;
bootCount++;
Serial.print("Это пробуждение №"); Serial.println(bootCount);
// 4. Уснуть
Serial.println("Иду спать... Zzz");
delay(100); // Дать время отправить сообщение
esp_deep_sleep_start();
}
void loop() {
// Сюда код НИКОГДА не дойдет!
// После esp_deep_sleep_start() ESP32 перезагружается
}
4. Arduino (AVR) Sleep Modes
Для Arduino нужна библиотека LowPower или avr/sleep.h.
Простой пример с кнопкой:
#include <LowPower.h>
void setup() {
pinMode(2, INPUT_PULLUP); // Кнопка для пробуждения
pinMode(LED_BUILTIN, OUTPUT);
}
void loop() {
// 1. Мигнуть светодиодом
digitalWrite(LED_BUILTIN, HIGH);
delay(100);
digitalWrite(LED_BUILTIN, LOW);
// 2. Измерить датчик
int sensorValue = analogRead(A0);
// 3. Отправить данные (если нужно)
if (sensorValue > 500) {
sendAlert();
}
// 4. СПАТЬ 8 СЕКУНД
// PowerDown: самый экономичный режим
// Проснется от прерывания на пине 2 (кнопка)
LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
// После пробуждения продолжится с этого места
}
Экономия на Arduino Pro Mini:
Без сна: 12 мА → 166 часов от батареи 2000 мАч
Со сном (1 сек активности в минуту): ~0.1 мА → 20 000 часов!
5. Стратегия “Проснись-Сделай-Усни”
Для робота-метеостанции:
Цикл:
1. Проснуться по таймеру (раз в час)
2. Измерить температуру, влажность, давление (5 секунд)
3. Отправить данные по LoRa (10 секунд)
4. Уснуть на 1 час
Потребление:
• Сон: 0.01 мА × 3599 секунд = 0.01 мАч
• Активность: 50 мА × 15 секунд = 0.2 мАч
• Итого за час: 0.21 мАч
• Батарея 2000 мАч: 2000 ÷ 0.21 ≈ 9523 часа ≈ 397 дней!
Для робота-охранника:
Цикл:
1. Спать в Deep Sleep
2. Проснуться от датчика движения (PIR)
3. Включить камеру, сделать снимок
4. Отправить фото по Wi-Fi
5. Сразу уснуть
Потребление:
• 99.9% времени: 0.01 мА (сон)
• 0.1% времени: 200 мА (фото + отправка)
• Работает от Power Bank 20000 мАч: 1-2 месяца
Практические примеры для школы
Проект 1: Робот-часовой для кабинета
Задача: Следить, чтобы дверь не открывали после уроков
Решение:
• ESP32 + датчик двери (геркон)
• ESP32 спит в Deep Sleep
• При открытии двери — просыпается, включает сирену
• Работает от 2x 18650: 3-6 месяцев
Код:
void setup() {
// Настроить пробуждение от датчика на пине 4
esp_sleep_enable_ext0_wakeup(GPIO_NUM_4, 0); // 0 = LOW
// Проверить, почему проснулись
if (esp_sleep_get_wakeup_cause() == ESP_SLEEP_WAKEUP_EXT0) {
// Дверь открыли!
soundAlarm();
sendNotification();
}
// Снова спать
esp_deep_sleep_start();
}
Проект 2: Метеостанция для школьного стадиона
Задача: Каждый час измерять погоду
Решение:
• ESP32 + датчики BME280
• Отправка данных раз в час по Wi-Fi
• Между измерениями — Deep Sleep
• Работает от солнечной панели + аккумулятор
Проект 3: Робот для соревнований с кнопкой
Задача: Робот должен ждать сигнала, но не сажать батарею
Решение:
• Всё время спит в Light Sleep
• При нажатии кнопки "СТАРТ" — просыпается и едет
• После финиша — снова спит
Частые ошибки и решения
Ошибка 1: “После сна всё сбрасывается”
Проблема: Данные теряются
Решение: Использовать RTC_DATA_ATTR для ESP32 или EEPROM
Ошибка 2: “Робот не просыпается”
Проблема: Неправильно настроено прерывание
Решение:
1. Проверить пины для пробуждения (не все подходят)
2. Для ESP32: только RTC_GPIO пины
3. Правильно настроить уровень сигнала
Ошибка 3: “Потребление в сне всё равно высокое”
Проблема: Что-то осталось включенным
Решение:
1. Отключить все светодиоды
2. Перевести неиспользуемые пины в INPUT_PULLDOWN
3. Отключить периферию (I2C, SPI, Serial)
Ошибка 4: “Слишком долго просыпается”
Проблема: ESP32 медленно поднимает Wi-Fi
Решение:
1. Не использовать Wi-Fi если не нужно
2. Использовать Light Sleep вместо Deep Sleep
3. Поднимать только необходимые сервисы
Эксперимент: Измерь потребление во сне
Что нужно:
- ESP32 Dev Board
- Мультиметр
- Резистор 10 Ом 1Вт
- Конденсатор 1000 мкФ
Шаги:
- Подключите в разрыв питания:
USB 5V ───[резистор 10Ω]─── ESP32 VIN ↓ Мультиметр (измеряет напряжение) - Загрузите программу:
void setup() { esp_sleep_enable_timer_wakeup(30 * 1000000); // 30 сек esp_deep_sleep_start(); } void loop() {} - Измерьте напряжение на резисторе:
- Напряжение 0.01V = ток 1 мА (0.01V ÷ 10Ω)
- Напряжение 0.001V = ток 0.1 мА
Вывод: Вы увидите, как мало ESP32 потребляет во сне!
Проверь себя
✅ Смогу ли я:
- Заставить ESP32 просыпаться раз в час и мигать светодиодом?
- Объяснить разницу между Deep Sleep и Light Sleep?
- Сделать робота, который работает 1 месяц от батареек?
- Выбрать правильный режим сна для метеостанции?
Если на все вопросы можете ответить — ваши роботы будут работать очень долго!
Что дальше?
Освоили режимы сна? Теперь можно:
- Мониторинг питания — как точно измерять потребление
- Солнечные панели — как сделать вечно работающего робота
- Оптимизация алгоритмов — как быстрее выполнять задачи, чтобы больше спать
Совет: Начните с самого простого — заставьте ESP32 мигать светодиодом раз в минуту, а 59 секунд спать. Измерьте потребление. Потом усложняйте. Помните: самый экономичный код — это тот, который не выполняется.
