Добрый день, уважаемый читатель. В прошлой статье, посвященной OTA обновлениям в ESP-IDF, я упоминал, что так же легко и просто можно реализовать подобный механизм и в фреймворке Arduino. И в этой статье я расскажу как это сделать для ESP8266 и Arduino IDE или PlatformIO.
Сразу скажу, что если вы читали предыдущую статью, то следующие две части можете смело пропускать – это простая копипаста с предыдущей статьи, предназначенная только для тех, кто будет читать данную статью первой (или только эту). Можете смело переходить к разделу выбора разметки Flash.
Что такое ОТА?
OTA — это обновление устройств, которое устанавливается при помощи Wi-Fi соединения или мобильного интернета (в случае со смартфонами). Аббревиатура OTA произошла от английского «Over the Air», а еще раньше это называлось «Firmware Over The Air» — что в переводе с английского означает «микропрограмма по воздуху».
Согласитесь, что намного удобнее обновлять “прошивки” умных устройств удаленно, без необходимости физического подключения кабелем к плате микроконтроллера. Особенно если это устройство установлено где-то глубоко в недрах кухонной вытяжки или, например, на чердаке. А особенно удобно обновлять (и добавлять новые функции, кстати) устройства, которые вообще находятся “за тридевять земель” и возможности физического подключения к ним нет вообще.
В общем с какой стороны не глянь – одни плюсы. Но на самом деле это не так, минусы то же имеются. Обо всем этом и поговорим в данной статье.
Способы доставки ОТА-обновлений
Чтобы использовать технологию ОТА-обновлений, необходимо как минимум скомпилировать исходники и “доставить” полученный двоичный файл с прошивкой непосредственно на устройство. Я знаю как минимум два способа доставки бинарного файла на устройства:
- Отправить файл с прошивкой напрямую на устройство, используя предварительно открытый специальный порт на устройстве. Вроде бы удобно, но этот способ можно использовать только в локальной сети. И возникает необходимость постоянно держать открытым порт на устройстве и мониторить его. Насколько я помню, этот способ реализован в Arduino IDE.
- Использовать промежуточный сервер в сети интернет. В этом случае файл с прошивкой предварительно загружается на этот сервер (например хостинг). Затем устройству отправляется прямая ссылка на загруженный файл любым удобным способом – через MQTT, telegram, web-интерфейс. Либо запускаем процесс обновления по расписанию и т.д. и т.п. В этом случае обновление можно “доставить” на целевое устройство в любую точку планеты, где есть интернет.
Следует учитывать, что файл с прошивкой должен быть размещен на таком ресурсе, где он доступен для скачивания по прямой ссылке. Яндекс Диск, Google Disk, Dropbox для этих целей не подойдут, так как ссылка на файл в этом случае ведёт не на сам файл, а на промежуточную страницу!
Есть и ещё способы отправить прошивку на устройство с использованием сторонних сервисов, но я ими не пользовался.
Я использую второй способ (с использованием промежуточного сервера), используя в качестве него виртуальный хостинг, на котором расположен мой сайт. И именно про этот способ пойдет речь в этой статье.
Подготовка разметки flash-памяти
Прежде чем начинать эксперименты с OTA-обновлениями, необходимо соответствующим образом подготовить разметку flash-памяти устройства.
Для того, чтобы механизм OTA работал, нам потребуется два раздела под хранения прошивок:
- С одного раздела запускается устройство в текущий момент, этот раздел называется активным.
- В другой раздел (неактивный) может записываться новая прошивка при получении её через OTA без риска нарушения работоспособности текущей прошивки.
Для ESP32 можно создавать произвольные таблицы разметки памяти, но для ESP8266 такой возможности нет. Можно использовать только готовые варианты разметки в виде ld-скриптов. Список доступных к использованию вариантов разметки flash-памяти вы можете найти здесь: esp8266/Arduino/tree/master/tools/sdk/ld.
Соответственно, нам требуется активировать разметку, которая будет содержать искомые два OTA-раздела. Как это сделать?
Arduino IDE
В Arduino IDE выбор разметки flash осуществляется очень просто: Инструменты -> Flash size -> выберите один из вариантов с OTA разделами, который подходят именно вам:

