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

相关文章

中文分词jieba库的使用与实景应用(一)

知识星球:https://articles.zsxq.com/id_fxvgc803qmr2.html 目录 一.定义: 精确模式(默认模式): 全模式: 搜索引擎模式: paddle 模式(基于深度学习的分词模式): 二 自定义词典 三.文本解析   调整词出现的频率 四. 关键词提取 A. 基于TF-IDF算法的关键词提取 B. 基于TextRank算法的关键词提取

使用SecondaryNameNode恢复NameNode的数据

1)需求: NameNode进程挂了并且存储的数据也丢失了,如何恢复NameNode 此种方式恢复的数据可能存在小部分数据的丢失。 2)故障模拟 (1)kill -9 NameNode进程 [lytfly@hadoop102 current]$ kill -9 19886 (2)删除NameNode存储的数据(/opt/module/hadoop-3.1.4/data/tmp/dfs/na

Hadoop数据压缩使用介绍

一、压缩原则 (1)运算密集型的Job,少用压缩 (2)IO密集型的Job,多用压缩 二、压缩算法比较 三、压缩位置选择 四、压缩参数配置 1)为了支持多种压缩/解压缩算法,Hadoop引入了编码/解码器 2)要在Hadoop中启用压缩,可以配置如下参数

Makefile简明使用教程

文章目录 规则makefile文件的基本语法:加在命令前的特殊符号:.PHONY伪目标: Makefilev1 直观写法v2 加上中间过程v3 伪目标v4 变量 make 选项-f-n-C Make 是一种流行的构建工具,常用于将源代码转换成可执行文件或者其他形式的输出文件(如库文件、文档等)。Make 可以自动化地执行编译、链接等一系列操作。 规则 makefile文件

使用opencv优化图片(画面变清晰)

文章目录 需求影响照片清晰度的因素 实现降噪测试代码 锐化空间锐化Unsharp Masking频率域锐化对比测试 对比度增强常用算法对比测试 需求 对图像进行优化,使其看起来更清晰,同时保持尺寸不变,通常涉及到图像处理技术如锐化、降噪、对比度增强等 影响照片清晰度的因素 影响照片清晰度的因素有很多,主要可以从以下几个方面来分析 1. 拍摄设备 相机传感器:相机传

poj3468(线段树成段更新模板题)

题意:包括两个操作:1、将[a.b]上的数字加上v;2、查询区间[a,b]上的和 下面的介绍是下解题思路: 首先介绍  lazy-tag思想:用一个变量记录每一个线段树节点的变化值,当这部分线段的一致性被破坏我们就将这个变化值传递给子区间,大大增加了线段树的效率。 比如现在需要对[a,b]区间值进行加c操作,那么就从根节点[1,n]开始调用update函数进行操作,如果刚好执行到一个子节点,

hdu1394(线段树点更新的应用)

题意:求一个序列经过一定的操作得到的序列的最小逆序数 这题会用到逆序数的一个性质,在0到n-1这些数字组成的乱序排列,将第一个数字A移到最后一位,得到的逆序数为res-a+(n-a-1) 知道上面的知识点后,可以用暴力来解 代码如下: #include<iostream>#include<algorithm>#include<cstring>#include<stack>#in

hdu1689(线段树成段更新)

两种操作:1、set区间[a,b]上数字为v;2、查询[ 1 , n ]上的sum 代码如下: #include<iostream>#include<algorithm>#include<cstring>#include<stack>#include<queue>#include<set>#include<map>#include<stdio.h>#include<stdl

pdfmake生成pdf的使用

实际项目中有时会有根据填写的表单数据或者其他格式的数据,将数据自动填充到pdf文件中根据固定模板生成pdf文件的需求 文章目录 利用pdfmake生成pdf文件1.下载安装pdfmake第三方包2.封装生成pdf文件的共用配置3.生成pdf文件的文件模板内容4.调用方法生成pdf 利用pdfmake生成pdf文件 1.下载安装pdfmake第三方包 npm i pdfma

零基础学习Redis(10) -- zset类型命令使用

zset是有序集合,内部除了存储元素外,还会存储一个score,存储在zset中的元素会按照score的大小升序排列,不同元素的score可以重复,score相同的元素会按照元素的字典序排列。 1. zset常用命令 1.1 zadd  zadd key [NX | XX] [GT | LT]   [CH] [INCR] score member [score member ...]