ESP8266 NodeMCU OTA (Over-the-Air) обновления – библиотека ElegantOTA с Arduino IDE

В этом руководстве показано, как выполнять OTA (over-the-air) обновления плат ESP8266 NodeMCU с использованием библиотеки ElegantOTA (версия V3) в Arduino IDE. Эта библиотека настраивает веб-сервер, который позволяет обновлять прошивку (новый скетч) на вашей плате по беспроводной сети. Таким образом, вам не нужно подключение между ESP8266 и компьютером для загрузки нового скетча.

ESP8266 NodeMCU OTA (Over-the-Air) обновления -- библиотека ElegantOTA с Arduino IDE

К концу этого руководства вы сможете легко добавлять OTA-возможности в ваши проекты веб-серверов на ESP8266 для беспроводной загрузки новой прошивки в будущем.

Содержание

В этом руководстве мы рассмотрим:

Мы рекомендуем следовать всем шагам руководства, чтобы понять, как работает библиотека ElegantOTA и как её можно использовать в ваших проектах. Чтобы продемонстрировать, как это сделать, мы загрузим файлы для создания различных проектов веб-серверов.

ESP8266 OTA (Over-the-Air) программирование

OTA (Over-the-Air) обновление – это процесс загрузки новой прошивки на плату ESP8266 с использованием Wi-Fi соединения, а не последовательной связи. Эта функциональность чрезвычайно полезна в случае отсутствия физического доступа к плате ESP8266. Вам не нужно подключение между компьютером и платой для загрузки нового кода.

Как работает Async ElegantOTA веб-сервер ESP8266

Существуют различные способы выполнения OTA обновлений. В этом руководстве мы рассмотрим, как это сделать с использованием библиотеки ElegantOTA (версия V3 – это преемник устаревшей библиотеки AsyncElegantOTA). По нашему мнению, это один из лучших и самых простых способов выполнения OTA обновлений.

Библиотека ElegantOTA создаёт веб-сервер, к которому вы можете получить доступ в вашей локальной сети для загрузки новой прошивки или файлов в файловую систему (SPIFFS или LittleFS). Файлы, которые вы загружаете, должны быть в формате .bin. Позже в этом руководстве мы покажем, как преобразовать ваши файлы в формат .bin.

Единственный недостаток OTA программирования заключается в том, что вам нужно добавлять код для OTA в каждый скетч, который вы загружаете, чтобы иметь возможность использовать OTA в будущем. В случае библиотеки ElegantOTA это всего три строки кода.

Библиотека ElegantOTA

Логотип ElegantOTA

Вот некоторые замечательные возможности этой библиотеки:

  • Она совместима со встроенной библиотекой ESP8266WebServer.h и с несколькими форками библиотеки ESPAsyncWebServer.

  • Вам нужно добавить всего три строки кода, чтобы добавить OTA-возможности в ваш «обычный» веб-сервер;

  • Она позволяет обновлять не только новую прошивку на плате, но и файлы в файловой системе ESP8266 (LittleFS или SPIFFS);

  • Она предоставляет красивый и современный интерфейс веб-сервера;

  • Она доступна в платной Pro-версии, которая добавляет дополнительные возможности.

OTA обновления с библиотекой ElegantOTA – краткий обзор

Чтобы добавить OTA-возможности в ваши проекты с использованием библиотеки ElegantOTA, выполните следующие шаги:

1) Установите библиотеки ElegantOTA, ESPAsyncTCP и ESPAsyncWebServer;

2) Подключите библиотеку ElegantOTA в начале скетча Arduino:

#include <ElegantOTA.h>;

3) Добавьте следующую строку в setup перед server.begin();

ElegantOTA.begin(&server);

4) В loop() добавьте следующую строку:

ElegantOTA.loop();

5) Откройте браузер и перейдите по адресу http://<IPAddress>/update, где <IPAddress> – это IP-адрес вашего ESP8266, чтобы получить доступ к веб-странице для OTA обновлений.

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

Как работает OTA Web Updater?

Первый скетч должен быть загружен через последовательное соединение. Этот скетч должен содержать код для настройки OTA Web Updater, позволяющий загружать новые скетчи через веб-браузер.

OTA Web Updater создаёт веб-сервер, на который вы можете загружать скетчи по беспроводной сети.

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

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

Установка библиотеки ElegantOTA

Для установки библиотеки ElegantOTA в Arduino IDE перейдите в Sketch > Include Library > Manage Libraries, найдите ElegantOTA и установите ElegantOTA library by Ayush Sharma.

Установка библиотеки ElegantOTA в Arduino IDE

Включение асинхронного режима

Чтобы библиотека ElegantOTA работала в асинхронном режиме (с библиотекой ESPAsyncWebServer), вам нужно выполнить следующую процедуру.

1) Перейдите в директорию libraries вашего Arduino.

