ESP8266 NodeMCU OTA(无线)更新——使用 Arduino IDE 的 AsyncElegantOTA

2023-10-14 12:20

本文主要是介绍ESP8266 NodeMCU OTA(无线)更新——使用 Arduino IDE 的 AsyncElegantOTA,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在本指南中,您将学习如何使用 AsyncElegantOTA 库对 ESP8266 NodeMCU 板进行无线 (OTA) 更新。该库创建了一个网络服务器,允许您将新固件(新草图)更新到您的电路板,而无需在 ESP8266 和您的计算机之间建立串行连接。

此外,您还可以将新文件上传到 ESP8266 文件系统 (LittleFS)。该库非常易于使用,并且与我们经常用于构建 Web 服务器项目的 ESPAsyncWebServer 库兼容。

使用 Arduino IDE 的 ESP8266 NodeMCU OTA 无线更新 AsyncElegantOTA

在本教程结束时,您将能够使用 ESP8266 轻松地将 OTA 功能添加到您的网络服务器项目中,以便将来以无线方式将新固件和文件上传到文件系统。

我们为 ESP32 开发板提供了类似的教程:


 

概述

本教程涵盖:

  • 将 ElegantOTA 功能添加到您的 Web 服务器
  • 通过 OTA 将新固件上传到 ESP8266 开发板
  • 通过 OTA 将文件上传到 LittleFS 到 ESP8266 板

我们建议您按照本教程中的所有步骤来了解 ElegantOTA 的工作原理以及如何在您的项目中使用它。为了演示如何执行此操作,我们将上传文件以构建不同的 Web 服务器项目。

OTA(空中下载)编程

OTA(空中下载)更新是使用 Wi-Fi 连接而不是串行通信将新固件加载到 ESP8266 NodeMCU 板的过程。在无法物理访问 ESP8266 开发板的情况下,此功能非常有用。

有多种方法可以执行 OTA 更新。在本教程中,我们将介绍如何使用AsyncElegantOTA 库来做到这一点。在我们看来,这是执行 OTA 更新的最佳和最简单的方法之一。

AsyncElegantOTA 库创建了一个 Web 服务器,您可以在本地网络上访问该服务器以将新固件或文件上传到文件系统 (LittleFS)。您上传的文件应为.bin格式。我们稍后将在本教程中向您展示如何将您的文件转换为.bin格式。

异步 ElegantOTA 网络服务器 ESP8266 工作原理

OTA 编程的唯一缺点是您需要在您上传的每个草图中添加 OTA 代码,以便您将来可以使用 OTA。对于 AsyncElegantOTA 库,它仅包含三行代码。

AsyncElegantOTA 库

如前所述,使用 ESP8266 板进行 OTA 编程有很多替代方案。例如,在 Arduino IDE 中,Examples文件夹下有BasicOTA示例(对我们来说从来都不是很好);以及来自不同库的许多其他示例。

我们使用ESP8266 的大多数 Web 服务器项目都使用ESPAsyncWebServer 库。因此,我们想要一个与该库兼容的解决方案。该AsyncElegantOTA库仅仅是完美的,我们想要的东西:

AsyncElegantOTA 库

  • 它与 ESPAsyncWebServer 库兼容;
  • 您只需要添加三行代码即可将 OTA 功能添加到您的“常规”异步 Web 服务器;
  • 它不仅允许您将新固件更新到板上,还允许您将文件更新到 ESP8266 文件系统 (LittleFS);
  • 它提供了一个漂亮而现代的 Web 服务器界面;
  • 它工作得非常好。

如果您喜欢这个库并且将在您的项目中使用它,请考虑支持开发人员的工作。

使用 AsyncElegantOTA 库进行 OTA 更新 – 快速总结

要使用 AsyncElegantOTA 库向您的项目添加 OTA 功能,请执行以下步骤:

  1. 安装AsyncElegantOTA、ESPAsyncTCP和ESPAsyncWebServer库;
  2. 在 Arduino 草图的顶部包含 AsyncElegantOTA 库: #include <AsyncElegantOTA.h>;
  3. 添加这一行 AsyncElegantOTA.begin(&server); 前 server.begin();
  4. 打开浏览器并转到 http://<IP 地址>/update, 在哪里 <IP地址> 是您的 ESP8266 IP 地址。

