Skip to main content

Энергосбережение (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 мА

Что делать:

  1. Используйте голые платы:

    • Arduino Pro Mini (без USB) вместо Uno
    • ESP32-S2/S3 (лучше спят)
    • ESP8266 (дешевле, меньше потребляет)
  2. Отключайте ненужное:

    // Отключить синий светодиод на ESP32
    pinMode(2, OUTPUT);
    digitalWrite(2, LOW);
    
    // Отключить неиспользуемые пины
    pinMode(неиспользуемый_пин, INPUT_PULLDOWN);
    
  3. Снижайте частоту процессора:

    // ESP32: снижение частоты с 240 МГц до 80 МГц
    setCpuFrequencyMhz(80);
    // Потребление упадет на 30-40%
    

2. Режимы сна микроконтроллеров

Сравнение режимов сна:

РежимПотреблениеЧто работаетПросыпается от
Активный50-200 мАВсё-
Idle (Дремота)10-20 мАCPU спит, таймеры работаютЛюбое прерывание
Light Sleep1-5 мАCPU и часть периферии спятТаймер, кнопка
Deep Sleep0.01-0.1 мАТолько RTC/таймерТаймер, кнопка, внешнее событие
Hibernation0.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 мкФ

Шаги:

  1. Подключите в разрыв питания:
    USB 5V ───[резистор 10Ω]─── ESP32 VIN
           Мультиметр (измеряет напряжение)
    
  2. Загрузите программу:
    void setup() {
      esp_sleep_enable_timer_wakeup(30 * 1000000); // 30 сек
      esp_deep_sleep_start();
    }
    void loop() {}
    
  3. Измерьте напряжение на резисторе:
    • Напряжение 0.01V = ток 1 мА (0.01V ÷ 10Ω)
    • Напряжение 0.001V = ток 0.1 мА

Вывод: Вы увидите, как мало ESP32 потребляет во сне!


Проверь себя

Смогу ли я:

  1. Заставить ESP32 просыпаться раз в час и мигать светодиодом?
  2. Объяснить разницу между Deep Sleep и Light Sleep?
  3. Сделать робота, который работает 1 месяц от батареек?
  4. Выбрать правильный режим сна для метеостанции?

Если на все вопросы можете ответить — ваши роботы будут работать очень долго!


Что дальше?

Освоили режимы сна? Теперь можно:

Совет: Начните с самого простого — заставьте ESP32 мигать светодиодом раз в минуту, а 59 секунд спать. Измерьте потребление. Потом усложняйте. Помните: самый экономичный код — это тот, который не выполняется.