ESP32 OTA (Over-the-Air) обновления – AsyncElegantOTA с использованием Arduino IDE

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

Это руководство УСТАРЕЛО. Пожалуйста, используйте вместо него: ESP32 OTA (Over-the-Air) Updates – ElegantOTA Library with Arduino IDE

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

ESP32 OTA Over-the-Air обновления AsyncElegantOTA с Arduino IDE прошивка файловая система

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

У нас есть аналогичное руководство для платы ESP8266 NodeMCU: ESP8266 NodeMCU OTA (Over-the-Air) Updates – AsyncElegantOTA using Arduino IDE

Видеоурок

Этот проект доступен в видеоформате и в письменном формате. Вы можете посмотреть видео ниже или прокрутить вниз для получения письменных инструкций.

Обзор

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

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

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

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

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

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

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

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

Библиотека AsyncElegantOTA

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

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

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

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

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

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

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

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

OTA-обновления с библиотекой AsyncElegantOTA – краткое описание

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

  1. Установите библиотеки AsyncElegantOTA, AsyncTCP и ESPAsyncWebServer;

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

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

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

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

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

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

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

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

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

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

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

Вы можете установить библиотеку AsyncElegantOTA с помощью менеджера библиотек Arduino. В вашей Arduino IDE перейдите в Sketch > Include Library > Manage Libraries… Найдите «AsyncElegantOTA» и установите ее.

Установка библиотеки Async Elegant OTA в Arduino IDE

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

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

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

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

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

Если вы используете ESP32, вам нужно понизить версию дополнения плат ESP32 до версии 2.0.X. На данный момент библиотека AsyncElegantOTA несовместима с версией 3.X. Если вы хотите использовать версию 3.X, пожалуйста, используйте новейшую версию библиотеки: ElegantOTA V3.

Установка версии 2 дополнения плат ESP32

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

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

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

#include <Arduino.h>
#include <WiFi.h>
#include <AsyncTCP.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 ESP32.");
  });

  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 <WiFi.h>
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include <AsyncElegantOTA.h>

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

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

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

AsyncWebServer server(80);

В функции setup() инициализируйте Serial Monitor:

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 ESP32.» при доступе к корневому (/) URL:

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

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

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

AsyncElegantOTA.begin(&server);

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

server.begin();

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

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

AsyncElegantOTA получение IP-адреса ESP в Serial Monitor

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

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

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

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

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

Загрузка новой прошивки OTA (Over-the-Air) – ESP32

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

Открыв ваш скетч, вам просто нужно перейти в Sketch > Export Compiled Binary. Файл .bin будет сгенерирован из вашего скетча. Сгенерированный файл будет сохранен в папке вашего проекта.

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

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

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

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

/*
  Rui Santos
  Complete project details
   - Arduino IDE: https://RandomNerdTutorials.com/esp32-ota-over-the-air-arduino/
   - VS Code: https://RandomNerdTutorials.com/esp32-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 <WiFi.h>
#include <AsyncTCP.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. Сохраните ваш скетч: File > Save и дайте ему имя. Например: Web_Server_LED_OTA_ESP32.

  2. Сгенерируйте файл .bin из вашего скетча. Перейдите в Sketch > Export Compiled Binary. Несколько файлов .bin будут созданы в папке проекта. Вы должны загрузить файл с расширением ino.bin.

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

Загрузка новой прошивки через Elegant OTA
  1. Когда загрузка завершится, нажмите кнопку Back.

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

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

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

Встроенный LED на плате ESP32 включен

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

Поздравляем, вы загрузили новый код на ваш ESP32 по Wi-Fi с помощью AsyncElegantOTA.

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

Загрузка файлов в файловую систему OTA (Over-the-Air) – ESP32

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

Плагин загрузки файловой системы ESP32

Прежде чем продолжить, вам нужно установить плагин ESP32 Uploader Plugin в вашу Arduino IDE. Следуйте следующему руководству перед продолжением:

Веб-сервер с файлами из SPIFFS

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

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

Прежде чем продолжить, убедитесь, что у вас установлена библиотека Arduino_JSON от Arduino версии 0.1.0. Вы можете установить эту библиотеку в менеджере библиотек Arduino IDE. Просто перейдите в Sketch > Include Library > Manage Libraries и найдите библиотеку по имени: Arduino_JSON.

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

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

/*
  Rui Santos
  Complete project details
   - Arduino IDE: https://RandomNerdTutorials.com/esp32-ota-over-the-air-arduino/
   - VS Code: https://RandomNerdTutorials.com/esp32-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 <WiFi.h>
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include "SPIFFS.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 SPIFFS
void initSPIFFS() {
  if (!SPIFFS.begin(true)) {
    Serial.println("An error has occurred while mounting SPIFFS");
  }
  Serial.println("SPIFFS 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);
  }
  initSPIFFS();
  initWiFi();
  initWebSocket();

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

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

  // 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";

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

Создайте файл .bin из этого скетча, как показано ранее (этот скетч включает необходимые строки кода для обеспечения возможностей OTA).

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

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

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

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

Чтобы найти папку вашего проекта, вы можете просто перейти в Sketch > Show Sketch Folder.

Вот где должна находиться ваша папка data и как она выглядит:

Структура папки Data ESP32 Async ElegantOTA пример

После этого, при отключенном ESP32 от компьютера (в этом и заключается весь смысл OTA), нажмите ESP32 Data Sketch Upload.

ESP32 Sketch Data Upload Arduino IDE SPIFFS FS файловая система

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

Прокрутите вверх в окне отладки, пока не найдете расположение файла .spiffs.bin. Это тот файл, который вы должны загрузить (в нашем случае файл называется Web_Server_OTA_ESP32_Example_2.spiffs.bin).

Получение пути к файлу SPIFFS bin

И вот путь, где расположен наш файл:

C:\Users\sarin\AppData\Local\Temp\arduino_build_675367\Web_server_OTA_ESP32_Example_2.spiffs.bin

Чтобы получить доступ к этому файлу на моем компьютере, мне нужно сделать скрытые файлы видимыми (папка AppData была невидимой). Проверьте, не ваш ли это случай.

Arduino IDE ESP32 ESP8266 NodeMCU исправление установки дополнения платы

Когда вы дойдете до пути папки, вам нужен файл с расширением .spiffs.bin.

Папка SPIFFS Bin в Arduino IDE

Для удобства вы можете скопировать этот файл в папку вашего проекта.

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

Загрузка файлов в файловую систему AsyncElegantOTA

Затем выберите файл с расширением .spiffs.bin.

После успешной загрузки нажмите кнопку Back. И снова перейдите на корневой (/) URL. Вы должны получить доступ к следующей веб-странице, которая управляет выходами ESP32 с помощью протокола WebSocket.

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

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

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

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

Заключение

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

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

Узнайте больше об ESP32 с помощью наших ресурсов:

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


Источник: ESP32 OTA (Over-the-Air) Updates – AsyncElegantOTA using Arduino IDE