继续阅读教程以获取更详细的步骤。

OTA Web 更新程序如何工作?

  • 第一个草图应该通过串口上传。此草图应包含用于创建 OTA Web 更新程序的代码,以便您稍后可以使用浏览器上传代码。
  • OTA 网络更新程序草图创建了一个网络服务器,您可以访问它以通过网络浏览器上传新的草图。
  • 然后,您需要在您上传的每个草图中实施 OTA 例程,以便您能够通过无线方式进行下一次更新/上传。
  • 如果您上传没有 OTA 例程的代码,您将无法再访问网络服务器并通过无线方式上传新的草图。

安装 AsyncElegantOTA 库

在本教程中,ESP8266 将使用 Arduino IDE 进行编程。如果你想学习如何使用 VS Code + PlatformIO 来做同样的事情,请按照下一个教程:  ESP8266 NodeMCU OTA(空中)更新 – AsyncElegantOTA(VS Code + PlatformIO)。

您可以使用 Arduino 库管理器安装 AsyncElegantOTA 库。在您的 Arduino IDE 中,转到Sketch > Include Library > Manage Libraries...搜索“ AsyncElegantOTA ”并安装它。

安装 Async Elegant OTA 库 Arduino IDE

安装 ESPAsyncWebServer 和 ESPAsyncTCP 库

您还需要安装 ESPAsyncTCP 和 ESPAsyncWebServer 库。单击下面的链接下载库。

  • ESPA同步网络服务器
  • ESPA同步TCP

这些库无法通过 Arduino 库管理器安装,因此您需要将库文件复制到 Arduino 安装库文件夹。或者,在您的 Arduino IDE 中,您可以转到 Sketch  >  Include Library  >  Add .zip Library 并选择您刚刚下载的库。

AsyncElegantOTA ESP8266 基本示例

让我们从库提供的基本示例开始。此示例使用 ESP8266 创建一个简单的 Web 服务器。根 URL 显示一些文本,并且/更新 URL 显示更新固件和文件系统的界面。

将以下代码复制到您的 Arduino IDE。

