ESP8266-Arduino网络编程实例-远程固件升级
远程固件升级
在前面的文章中,实现了在Arduino IED中设置通过OTA方式下载固件到ESP8266。在本文中,将演示如何通过Web页面通过OTA方式升级固件。
1、硬件准备
- ESP8266 NodeMCU开发板一块
- 数据线一条
2、软件准备
- Arduino IDE或VSCode + PlatformIO
在前面的文章中,对如何搭建ESP8266开发环境做了详细的介绍,请参考:
ESP8266 NodeMCU的引脚介绍在前面的文章中做了详细的介绍,请参考:
3、代码实现
本次实例使用到的开源库如下:
Web页面的固件升级流程如下:

第一步,通过串口下载支持OTA升级固件
第二步,生成新的升级固件二进制文件
第三步,通过浏览器上传固件
第四步,ESP8266更新固件,重新启动,运行新固件
下面代码为运行OTA升级的基础固件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
| #include <Arduino.h> #include <ESP8266WiFi.h> #include <ESPAsyncTCP.h> #include <ESPAsyncWebServer.h> #include <AsyncElegantOTA.h>
const char\* ssid = "\*\*\*\*"; const char\* ssid_pwd = "\*\*\*\*";
AsyncWebServer server(80);
void setup(void) { Serial.begin(115200); // 设置WiFi工作模式 WiFi.mode(WIFI_STA); // 连接WiFi WiFi.begin(ssid, ssid_pwd); Serial.println("");
// 等待WiFi连接 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()); // 注册Web服务器路由 server.on("/", HTTP_GET, [](AsyncWebServerRequest \*request) { request->send(200, "text/plain", "Hi! I am ESP8266."); }); // 启动OTA服务 AsyncElegantOTA.begin(&server); // Start ElegantOTA // 启动Web服务器 server.begin(); Serial.println("HTTP server started"); }
void loop(void) {
}
|
下载固件后,通过串口信息可以查询到ESP8266连接到WiFi后分配到的IP地址,然后在浏览器输入:
http://ESP8266IP地址/update
即可打开Web固件更新页面:

下面代码为甚至OTA升级的新固件代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227
| #include <Arduino.h> #include <ESP8266WiFi.h> #include <ESPAsyncTCP.h> #include <ESPAsyncWebServer.h> #include <AsyncElegantOTA.h>
// Replace with your network credentials const char* ssid = "*****"; const char* ssid_pwd= "*****";
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 purposes Serial.begin(115200);
pinMode(ledPin, OUTPUT); digitalWrite(ledPin, LOW); // Connect to Wi-Fi WiFi.begin(ssid, ssid_pwd); 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_P(200, "text/html", index_html, processor); });
// Start ElegantOTA AsyncElegantOTA.begin(&server); // Start server server.begin(); }
void loop() { ws.cleanupClients(); digitalWrite(ledPin, ledState); }
|
在Arduino中,生成的固件步骤如下:

生成的固件储存的Arduino IDE当前代码目录下。
最后通过Web页面上传新的OTA固件即可完成固件升级。

升级完成后,新的固件运行结果如下:

文章来源: https://iotsmart.blog.csdn.net/article/details/127628091
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!