2) Откройте папку ElegantOTA, а затем откройте папку src.

3) Найдите макрос ELEGANTOTA_USE_ASYNC_WEBSERVER в файле ElegantOTA.h и установите его в 1 следующим образом:

#define ELEGANTOTA_USE_ASYNC_WEBSERVER 1
Включение асинхронного режима в библиотеке ElegantOTA

4) Сохраните изменения в файле ElegantOTA.h.

5) Теперь вы можете использовать ElegantOTA в асинхронном режиме для OTA обновлений и с библиотекой ESPAsyncWebServer.

Установка библиотек ESPAsyncTCP и ESPAsyncWebServer

Для тестирования примеров в этом руководстве вам также необходимо установить библиотеки ESPAsyncTCP и ESPAsyncWebServer.

Примечание

Библиотека ElegantOTA работает с различными форками библиотек ESPAsyncWebServer и ESPAsyncTCP, поэтому вам не обязательно использовать те же самые, что и мы.

Следуйте инструкциям ниже, чтобы установить эти библиотеки.

Нажмите на ссылки ниже, чтобы скачать .zip архивы библиотек.

Эти библиотеки недоступны для установки через Arduino Library Manager, поэтому вам нужно скопировать .zip файлы библиотек в папку Libraries установки Arduino. Или же в вашей Arduino IDE можно перейти в Sketch > Include Library > Add .zip Library и выбрать только что скачанные библиотеки.

Базовый пример ElegantOTA для ESP8266

Начнём с базового примера (основанного на одном из примеров библиотеки). Следующий код создаёт простой веб-сервер на ESP8266. Корневой URL отображает некоторый текст, а URL /update отображает интерфейс для обновления прошивки и файловой системы.

Скопируйте следующий код в вашу Arduino IDE.

/*********
  Rui Santos & Sara Santos - Random Nerd Tutorials
  Complete project details at https://RandomNerdTutorials.com/esp8266-nodemcu-ota-elegantota-arduino/
  Permission is hereby granted, free of charge, to any person obtaining a copy of this software
  and associated documentation files. The above copyright notice and this permission notice
  shall be included in all copies or substantial portions of the Software.
*********/

#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <ESPAsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include <ElegantOTA.h>

const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";

AsyncWebServer server(80);

void setup(void) {
  Serial.begin(115200);
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  Serial.println("");

  // Wait for connection
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.print("Connected to ");
  Serial.println(ssid);
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());

  server.on("/", HTTP_GET, [](AsyncWebServerRequest *request) {
    request->send(200, "text/plain", "Hi! I am ESP8266.");
  });

  server.begin();
  Serial.println("HTTP server started");

  ElegantOTA.begin(&server);    // Start ElegantOTA
}

void loop(void) {
  ElegantOTA.loop();
}

Просмотреть исходный код

Вставьте ваши сетевые учётные данные, и код должен сразу заработать.

const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";

Как работает код?

Начните с подключения необходимых библиотек.

#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <ESPAsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include <ElegantOTA.h>

Вставьте ваши сетевые учётные данные в следующие переменные, чтобы ESP8266 мог подключиться к Wi-Fi в вашей локальной сети.

const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";

Создайте объект AsyncWebServer на порту 80:

AsyncWebServer server(80);

В setup() инициализируйте монитор порта:

Serial.begin(115200);

Инициализируйте Wi-Fi:

WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
Serial.println("");

// Wait for connection
while (WiFi.status() != WL_CONNECTED) {
  delay(500);
  Serial.print(".");
}
Serial.println("");
Serial.print("Connected to ");
Serial.println(ssid);
Serial.print("IP address: ");
Serial.println(WiFi.localIP());

Затем обработайте клиентские запросы. Следующие строки отправляют текст Hi! I am ESP8266 при доступе к корневому (/) URL:

server.on("/", HTTP_GET, [](AsyncWebServerRequest *request) {
  request->send(200, "text/plain", "Hi! I am ESP8266.");
});

Если вашему веб-серверу нужно обрабатывать больше запросов, вы можете их добавить (мы покажем это в следующем примере).

Инициализируйте сервер:

server.begin();

Затем добавьте следующую строку для запуска ElegantOTA:

ElegantOTA.begin(&server);    // Start ElegantOTA

В loop() добавьте следующую строку:

ElegantOTA.loop();

Доступ к веб-серверу

После загрузки кода на плату откройте монитор порта на скорости 115200. Нажмите кнопку RST на плате ESP8266. Должен отобразиться IP-адрес ESP, как показано ниже (ваш может отличаться):

ESP8266 ElegantOTA веб-сервер -- получение IP-адреса в мониторе порта

В вашей локальной сети откройте браузер и введите IP-адрес ESP8266. Вы должны получить доступ к корневой (/) веб-странице с отображённым текстом.

