ESP8266 NodeMCU OTA (Over-the-Air) обновления — AsyncElegantOTA (VS Code + PlatformIO)

В этом руководстве вы узнаете, как выполнять обновления по воздуху (OTA) на платах ESP8266 NodeMCU с помощью библиотеки AsyncElegantOTA и VS Code с PlatformIO. Библиотека AsyncElegantOTA создает веб-сервер, который позволяет загружать новую прошивку (новый скетч) на вашу плату без необходимости устанавливать последовательное соединение между ESP8266 и вашим компьютером.

Кроме того, вы также можете загружать новые файлы в файловую систему ESP8266 (LittleFS). Библиотека очень проста в использовании и совместима с библиотекой ESPAsyncWebServer, которую мы часто используем для создания проектов веб-серверов.

ESP8266 NodeMCU OTA Over-the-Air обновления AsyncElegantOTA VS Code PlatformIO IDE

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

Рекомендуемое чтение: Начало работы с VS Code и PlatformIO IDE для ESP32 и ESP8266

У нас есть аналогичное руководство для платы ESP32: ESP32 OTA (Over-the-Air) обновления — AsyncElegantOTA (VS Code + PlatformIO)

Обзор

Это руководство охватывает:

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

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

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

Существуют различные способы выполнения OTA-обновлений. В этом руководстве мы рассмотрим, как это сделать с помощью библиотеки AsyncElegantOTA. На наш взгляд, это один из лучших и самых простых способов выполнения OTA-обновлений.

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

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

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

Библиотека AsyncElegantOTA

Как упоминалось ранее, существует множество альтернатив для OTA-программирования с платами ESP8266. Например, в Arduino IDE, в папке Examples, есть пример BasicOTA (который у нас никогда не работал хорошо); а также множество других примеров из различных библиотек.

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

Async ElegantOTA логотип
  • Она совместима с библиотекой ESPAsyncWebServer;

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

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

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

  • Она работает превосходно.

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

OTA-обновления с библиотекой AsyncElegantOTA — краткое резюме

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

  1. Подключите библиотеки AsyncElegantOTA, ESPAsyncTCP и ESPAsyncWebServer в файле platformio.ini вашего проекта;

  2. Подключите библиотеку AsyncElegantOTA в начале кода: #include <AsyncElegantOTA.h>;

  3. Добавьте эту строку AsyncElegantOTA.begin(&server); перед server.begin();

  4. Откройте браузер и перейдите по адресу http://<IPAddress>/update, где <IPAddress> — это IP-адрес вашего ESP8266.

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

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

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

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

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

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

Установка библиотеки AsyncElegantOTA (VS Code + PIO)

В этом руководстве мы будем использовать VS Code + PIO для программирования ESP8266. Если вы хотите использовать Arduino IDE, следуйте следующему руководству: ESP8266 NodeMCU OTA (Over-the-Air) обновления — AsyncElegantOTA с использованием Arduino IDE.

Чтобы использовать библиотеку AsyncElegantOTA, подключите её в вашем файле platformio.ini. Вам также нужно подключить библиотеку ESPAsyncWebServer. Добавьте эти библиотеки следующим образом:

lib_deps = ESP Async WebServer
  ayushsharma82/AsyncElegantOTA @ ^2.2.5

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

Давайте начнём с базового примера, предоставляемого библиотекой. Этот пример создает простой веб-сервер на ESP8266. Корневой URL отображает некоторый текст, а URL /update отображает интерфейс для обновления прошивки и файловой системы.

Отредактируйте ваш файл platformio.ini так, чтобы он выглядел следующим образом:

[env:esp12e]
platform = espressif8266
board = esp12e
framework = arduino
monitor_speed = 115200
lib_deps = ESP Async WebServer
  ayushsharma82/AsyncElegantOTA @ ^2.2.5

Скопируйте следующий код в файл main.cpp.

/*
  Rui Santos
  Complete project details
   - Arduino IDE: https://RandomNerdTutorials.com/esp8266-nodemcu-ota-over-the-air-arduino/
   - VS Code: https://RandomNerdTutorials.com/esp8266-nodemcu-ota-over-the-air-vs-code/

  This sketch shows a Basic example from the AsyncElegantOTA library: ESP8266_Async_Demo
  https://github.com/ayushsharma82/AsyncElegantOTA
*/

#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <ESPAsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include <AsyncElegantOTA.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.");
  });

  AsyncElegantOTA.begin(&server);    // Start ElegantOTA
  server.begin();
  Serial.println("HTTP server started");
}