/*Rui SantosComplete 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_Demohttps://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 connectionwhile (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 ElegantOTAserver.begin();Serial.println("HTTP server started");
}void loop(void) {AsyncElegantOTA.loop();
}

插入您的网络凭据,代码应立即生效:

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

代码的工作原理

首先,包括必要的库:

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

创建一个 异步网络服务器 端口 80 上的对象:

AsyncWebServer server(80);

在里面 设置(),初始化串口监视器:

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

然后,处理客户端请求。以下几行,发送一些文本你好!我是ESP8266。 当您访问根 (/) 网址:

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

如果您的 Web 服务器需要处理更多请求,您可以添加它们(我们将在下一个示例中向您展示)。

然后,添加下一行以启动 ElegantOTA:

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

最后,初始化服务器:

server.begin();

最后在里面添加以下内容 loop()

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

访问网络服务器

上传代码到板子后,以115200的波特率打开串口监视器,按下ESP8266板载RST按钮。它应该显示 ESP IP 地址如下(你的可能不同):

Async ElegantOTA 获取 ESP IP 地址串行监视器

在本地网络中,打开浏览器并输入 ESP8266 IP 地址。您应该可以访问根目录(/) 显示一些文本的网页。

ESP8266 Async ElegantOTA 演示示例 Web 服务器根 URL

现在,假设您要修改 Web 服务器代码。要通过 OTA 执行此操作,请转到 ESP IP 地址,然后是/更新. 应加载以下网页。

ESP8266 Async ElegantOTA 更新页面

按照下一节了解如何使用 AsyncElegantOTA 上传新固件。

上传新固件 OTA(无线)更新 – ESP8266

您通过 OTA 上传的每个文件都应为.bin格式。您可以使用 Arduino IDE 从您的草图中生成一个.bin文件。

打开草图后,您需要转到Sketch > Export Compiled Binary。一个名为.bin文件将从您的草图生成。生成的文件将保存在您的项目文件夹下。

如果您想上传新固件,您应该使用 AsyncElegantOTA 网页上传那个.bin文件。

上传新的 Web 服务器草图 – 示例

让我们看一个实际的例子。想象一下,在上传之前的草图后,您想上传一个新的草图,该草图允许您通过网络界面控制 LED,例如这个项目。以下是您需要遵循的步骤:

1. 将以下代码复制到您的 Arduino IDE。不要忘记插入您的网络凭据。

/*Rui SantosComplete 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 copyof this software and associated documentation files.The above copyright notice and this permission notice shall be included in allcopies 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; // <-- add this line}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 purposesSerial.begin(115200);pinMode(ledPin, OUTPUT);digitalWrite(ledPin, LOW);// Connect to Wi-FiWiFi.begin(ssid, password);while (WiFi.status() != WL_CONNECTED) {delay(1000);Serial.println("Connecting to WiFi..");}// Print ESP Local IP AddressSerial.println(WiFi.localIP());initWebSocket();// Route for root / web pageserver.on("/", HTTP_GET, [](AsyncWebServerRequest *request){request->send_P(200, "text/html", index_html, processor);});// Start ElegantOTAAsyncElegantOTA.begin(&server);// Start serverserver.begin();
}void loop() {AsyncElegantOTA.loop();ws.cleanupClients();digitalWrite(ledPin, ledState);
}

查看原始代码

这与此项目中使用的代码相同,但它包含处理 ElegantOTA 所需的代码行:

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

2. 保存您的草图:文件>保存并为其命名。例如:Web_Server_LED_OTA_ESP8266

3.从你的草图中生成一个.bin文件。转到Sketch > Export Compiled Binary。应该在项目文件夹下创建一个新的.bin文件。

为 OTA 更新 Arduino IDE 生成的 ESP8266 Bin 文件

4. 现在您只需要使用 ElegantOTA 页面上传该文件。转到您的 ESP IP 地址,然后是/更新. 确保您选择了固件选项。单击“选择文件”并选择您刚刚生成的.bin文件。

ESP8266 更新新固件 Elegant OTA

5. 完成后,单击“返回”按钮。

ESP8266 NodeMCU 上传新固件 Elegant OTA 成功

6.然后,你可以去根(/) 访问新 Web 服务器的 URL。这是访问根目录上的 ESP IP 地址时应该看到的页面 (/) 网址。

ESP8266 NodeMCU Websocket 服务器控制输出

您可以单击按钮来打开和关闭 ESP8266 板载 LED。

ESP8266 NodeMCU 板 内置 LED 高亮

因为我们还为这个新的 Web 服务器添加了 OTA 功能,所以我们可以在未来根据需要上传新的草图。您只需要转到 ESP8266 IP 地址,然后/更新.

恭喜,您已使用 ElegantOTA 通过 Wi-Fi 将新代码上传到您的 ESP8266。

如果您想了解如何使用 AsyncElegantOTA 将文件上传到 ESP8266 文件系统 (LittleFS),请继续阅读。

将文件上传到文件系统 OTA(无线)更新 – ESP8266

在本节中,您将学习使用 AsyncElegantOTA 将文件上传到 ESP8266 文件系统 (LittleFS)。

ESP8266 LittleFS 文件系统上传插件

在继续之前,您需要在 Arduino IDE 中安装 ESP8266 LittleFS Uploader Plugin。在继续之前,请按照下一个教程进行操作:

  • 安装 Arduino ESP8266 LittleFS 文件系统上传器

带有 LittleFS 文件的 Web 服务器

想象一下您需要将文件上传到 ESP8266 文件系统的场景,例如配置文件、HTML、CSS 和 JavaScript 文件以更新 Web 服务器页面或您可能希望通过 OTA 保存在 LittleFS 中的任何其他文件。

为了向您展示如何执行此操作,我们将创建一个新的 Web 服务器,该服务器提供来自文件系统 (LittleFS) 的文件:HTML、CSS 和 JavaScript 文件,以构建一个远程控制 ESP8266 GPIO 的网页。

在继续之前,请确保您已安装Arduino 0.1.0 版的Arduino_JSON 库。您可以在 Arduino IDE 库管理器中安装此库。只需转到 Sketch  >  Include Library  >  Manage Libraries 并按如下方式搜索库名称:Arduino_JSON。

将以下代码复制到您的 Arduino IDE。

/*Rui SantosComplete 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 copyof this software and associated documentation files.The above copyright notice and this permission notice shall be included in allcopies 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 purposesSerial.begin(115200);// Set GPIOs as outputsfor (int i =0; i<NUM_OUTPUTS; i++){pinMode(outputGPIOs[i], OUTPUT);}initLittleFS();initWiFi();initWebSocket();// Route for root / web pageserver.on("/", HTTP_GET, [](AsyncWebServerRequest *request){request->send(LittleFS, "/index.html", "text/html",false);});server.serveStatic("/", LittleFS, "/");// Start ElegantOTAAsyncElegantOTA.begin(&server);// Start serverserver.begin();
}void loop() {AsyncElegantOTA.loop();ws.cleanupClients();
}

查看原始代码

在以下变量中插入您的网络凭据并保存代码。

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

更新固件

从此草图创建一个.bin文件,如前所示(此草图包括提供 OTA 功能所需的代码行)。

转到 ESP8266 IP 地址,然后是 /更新 并上传新固件。

接下来,我们将看到如何上传文件。

更新文件系统

在项目文件夹下创建一个名为data的文件夹并粘贴以下 HTML、CSS 和 JavaScript 文件(单击链接下载文件):

  • HTML 文件:index.html
  • CSS 文件:style.css
  • JavaScript 文件:script.js
  • 下载所有文件
     
<!DOCTYPE HTML><html>
<head><title>ESP IOT DASHBOARD</title><meta name="viewport" content="width=device-width, initial-scale=1"><link rel="stylesheet" type="text/css" href="style.css"><link rel="icon"  type="image/png" href="favicon.png"><link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.2/css/all.css" integrity="sha384-fnmOCqbTlWIlj8LyTjo7mOUStjsKC4pOpQbqyi7RrhN7udi9RwhKkMHpvLbHG9Sr" crossorigin="anonymous">
</head>
<body><div class="topnav"><h1>ESP WEB SERVER - Control Multiple Outputs WebSocket</h1></div><div class="content"><div class="card-grid"><div class="card">             <p class="card-title"><i class="fas fa-lightbulb"></i> GPIO 2</p><label class="switch"><input type="checkbox" onchange="toggleCheckbox(this)" id="2"><span class="slider"></span></label><p class ="state">State: <span id="2s"></span></p></div><div class="card"><p class="card-title"><i class="fas fa-lightbulb"></i> GPIO 4</p><label class="switch"><input type="checkbox" onchange="toggleCheckbox(this)" id="4"><span class="slider"></span></label><p class ="state">State: <span id="4s"></span></p></div><div class="card"><p class="card-title"><i class="fas fa-lightbulb"></i> GPIO 14</p><label class="switch"><input type="checkbox" onchange="toggleCheckbox(this)" id="14"><span class="slider"></span></label><p class ="state">State: <span id="14s"></span></p></div><div class="card"><p class="card-title"><i class="fas fa-lightbulb"></i> GPIO 12</p><label class="switch"><input type="checkbox" onchange="toggleCheckbox(this)" id="12"><span class="slider"></span></label><p class="state">State: <span id="12s"></span></p></div></div>
</div>
<script src="/script.js"></script>
</body>
</html>
html {font-family: Arial, Helvetica, sans-serif; text-align: center;
}
h1 {font-size: 1.8rem; color: white;
}
.topnav { overflow: hidden; background-color: #0A1128;
}
body {  margin: 0;
}
.content { padding: 50px;
}
.card-grid { max-width: 600px; margin: 0 auto; display: grid; gap: 2rem; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
}
.card { background-color: white; box-shadow: 2px 2px 12px 1px rgba(140,140,140,.5);
}
.card-title { font-size: 1.2rem;font-weight: bold;color: #034078
}
.state {font-size: 1.2rem;color:#1282A2;
}
.switch {position: relative; display: inline-block; width: 120px; height: 68px
} 
.switch input {display: none
}
.slider {position: absolute; top: 0; left: 0; right: 0; bottom: 0; background-color: #ccc; border-radius: 50px
}
.slider:before {position: absolute; content: ""; height: 52px; width: 52px; left: 8px; bottom: 8px; background-color: #fff; -webkit-transition: .4s; transition: .4s;border-radius: 50px;
}
input:checked+.slider {background-color: #b30000;
}
input:checked+.slider:before {-webkit-transform: translateX(52px);-ms-transform: translateX(52px); transform: translateX(52px);
}
var gateway = `ws://${window.location.hostname}/ws`;
var websocket;
window.addEventListener('load', onLoad);function onLoad(event) {initWebSocket();
}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');websocket.send("states");
}function onClose(event) {console.log('Connection closed');setTimeout(initWebSocket, 2000);
} function onMessage(event) {var myObj = JSON.parse(event.data);console.log(myObj);for (i in myObj.gpios){var output = myObj.gpios[i].output;var state = myObj.gpios[i].state;console.log(output);console.log(state);if (state == "1"){document.getElementById(output).checked = true;document.getElementById(output+"s").innerHTML = "ON";}else{document.getElementById(output).checked = false;document.getElementById(output+"s").innerHTML = "OFF";}}console.log(event.data);
}// Send Requests to Control GPIOs
function toggleCheckbox (element) {console.log(element.id);websocket.send(element.id);if (element.checked){document.getElementById(element.id+"s").innerHTML = "ON";}else {document.getElementById(element.id+"s").innerHTML = "OFF"; }
}

要找到您的项目文件夹,您可以转到Sketch > Show Sketch Folder

这是您的数据文件夹应位于的位置及其外观:

数据文件夹结构 ESP8266 Async ElegantOTA 示例

在此之后,将 ESP8266 与您的计算机断开连接(这就是 OTA 的全部目的),点击ESP8266 LittleFS Data Upload

ESP8266 LittleFS 数据上传 Arduino IDE

您会收到错误消息,因为没有任何 ESP8266 板连接到您的计算机 - 别担心。

在调试窗口上向上滚动,直到找到.mklittlefs.bin文件位置。那就是您应该上传的文件(在我们的例子中,该文件名为Web_Server_OTA_ESP8266_Example_2.mklittlefs.bin。

获取 LittleFS Bin 文件路径 ESP8266

这是我们文件所在的路径:

C:\Users\sarin\AppData\Local\Temp\arduino_build_375940\Web_server_OTA_ESP8266_Example_2.mklittlefs.bin

要在我的计算机上访问该文件,我需要使隐藏文件可见(AppData文件夹不可见)。检查这是否也是你的情况。

Arduino IDE ESP32 ESP8266 NodeMCU 板附加修复安装

到达文件夹路径后,您希望获取扩展名为.mklittlefs.bin的文件。

LittleFS Bin 文件 ESP8266

为方便起见,您可以将该文件复制到您的项目文件夹中。

现在我们有来自数据文件夹的.bin文件,我们可以上传该文件。转到您的 ESP8266 IP 地址,然后是/更新. 确保您选择了文件系统选项。

上传文件文件系统 ElegantOTA ESP8266

然后,选择扩展名为.mklittlefs.bin的文件。

上传成功后,点击返回按钮。并转到根 (/) 网址。您应该可以访问以下使用Web Socket 协议控制 ESP8266 输出的网页。

控制多个 ESP32 ESP8266 输出 Websocket Web 服务器

要查看网络服务器的工作情况,您可以将 4 个 LED 连接到 GPIOS 上的 ESP8266:2、4、12 和 14。您应该能够控制来自网络服务器的这些输出。

如果您需要更新项目中的某些内容,只需转到您的 ESP8266 IP 地址,然后输入 /更新.

恭喜!您已使用 ElegantOTA 成功将文件上传到 ESP8266 文件系统。

这篇关于ESP8266 NodeMCU OTA(无线)更新——使用 Arduino IDE 的 AsyncElegantOTA的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/210479

相关文章

Python使用Pandas对比两列数据取最大值的五种方法

《Python使用Pandas对比两列数据取最大值的五种方法》本文主要介绍使用Pandas对比两列数据取最大值的五种方法,包括使用max方法、apply方法结合lambda函数、函数、clip方法、w... 目录引言一、使用max方法二、使用apply方法结合lambda函数三、使用np.maximum函数

Qt 中集成mqtt协议的使用方法

《Qt中集成mqtt协议的使用方法》文章介绍了如何在工程中引入qmqtt库,并通过声明一个单例类来暴露订阅到的主题数据,本文通过实例代码给大家介绍的非常详细,感兴趣的朋友一起看看吧... 目录一,引入qmqtt 库二,使用一,引入qmqtt 库我是将整个头文件/源文件都添加到了工程中进行编译,这样 跨平台

C++使用栈实现括号匹配的代码详解

《C++使用栈实现括号匹配的代码详解》在编程中,括号匹配是一个常见问题,尤其是在处理数学表达式、编译器解析等任务时,栈是一种非常适合处理此类问题的数据结构,能够精确地管理括号的匹配问题,本文将通过C+... 目录引言问题描述代码讲解代码解析栈的状态表示测试总结引言在编程中,括号匹配是一个常见问题,尤其是在

Java中String字符串使用避坑指南

《Java中String字符串使用避坑指南》Java中的String字符串是我们日常编程中用得最多的类之一,看似简单的String使用,却隐藏着不少“坑”,如果不注意,可能会导致性能问题、意外的错误容... 目录8个避坑点如下:1. 字符串的不可变性:每次修改都创建新对象2. 使用 == 比较字符串,陷阱满

Python使用国内镜像加速pip安装的方法讲解

《Python使用国内镜像加速pip安装的方法讲解》在Python开发中,pip是一个非常重要的工具,用于安装和管理Python的第三方库,然而,在国内使用pip安装依赖时,往往会因为网络问题而导致速... 目录一、pip 工具简介1. 什么是 pip?2. 什么是 -i 参数?二、国内镜像源的选择三、如何

使用C++实现链表元素的反转

《使用C++实现链表元素的反转》反转链表是链表操作中一个经典的问题,也是面试中常见的考题,本文将从思路到实现一步步地讲解如何实现链表的反转,帮助初学者理解这一操作,我们将使用C++代码演示具体实现,同... 目录问题定义思路分析代码实现带头节点的链表代码讲解其他实现方式时间和空间复杂度分析总结问题定义给定

Linux使用nload监控网络流量的方法

《Linux使用nload监控网络流量的方法》Linux中的nload命令是一个用于实时监控网络流量的工具,它提供了传入和传出流量的可视化表示,帮助用户一目了然地了解网络活动,本文给大家介绍了Linu... 目录简介安装示例用法基础用法指定网络接口限制显示特定流量类型指定刷新率设置流量速率的显示单位监控多个

JavaScript中的reduce方法执行过程、使用场景及进阶用法

《JavaScript中的reduce方法执行过程、使用场景及进阶用法》:本文主要介绍JavaScript中的reduce方法执行过程、使用场景及进阶用法的相关资料,reduce是JavaScri... 目录1. 什么是reduce2. reduce语法2.1 语法2.2 参数说明3. reduce执行过程

如何使用Java实现请求deepseek

《如何使用Java实现请求deepseek》这篇文章主要为大家详细介绍了如何使用Java实现请求deepseek功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1.deepseek的api创建2.Java实现请求deepseek2.1 pom文件2.2 json转化文件2.2

python使用fastapi实现多语言国际化的操作指南

《python使用fastapi实现多语言国际化的操作指南》本文介绍了使用Python和FastAPI实现多语言国际化的操作指南,包括多语言架构技术栈、翻译管理、前端本地化、语言切换机制以及常见陷阱和... 目录多语言国际化实现指南项目多语言架构技术栈目录结构翻译工作流1. 翻译数据存储2. 翻译生成脚本