Базовый веб-сервер ESP8266 NodeMCU с OTA

Теперь, если вы хотите изменить код веб-сервера через OTA, перейдите по IP-адресу ESP, добавив /update. Должна загрузиться следующая веб-страница.

Страница веб-сервера ElegantOTA ESP8266

Для загрузки нового кода на плату или файлов в файловую систему вам нужно загружать их в формате .bin. Следуйте следующему разделу, чтобы узнать, как сгенерировать файл .bin из вашего скетча в Arduino IDE.

Загрузка нового кода на ESP8266 через OTA

Каждый файл, который вы загружаете через OTA, должен быть в формате .bin. Вы можете сгенерировать файл .bin из вашего скетча с помощью Arduino IDE.

Открыв ваш скетч, вам просто нужно выбрать используемую плату ESP8266 в Tools > Board, а затем перейти в Sketch > Export Compiled Binary. Из вашего скетча будет сгенерирован файл .bin.

Arduino IDE, экспорт bin-файла

Сгенерированный файл будет сохранён в папке вашего проекта внутри серии других папок. Файл с расширением .ino.bin – это тот, который вы должны загрузить на плату через веб-страницу ElegantOTA.

Загрузка нового скетча веб-сервера через OTA – пример

Представьте, что после загрузки предыдущего скетча вы хотите загрузить новый, который позволяет управлять светодиодом через веб-интерфейс, как этот проект. Вот шаги, которые нужно выполнить:

  1. Скопируйте следующий код в вашу Arduino IDE. Не забудьте вставить ваши сетевые учётные данные.

/*********
  Rui Santos & Sara Santos - Random Nerd Tutorials
  Complete project details at https://RandomNerdTutorials.com/esp8266-nodemcu-ota-elegantota-arduino/
  Permission is hereby granted, free of charge, to any person obtaining a copy of this software
  and associated documentation files. The above copyright notice and this permission notice
  shall be included in all copies or substantial portions of the Software.
*********/

// Import required libraries
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <ESPAsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include <ElegantOTA.h>

// Replace with your network credentials
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";

bool ledState = 0;
const int ledPin = 2;

// Create AsyncWebServer object on port 80
AsyncWebServer server(80);
AsyncWebSocket ws("/ws");

const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML><html>
<head>
  <title>ESP Web Server</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" href="data:,">
  <style>
  html {
    font-family: Arial, Helvetica, sans-serif;
    text-align: center;
  }
  h1 {
    font-size: 1.8rem;
    color: white;
  }
  h2{
    font-size: 1.5rem;
    font-weight: bold;
    color: #143642;
  }
  .topnav {
    overflow: hidden;
    background-color: #143642;
  }
  body {
    margin: 0;
  }
  .content {
    padding: 30px;
    max-width: 600px;
    margin: 0 auto;
  }
  .card {
    background-color: #F8F7F9;;
    box-shadow: 2px 2px 12px 1px rgba(140,140,140,.5);
    padding-top:10px;
    padding-bottom:20px;
  }
  .button {
    padding: 15px 50px;
    font-size: 24px;
    text-align: center;
    outline: none;
    color: #fff;
    background-color: #0f8b8d;
    border: none;
    border-radius: 5px;
    -webkit-touch-callout: none;
    -webkit-user-select: none;
    -khtml-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
    -webkit-tap-highlight-color: rgba(0,0,0,0);
   }
   /*.button:hover {background-color: #0f8b8d}*/
   .button:active {
     background-color: #0f8b8d;
     box-shadow: 2 2px #CDCDCD;
     transform: translateY(2px);
   }
   .state {
     font-size: 1.5rem;
     color:#8c8c8c;
     font-weight: bold;
   }
  </style>
<title>ESP Web Server</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" href="data:,">
</head>
<body>
  <div class="topnav">
    <h1>ESP WebSocket Server</h1>
  </div>
  <div class="content">
    <div class="card">
      <h2>Output - GPIO 2</h2>
      <p class="state">state: <span id="state">%STATE%</span></p>
      <p><button id="button" class="button">Toggle</button></p>
    </div>
  </div>
<script>
  var gateway = `ws://${window.location.hostname}/ws`;
  var websocket;
  window.addEventListener('load', onLoad);
  function initWebSocket() {
    console.log('Trying to open a WebSocket connection...');
    websocket = new WebSocket(gateway);
    websocket.onopen    = onOpen;
    websocket.onclose   = onClose;
    websocket.onmessage = onMessage;
  }
  function onOpen(event) {
    console.log('Connection opened');
  }
  function onClose(event) {
    console.log('Connection closed');
    setTimeout(initWebSocket, 2000);
  }
  function onMessage(event) {
    var state;
    if (event.data == "1"){
      state = "ON";
    }
    else{
      state = "OFF";
    }
    document.getElementById('state').innerHTML = state;
  }
  function onLoad(event) {
    initWebSocket();
    initButton();
  }
  function initButton() {
    document.getElementById('button').addEventListener('click', toggle);
  }
  function toggle(){
    websocket.send('toggle');
  }
