Оптимизация энергопотребления LoRa
Последние несколько месяцев я работаю над уменьшением энергопотребления в проекте lora-at. Идея заключается в том, чтобы сделать энергонезависимый приёмник, положить его на балконе и 24/7 принимать сигналы со спутников. Легче сказать, чем сделать. Особенно для того, кто никогда не оптимизировал код по низкое энергопотребление и не проектировал электрические цепи. Конечно, можно поставить самую большую солнечную панель, принимать сигналы только днём и не заморачиваться. Но мне такой подход показался недостойным звания инженера, поэтому я принял вызов и принялся проектировать.
Общая схема
Прежде чем оптимизировать энергопотребление, необходимо понять электрическую схему работы и алгоритм программы.
Принцип работы достаточно простой:
- Солнечная панель 6В подключается к специальному контроллеру
- Этот контроллер должен делать следующее:
- заряжать батарею
- следить за напряжением зарядки и уровнем разрядки батареи
- отключать батарею от нагрузки при сильной разрядке
- следить за током потребления с солнечной панели (MPTT)
- Li-ion батарея должна работать ночью, когда солнца нет и панель не вырабатывает достаточно энергии.
- ESP32 плата с приёмником LoRa
- (Опционально) делитель напряжения для мониторинга заряда батареи.
Поскольку схема достаточно стандартная, то в интернете можно найти множество разлиичных гидов и описаний.
Алгоритм работы программы
С программной частью дела на такие радужные и что-то сложнее, чем “hello world” найти очень сложно. Основным и единственным способом уменьшить энергопотребление - это переход процессора в режим глубокого сна (deep sleep). При этом отключается большинство модулей процессора и энергопотребление минимально - 10 микроампер.
При этом обычная линейная программа в таком режиме полностью меняется. Я пришёл к следующему алгоритму:
Во-первых, мне нужно, чтобы прошивка поддерживала как работу в режиме глубокого сна, так и через 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 получает сообщение, он тоже генерирует прерывание! Алгоритм работы в таком случае следующий:
Соответствующая конфигурация:
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 и модифицировать её.
Послесловие
А потом я вышел на балкон и понял, что он выходит на север…