Оптимизация энергопотребления LoRa

Последние несколько месяцев я работаю над уменьшением энергопотребления в проекте lora-at. Идея заключается в том, чтобы сделать энергонезависимый приёмник, положить его на балконе и 24/7 принимать сигналы со спутников. Легче сказать, чем сделать. Особенно для того, кто никогда не оптимизировал код по низкое энергопотребление и не проектировал электрические цепи. Конечно, можно поставить самую большую солнечную панель, принимать сигналы только днём и не заморачиваться. Но мне такой подход показался недостойным звания инженера, поэтому я принял вызов и принялся проектировать.

Общая схема

Прежде чем оптимизировать энергопотребление, необходимо понять электрическую схему работы и алгоритм программы.

Солнечная
панель 6В
Солнечная панель 6В
Контроллер
Контроллер
Батарея 3.7В
Батарея 3.7В
ESP32
ESP32
JST коннектор
JST коннектор
Делитель
напряжения
Делитель напряжения
Уровень
заряда
батареи
Уровеньзарядабатареи...
Text is not SVG - cannot display

Принцип работы достаточно простой:

  • Солнечная панель 6В подключается к специальному контроллеру
  • Этот контроллер должен делать следующее:
    • заряжать батарею
    • следить за напряжением зарядки и уровнем разрядки батареи
    • отключать батарею от нагрузки при сильной разрядке
    • следить за током потребления с солнечной панели (MPTT)
  • Li-ion батарея должна работать ночью, когда солнца нет и панель не вырабатывает достаточно энергии.
  • ESP32 плата с приёмником LoRa
  • (Опционально) делитель напряжения для мониторинга заряда батареи.

Поскольку схема достаточно стандартная, то в интернете можно найти множество разлиичных гидов и описаний.

Алгоритм работы программы

С программной частью дела на такие радужные и что-то сложнее, чем “hello world” найти очень сложно. Основным и единственным способом уменьшить энергопотребление - это переход процессора в режим глубокого сна (deep sleep). При этом отключается большинство модулей процессора и энергопотребление минимально - 10 микроампер.

При этом обычная линейная программа в таком режиме полностью меняется. Я пришёл к следующему алгоритму:

Получить
время наблюдения
Получитьвремя наблюдения...
Выход из
сна?
Выход из...
Настало время
наблюдения?
Настало время...
Ожидать команду
Ожидать команду
Перейти в режим сна
Перейти в режим сна
Таймер 
неактивности?
Таймер...
Запустить приёмник LoRa
Запустить приёмник LoRa
Наблюдение
завершено?
Наблюдение завершено?
Нет
Нет
Нет
Нет
Нет
Нет
Нет
Нет
Да
Да
Да
Да
Да
Да
Да
Да
Сообщение
получено?
Сообщение получено?
Отправить по 
bluetooth
Отправить по...
Да
Да
Нет
Нет
Text is not SVG - cannot display

Во-первых, мне нужно, чтобы прошивка поддерживала как работу в режиме глубокого сна, так и через AT команды. Они крайне удобны для отладки. Однако, в режиме глубокого сна последовательная шина недоступна. Чтобы это обойти я создал специальный таймер неактивности. Если в течении некоторого времени нет команд, то процессор переходит в режим глубокого сна. В этом режиме он периодически просыпается, получает по bluetooth время следующего наблюдения и уходит в спячку. Поскольку цикл бодрствования достаточно короткий, то успеть послать AT команду практически нереально. Чтобы послать AT команду устройству в режиме глубокого сна, нужно подойти и перезагрузить ESP32 вручную. Это немного неудобно, но с этим можно жить во время отладки. Либо на время отключить режим глубокого сна.

Во-вторых, используется bluetooth для связи с RaspberryPI. Этот протокол не самый энергоэффективный и логичнее было бы использовать тот же LoRa, чтобы отправлять данные. Но, к сожалению, в RaspberryPI нет модуля LoRa. А отдельный стоит достаточно дорого. Хорошая новость заключается в том, что и ESP32 и RaspberryPI поддерживают энергоэффективную версию bluetooth - bluetooth low energy (BLE), которую логично использовать. Интеграция по bluetooth заслуживает отдельную статью.

Измерение энергопотребления

В этот момент меня настигли вайбы лабораторных работ по физике в университете. За одним исключением - на этот раз мне действительно интересно узнать физику процесса. Для измерений я использовал USB тестер A3-B, который обозревал в одной из предыдущих статей. Результаты получились следующие:

  • в режиме глубокого сна - 6 мА
  • в режиме приёма сигнала - 86 мА

В среднем за день все спутники с LoRa передатчиком пролетают за 313 минут. Тогда всё остальное время глубокого сна будет 1127 минут. Итого:

323 мин * 86 мА + 1127 мин * 6 мА = 575.66 мАч

Или в пересчёте на мощность:

575.66 мАч * 3.3 В = 1.8997 Втч

1.8997 Втч потребления за сутки. Не очень понятно - это много или мало. Чтобы это понять, надо оценить теоретическую мощность, которую можно получить от солнечных панелей.

Теоретическая мощность