</script>
</body>
</html>)rawliteral";

void notifyClients() {
  ws.textAll(String(ledState));
}

void handleWebSocketMessage(void *arg, uint8_t *data, size_t len) {
  AwsFrameInfo *info = (AwsFrameInfo*)arg;
  if (info->final && info->index == 0 && info->len == len && info->opcode == WS_TEXT) {
    data[len] = 0;
    if (strcmp((char*)data, "toggle") == 0) {
      ledState = !ledState;
      notifyClients();
    }
  }
}

void onEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventType type,
             void *arg, uint8_t *data, size_t len) {
  switch (type) {
    case WS_EVT_CONNECT:
      Serial.printf("WebSocket client #%u connected from %s\n", client->id(), client->remoteIP().toString().c_str());
      break;
    case WS_EVT_DISCONNECT:
      Serial.printf("WebSocket client #%u disconnected\n", client->id());
      break;
    case WS_EVT_DATA:
      handleWebSocketMessage(arg, data, len);
      break;
    case WS_EVT_PONG:
    case WS_EVT_ERROR:
      break;
  }
}

void initWebSocket() {
  ws.onEvent(onEvent);
  server.addHandler(&ws);
}

String processor(const String& var){
  Serial.println(var);
  if(var == "STATE"){
    if (ledState){
      return "ON";
    }
    else{
      return "OFF";
    }
  }
  return String();
}

void setup(){
  // Serial port for debugging purposes
  Serial.begin(115200);

  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, LOW);

  // Connect to Wi-Fi
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.println("Connecting to WiFi..");
  }

  // Print ESP Local IP Address
  Serial.println(WiFi.localIP());

  initWebSocket();

  // Route for root / web page
  server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send(200, "text/html", index_html, processor);
  });

  // Start server
  server.begin();
  ElegantOTA.begin(&server);    // Start ElegantOTA
}

void loop() {
  ws.cleanupClients();
  digitalWrite(ledPin, !ledState);
  ElegantOTA.loop();
}

Просмотреть исходный код

Это тот же код, который используется в этом проекте, но он содержит необходимые строки кода для работы ElegantOTA:

#include <ElegantOTA.h>
ElegantOTA.begin(&server);
ElegantOTA.loop();

2. Сохраните ваш скетч: File > Save и дайте ему имя. Например: ESP8266_WebServer_LED_OTA.

3. Сгенерируйте файл .bin из вашего скетча. Сначала выберите используемую модель платы в Tools > Board. Затем перейдите в Sketch > Export Compiled Binary.

Arduino IDE, экспорт bin-файла

Перейдите в папку вашего скетча. Там должна быть папка build. Внутри этой папки будет ещё одна папка, связанная с моделью вашей платы. Откройте эту папку. Там будет несколько файлов. Вы должны загрузить файл с расширением ino.bin.

bin-файл для OTA обновлений ESP8266

4. Теперь вам нужно загрузить этот файл через страницу ElegantOTA. Перейдите по IP-адресу вашего ESP, добавив /update. Убедитесь, что выбрана опция firmware. Нажмите Choose File и выберите файл .ino.bin, который вы только что сгенерировали.

ESP8266 ElegantOTA загрузка новой прошивки

5. Через несколько секунд вы должны получить сообщение об успешной загрузке. Затем нажмите кнопку Back.

ESP8266 ElegantOTA успешная загрузка новой прошивки

6. Теперь вы можете перейти на корневой (/) URL для доступа к новому веб-серверу. Это страница, которую вы должны увидеть при доступе к IP-адресу ESP по корневому (/) URL.

ESP8266 Websocket сервер -- управление выходами

Вы можете нажать на кнопку, чтобы включить и выключить встроенный светодиод ESP8266.

Встроенный светодиод ESP8266 NodeMCU включён

Поскольку мы также добавили OTA-возможности к этому новому веб-серверу, мы можем загрузить новый скетч в будущем, если это потребуется. Вам просто нужно перейти по IP-адресу ESP8266, добавив /update.

Поздравляем, вы загрузили новый код на ESP8266 по Wi-Fi с использованием ElegantOTA.

Подведение итогов

В этом руководстве вы узнали, как добавить OTA-возможности в ваши проекты асинхронных веб-серверов с использованием библиотеки ElegantOTA на плате ESP8266. Эта библиотека проста в использовании – вам нужно добавить всего три строки кода в ваш проект.

Мы надеемся, что это руководство было для вас полезным.

Узнайте больше об ESP8266 с нашими ресурсами:

Спасибо за чтение.