void loop(void) {

}

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

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

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 <AsyncElegantOTA.h>

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

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.");
});

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

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

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

Наконец, инициализируйте сервер:

server.begin();

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

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

VS Code с PlatformIO получение IP-адреса платы

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

ESP8266 Async ElegantOTA демо пример веб-сервера корневой URL

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

ESP8266 Async ElegantOTA страница обновления

Следуйте следующим разделам, чтобы узнать, как загрузить новую прошивку с помощью AsyncElegantOTA.

Загрузка новой прошивки OTA (Over-the-Air) обновления — ESP8266

Каждый файл, который вы загружаете через OTA, должен быть в формате .bin. VS Code автоматически генерирует файл .bin для вашего проекта при компиляции кода. Файл называется firmware.bin и сохраняется в папке вашего проекта по следующему пути (или аналогичному, в зависимости от используемой платы):

.pio/build/esp12e/firmware.bin

Это тот файл .bin, который вы должны загрузить через веб-страницу AsyncElegantOTA, если хотите обновить прошивку.

Загрузка нового скетча веб-сервера

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

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

/*
  Rui Santos & Sara Santos - Random Nerd Tutorials
  Complete project details
   - Arduino IDE: https://RandomNerdTutorials.com/esp8266-nodemcu-ota-over-the-air-arduino/
   - VS Code: https://RandomNerdTutorials.com/esp8266-nodemcu-ota-over-the-air-vs-code/

  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 <AsyncElegantOTA.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').textContent = 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 ElegantOTA
  AsyncElegantOTA.begin(&server);
  // Start server
  server.begin();
}

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

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

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

#include <AsyncElegantOTA.h>
AsyncElegantOTA.begin(&server);
  1. Отредактируйте ваш файл platformio.ini следующим образом:

[env:esp12e]
platform = espressif8266
board = esp12e
framework = arduino
monitor_speed = 115200
lib_deps = ESP Async WebServer
  ayushsharma82/AsyncElegantOTA @ ^2.2.5

2. Сохраните и скомпилируйте код — нажмите на иконку Build.

VS Code + PlatformIO компиляция (сборка) кода

3. Теперь на вкладке Explorer в VS Code вы можете проверить, что у вас есть файл firmware.bin в папке проекта по следующему пути (или аналогичному):

.pio/build/esp12e/firmware.bin

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

5. Нажмите Choose File, перейдите к папке на вашем компьютере и выберите файл вашего проекта.

Расположение файла firmware.bin в VS Code PlatformIO

6. Дождитесь, пока индикатор прогресса достигнет 100%.

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

7. Когда загрузка завершится, нажмите кнопку Back.

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

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

ESP32 ESP8266 NodeMCU WebSocket сервер управление выходами

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

ESP8266 NodeMCU встроенный светодиод

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

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

Продолжайте чтение, если хотите узнать, как загружать файлы в файловую систему ESP8266 (LittleFS) с помощью AsyncElegantOTA.

Загрузка файлов в файловую систему OTA (Over-the-Air) обновления — ESP8266

В этом разделе вы узнаете, как загружать файлы в файловую систему ESP8266 (LittleFS) с помощью AsyncElegantOTA.

Веб-сервер с файлами из файловой системы (LittleFS)

Представьте сценарий, когда вам нужно загрузить файлы в файловую систему ESP8266, например, файлы конфигурации, HTML, CSS и JavaScript файлы для обновления страницы веб-сервера или любые другие файлы, которые вы хотите сохранить в LittleFS через OTA.

Чтобы показать вам, как это сделать, мы создадим новый веб-сервер, который обслуживает файлы из LittleFS: HTML, CSS и JavaScript файлы для создания веб-страницы, которая удалённо управляет GPIO ESP8266.

Скопируйте следующий код в ваш файл main.cpp.

/*
  Rui Santos
  Complete project details
   - Arduino IDE: https://RandomNerdTutorials.com/esp8266-nodemcu-ota-over-the-air-arduino/
   - VS Code: https://RandomNerdTutorials.com/esp8266-nodemcu-ota-over-the-air-vs-code/

  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 "LittleFS.h"
#include <Arduino_JSON.h>
#include <AsyncElegantOTA.h>

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

// Create AsyncWebServer object on port 80
AsyncWebServer server(80);

// Create a WebSocket object
AsyncWebSocket ws("/ws");

// Set number of outputs
#define NUM_OUTPUTS  4

// Assign each GPIO to an output
int outputGPIOs[NUM_OUTPUTS] = {2, 4, 12, 14};

// Initialize LittleFS
void initLittleFS() {
  if (!LittleFS.begin()) {
    Serial.println("An error has occurred while mounting LittleFS");
  }
  Serial.println("LittleFS mounted successfully");
}

// Initialize WiFi
void initWiFi() {
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  Serial.print("Connecting to WiFi ..");
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print('.');
    delay(1000);
  }
  Serial.println(WiFi.localIP());
}

String getOutputStates(){
  JSONVar myArray;
  for (int i =0; i<NUM_OUTPUTS; i++){
    myArray["gpios"][i]["output"] = String(outputGPIOs[i]);
    myArray["gpios"][i]["state"] = String(digitalRead(outputGPIOs[i]));
  }
  String jsonString = JSON.stringify(myArray);
  return jsonString;
}

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

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, "states") == 0) {
      notifyClients(getOutputStates());
    }
    else{
      int gpio = atoi((char*)data);
      digitalWrite(gpio, !digitalRead(gpio));
      notifyClients(getOutputStates());
    }
  }
}

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);
}

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

  // Set GPIOs as outputs
  for (int i =0; i<NUM_OUTPUTS; i++){
    pinMode(outputGPIOs[i], OUTPUT);
  }
  initLittleFS();
  initWiFi();
  initWebSocket();

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

  server.serveStatic("/", LittleFS, "/");

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

  // Start server
  server.begin();
}

void loop() {
  ws.cleanupClients();
}

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

Вставьте ваши сетевые учётные данные в следующие переменные и сохраните код.

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

Отредактируйте ваш файл platformio.ini так, чтобы он выглядел следующим образом:

[env:esp12e]
platform = espressif8266
board = esp12e
framework = arduino
monitor_speed = 115200
lib_deps  =  ESP Async WebServer
    arduino-libraries/Arduino_JSON @ 0.1.0
    ayushsharma82/AsyncElegantOTA @ ^2.2.5
board_build.filesystem = littlefs

Обновление прошивки

После вставки сетевых учётных данных сохраните и скомпилируйте код.

VS Code + PlatformIO компиляция (сборка) кода

Перейдите по IP-адресу ESP, добавив /update, и загрузите новую прошивку, как показано ранее.

Далее мы рассмотрим, как загружать файлы в файловую систему.

Обновление файловой системы

В папке проекта создайте папку с именем data и вставьте следующие HTML, CSS и JavaScript файлы (нажмите на ссылки для скачивания файлов):

В VS Code нажмите на иконку PIO и перейдите в Project Tasks > env:esp12e (или аналогичный) > Platform > Build Filesystem Image. Это создаст файл .bin из файлов, сохранённых в папке data.

Создание образа файловой системы VS Code PlatformIO ESP8266 NodeMCU

После создания образа файловой системы у вас должен появиться файл littlefs.bin по следующему пути (или аналогичному):

.pio/build/esp12e/littlefs.bin
Расположение файла LittleFS bin ESP8266 VS Code PlatformIO

Это тот файл, который вы должны загрузить для обновления файловой системы.

Перейдите по IP-адресу вашего ESP, добавив /update. Убедитесь, что выбрана опция Filesystem, и выберите файл littlefs.bin.

Загрузка файлов файловой системы ElegantOTA ESP8266

После успешной загрузки нажмите кнопку Back. И снова перейдите к корневому (/) URL.

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

Управление несколькими выходами ESP32 ESP8266 WebSocket веб-сервер

Чтобы увидеть работу веб-сервера, вы можете подключить 4 светодиода к ESP8266 на GPIO: 2, 4, 12 и 14. Вы сможете управлять этими выходами через веб-сервер.

Если вам нужно обновить что-то в вашем проекте, просто перейдите по IP-адресу ESP8266, добавив /update.

Поздравляем! Вы успешно загрузили файлы в файловую систему ESP8266 с помощью ElegantOTA.

Заключение

В этом руководстве вы узнали, как добавить возможности OTA в ваши Async Web Server проекты с помощью библиотеки AsyncElegantOTA. Эта библиотека невероятно проста в использовании и позволяет загружать новую прошивку или файлы в LittleFS без усилий, используя веб-страницу. На наш взгляд, библиотека AsyncElegantOTA — один из лучших вариантов для обработки OTA веб-обновлений.

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

Узнайте всё, что нужно знать о создании веб-серверов с ESP8266:

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

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