В этом видео очень хорошо объяснено, как посчитать теоретическую мощность от солнечных панелей. В моём случае входные параметры следующие:

  • город - Лондон
  • солнечная панель 6В 1Вт площадью 11см * 6см. Да, я взял самую маленькую солнечную панель на 6В. Зато 3 штуки по скидке.
  • условная эффективность таких панелей - 15%
  • эффективность контроллера и понижения напряжения будем считать ещё 5%
  • направление панели - строго вверх
  • месяц - декабрь. Самый пасмурный месяц в году с минимальной продолжительностью солнечного дня.

Итого:

600 Втч/м2 * (15% - 5%) = 60 Втч/м2 = 0.006 Втч/см2

В пересчёта на мою солнечную панель:

0.006 Втч/см2 * (11см * 6см) = 0.396 Втч

Расчёты крайне усреднённые и в один солнечный день может быть в два раза больше энергии, а в другой день - в два раза меньше. Тем не менее получается, что моей солнечной панели не хватит ( 0.396 Втч < 1.8997 Втч ).

Раз на целый день не хватит, то может быть на чуть-чуть хватит? Для этого я открыл вот этот сайт посмотреть сколько теоретически я могу получить энергии с разбивкой по часам.

Итак, в 12 дня я смогу получить 221 Втч/м2.

221 Втч/м2 * (15% - 5%) = 22.1 Втч/м2 = 0.00221 Втч/см2 * (11см * 6см) = 0.14586 Втч

А среднее потребление ESP32:

1.8997 Втч / 24 = 0.07915 Втч

Получается, что энергии будет хватать. Таким образом вся станция будет запускаться часов в 11-12, работать от силы час или два и выключаться до следующего дня. Батарея при этом будет постоянно находится в разряженном состоянии и лишь немного заряжаться на 0.06671 Вт, чтобы потом опять разрядится.

Оптимизация энергопотребления

Самые очевидные способы, которые приходят в голову без google:

  • подключить ещё одну маленькую панель. 0.396 Втч * 2 = 0.792Втч - тоже не ахти.
  • переехать в Дубай
  • уменьшить количество наблюдений спутников
  • оптимизировать код

Третий и четвёртый пункты выглядят очень заманчиво. Итак, если оставить только одно наблюдение в день:

10 мин * 86 мА + 1430 мин * 6 мА = 860 мАмин + 8580 мАмин = 157.33 мАч * 3.3В = 519.2 Втч

То есть даже для одно наблюдения в день одной солнечной панели будет недостаточно. Нужно как минимум две.

Пришло время оптимизировать код.

Оптимизация кода

В таблице ниже я собрал все техники, которые смог найти в интернете.

Метод Потребление
По-умолчанию пустой проект 70мА
Включённый LoRa приёмник 86мА
Пустой проект с пониженной частотой - 80Мгц
Минимальная частота для работы bluetooth
30мА
Включённый LoRa приёмник с пониженной частотой ESP32 46мА
Глубокий сон 6мА
Использовать питание через JST коннектор, а не 5В USB Видимо токи маленькие и померить мультиметром не получится
Включённый LoRa приёмник с ESP32 в глубоком сне 16мА

Итак, самый интересный метод - последний. Я случайно наткнулся на него в этой статье. Дело в том, что ESP32 может выходить из глубокого сна с помощью нескольких способов - по таймеру, по изменению напряжения на внешнем пине, либо по прерыванию. При этом, когда приёмник LoRa получает сообщение, он тоже генерирует прерывание! Алгоритм работы в таком случае следующий:

Получить
время наблюдения
Получитьвремя наблюдения...
Выход из
сна?
Выход из...
Настало время
наблюдения?
Настало время...
Ожидать команду
Ожидать команду
Перейти в режим сна
Перейти в режим сна
Таймер 
неактивности?
Таймер...
Запустить приёмник LoRa
Запустить приёмник LoRa
Наблюдение
завершено?
Наблюдение завершено?
Нет
Нет
Нет
Нет
Нет
Нет
Нет
Нет
Да
Да
Да
Да
Да
Да
Да
Да
Сообщение
получено?
Сообщение получено?
Отправить по 
bluetooth
Отправить по...
Да
Да
Нет
Нет
Выход по
прерыванию?
Выход по...
Нет
Нет
Обработать
прерывание
Обработать прерывание
Восстановить
статус 
приемника
Восстановитьстатус...
Text is not SVG - cannot display

Соответствующая конфигурация:

pinMode(RST, INPUT_PULLUP);
esp_sleep_enable_ext0_wakeup((gpio_num_t)DIO0, RISING);

Приёмник LoRa продолжит работать, даже если ESP32 уходит в спящий режим. Потребление в активном режиме сократится с 86мА до 16мА - больше, чем в 5 раз!

323 мин * 16 мА + 1127 мин * 6 мА = 5168 мАмин + 6762 мАмин =
= 198.83 мАч * 3.3В = 656.15 Втч

Двух маленьких панелей будет достаточно, чтобы принять все пролетающие спутники.

К сожалению, ни одна из существующих библиотек не позволяет прочитать сообщение из LoRa после выхода из сна. Мне пришлось взять arduino-LoRa и модифицировать её.

Послесловие

А потом я вышел на балкон и понял, что он выходит на север…