Выбор размера OTA-разделов в Arduino IDE
В зависимости от выбранного варианты размер OTA разделов будет разный, выбирайте вариант, в который “влезет” весь созданный вами код. На этом подготовку разделов памяти для Arduino IDE можно считать законченной.
VS Code + PlatformIO
В PlatformIO выбор разметки flash-памяти осуществляется, как всегда, через файл настройки проекта platformio.ini. Для этого добавьте в него следующую строку:
Как видите, это не намного сложнее чем в Arduino IDE, нужно лишь правильно выбрать нужный ld скрипт. Список доступных вариантов вы можете найти здесь: github.com/esp8266/Arduino.
Код загрузки новой прошивки через HTTPS
Для того, чтобы задействовать библиотеку HTTP-обновлений в вашем проекте, необходимо её подключить:
#include <ESP8266httpUpdate.h>
Ни в Arduino IDE, ни в PlatformIO ничего дополнительно скачивать и устанавливать не требуется, это системная библиотека, включенная в framework Arduino для ESP8266.
Далее напишем функцию, которая будет принимать на вход ссылку на бинарник с новой прошивкой и запускать обновление. Она ещё проще, чем для ESP32 и ESP-IDF:
Ничего хитрого в ней нет – объявляем локальную переменную на “безопасный” wifi клиент и запускаем с помощью него обновление, передав ссылку. Если обновление пройдет успешно, микроконтроллер будет автоматически перезагружен.
Впрочем, можно обойтись и без функции, но это на ваш вкус.
Где взять двоичный файл с прошивкой
Где взять двоичный файл с прошивкой, который будет отправлять на устройство?
Для ArduinoIDE существует специальная команда “Экспорт бинарного файла”, которая как раз и предназначена для получения двоичного файла прошивки:
Файл после этого вы найдете прямо в каталоге с вашим скетчем.
Для PlatformIO необходимо скомпилировать проект командой build, а затем найти файл %prj_dir%\.pio\build\%prj_obj%\firmware.bin, где:
- firmware.bin – это и есть тот самый файл с прошивкой
- %prj_dir% – каталог проекта, то есть тот каталог, в котором расположен файл platfromio.ini
- %prj_obj% – название секции устройства в platfromio.ini, для которого производится компиляция, например nodemcuv2
Затем двоичный файл нужно любым способом загрузить на доступный вам HTTPS-ресурс и получить прямую ссылку на него. Это зависит от используемого сервера, поэтому здесь не может быть общих рекомендаций.
Отправляем уведомление на устройство о том, что нужно обновиться
Теперь нужно любым удобным способом оповестить устройство о том, что нужно скачать новую прошивку. Сделать это можно следующими способами:
- Можно обновлять прошивку из одного и того же сервера и каталога один раз в сутки или в неделю и т.д. В этом случае вы заранее прошиваете в устройство путь к файлу прошивки и расписание обновления, а потом устройство самостоятельно обновляется без вашего участия.
- Отправить ссылку на файл через MQTT сервер в заранее определенный топик, например device/ota. Получив сообщение в этом топике, устройство понимает, что нужно обновить прошивку немедленно. Я предпочитаю именно этот способ.
- Создать web-интерфейс на вашем устройстве и добавить поле для ввода ссылки на новую прошивку и кнопку для запуска обновления.
- Отправить ссылку на файл через telegram-бота или любой другой канал связи (mail например).
Как я уже написал, я предпочитаю использовать проверенный способ – через MQTT, чем и займемся далее. Я использую скетч, написанный для одной из предыдущих статей, и просто добавлю в него функции ОТА-обновления.
Телеметрия на Arduino и ESP8266. Создание проекта с MQTT управлением в среде PlatformIO
Возьмём скетч, написанный для предыдущей статьи, и доработаем его:
- Во первых добавим функцию, что я привёл выше.
- Во вторых объявим необходимые константы:
- Затем добавим код подписки на этот топик сразу после подключения к брокеру:
- Ну и добавим чуть-чуть кода в функцию обработки входящих сообщений с сервера:
Вот, собственно и все доработки проекта. Все готово.
В первый раз придется залить все эти доработки в микроконтроллер по кабелю.
Как всем этим пользоваться?
1. Скомпилировать проект и получить двоичный (бинарный) файл с кодом прошивки, как описано выше.
2. Загрузить файл на любой HTTP-сервер в сети интернет, например на хостинг. Следует учитывать, что файл с прошивкой должен быть размещен на таком ресурсе, где он доступен для скачивания по прямой ссылке. Яндекс Диск, Google Disk, Dropbox для этих целей не подойдут, так как ссылка на файл в этом случае ведёт не на сам файл, а на промежуточную страницу!
3. После загрузки файла на сервер получить https-ссылку на него и отправить её в топик device/ota, например с использованием MQTT Explorer или любым другим удобный способом.
4. Дождаться перезагрузки устройства. Enjoy!
Не всегда обновление проходит с первого раза. Иногда, особенно при высокой загруженности канала связи, на это требуется несколько попыток. поэтому есть смысл обернуть обновление в цикл из 3-10 итераций.
Перед обновлением отключите реле, управляющее нагрузкой
ОТА – обновление – штука медленная. И иногда не предсказуемая. Устройство может зависнуть или начать спонтанно перезагружаться. Не часто, но такое вполне возможно. Как правило это происходит либо из-за проблем в прошивке, которые вы же сами и допустили; либо из-за очень медленного и загруженного канала связи.
Поэтому после того, как вы получили ссылку на файл обновления – приостановите все критичные процессы. Отключите нагрузку, которой управляет устройство. В общем, примите все необходимые меры, дабы предотвратить неожиданные и аварийные ситуации в случае зависания устройства, например.
Ссылки
Пример проекта с использованием ОТА-механизма вы можете найти здесь: arduino/arduino_eps8266_ota
Благодарю за внимание!