ESP8266 OTA (Over-the-Air) 升级 – AsyncElegantOTA (VS Code + PlatformIO)

原文:https://randomnerdtutorials.com/esp8266-nodemcu-ota-over-the-air-vs-code/

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

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

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

推荐阅读:ESP32 和 ESP8266 的 VS Code 和 PlatformIO IDE 入门

我们有一个类似的 ESP32 开发板教程:ESP32 OTA(无线)更新 – AsyncElegantOTA(VS Code + PlatformIO)

概述

本教程涵盖:

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

OTA(无线)编程

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

执行 OTA 更新的方法有多种。在本教程中,我们将介绍如何使用AsyncElegantOTA 库执行此操作。我们认为,这是执行 OTA 更新的最佳和最简单的方法之一。

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

OTA编程唯一的缺点是你需要在你上传的每个草图中添加OTA的代码,这样你以后才能使用OTA。对于 AsyncElegantOTA 库,它仅包含三行代码。

AsyncElegantOTA 库

如前所述,使用 ESP8266 板进行 OTA 编程有多种选择。例如,在 Arduino IDE 中的Examples文件夹下,有BasicOTA示例(对我们来说效果不佳);以及来自不同库的许多其他示例。

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

  • 它与 ESPAsyncWebServer 库兼容;

  • 您只需添加三行代码即可将 OTA 功能添加到您的“常规”异步 Web 服务器;

  • 它不仅允许您将新固件更新到电路板,还可以将文件更新到 ESP8266 文件系统 (LittleFS);

  • 它提供了一个漂亮而现代的网络服务器界面;

  • 它工作得非常好。

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

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

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

  1. 我在项目的platformio.ini文件中包含AsyncElegantOTAESPAsyncTCPESPAsyncWebServer库;

  1. 在代码顶部包含 AsyncElegantOTA 库:#include <AsyncElegantOTA.h>;

  1. 添加这一行AsyncElegantOTA.begin(&server);前服务器.开始();

  1. 打开浏览器并转到http://<IP 地址>/更新, 在哪里<IP地址>是你的 ESP8266 IP 地址。

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

OTA Web 更新程序如何工作?

  • 第一个草图应该通过串口上传。此草图应包含创建 OTA Web 更新程序的代码,以便您稍后可以使用浏览器上传代码。

  • OTA Web Updater sketch 创建了一个网络服务器,您可以访问它以通过网络浏览器上传新的 sketch。

  • 然后,您需要在上传的每个草图中实施 OTA 例程,以便您能够通过无线方式进行下一次更新/上传。

  • 如果您在没有 OTA 例程的情况下上传代码,您将无法再访问网络服务器并通过无线方式上传新草图。

安装 AsyncElegantOTA 库(VS Code + PIO)

在本教程中,我们将使用 VS Code + PIO 对 ESP8266 进行编程。如果您想使用 Arduino IDE,请遵循下一个教程: ESP8266 NodeMCU OTA(空中下载)更新 – 使用 Arduino IDE 的 AsyncElegantOTA

要使用 AsyncElegantOTA 库,请将其包含在您的platformio.ini文件中。您还需要包含 ESPAsyncWebServer 库。添加这些库如下:

lib_deps = ESP Async WebServer
  ayushsharma82/AsyncElegantOTA @ ^2.2.5

AsyncElegantOTA ESP8266 基本示例

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

编辑您的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>constchar* ssid ="REPLACE_WITH_YOUR_SSID";constchar* password ="REPLACE_WITH_YOUR_PASSWORD";

AsyncWebServer server(80);voidsetup(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 ElegantOTA
  server.begin();
  Serial.println("HTTP server started");}voidloop(void){}

查看原始代码

插入您的网络凭据,代码应该立即运行:

constchar* ssid ="REPLACE_WITH_YOUR_SSID";constchar* password ="REPLACE_WITH_YOUR_PASSWORD";

代码如何运作

首先,包括必要的库:

#include<Arduino.h>#include<ESP8266WiFi.h>#include<ESPAsyncTCP.h>#include<ESPAsyncWebServer.h>#include<AsyncElegantOTA.h>

在以下变量中插入您的网络凭据,以便 ESP8266 可以连接到您的本地网络。

constchar* ssid ="REPLACE_WITH_YOUR_SSID";constchar* password ="REPLACE_WITH_YOUR_PASSWORD";

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

AsyncWebServer server(80);

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

Serial.begin(115200);

初始化 Wi-Fi:

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

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

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

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

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

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

最后,初始化服务器:

server.begin();

访问网络服务器

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

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

现在,假设您想修改您的 Web 服务器代码。要通过 OTA 做到这一点,请转到 ESP IP 地址,然后是“/update”. 应加载以下网页。

按照接下来的部分学习如何使用 AsyncElegantOTA 上传新固件。

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

您通过 OTA 上传的每个文件都应为 .bin 格式。编译代码时,VS Code 会自动为您的项目生成 .bin 文件。该文件称为 firmware.bin,它保存在以下路径的项目文件夹中(或类似路径,具体取决于您使用的开发板):

.pio/build/esp12e/ firmware.bin

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

上传新的 Web 服务器草图

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

1. 将以下代码复制到您的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<AsyncElegantOTA.h>// Replace with your network credentialsconstchar* ssid ="REPLACE_WITH_YOUR_SSID";constchar* password ="REPLACE_WITH_YOUR_PASSWORD";

bool ledState =0;constint ledPin =2;// Create AsyncWebServer object on port 80
AsyncWebServer server(80);
AsyncWebSocket ws("/ws");constchar 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:0auto;}.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:22px #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";voidnotifyClients(){
  ws.textAll(String(ledState));}voidhandleWebSocketMessage(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();}}}voidonEvent(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;}}voidinitWebSocket(){
  ws.onEvent(onEvent);
  server.addHandler(&ws);}

String processor(const String& var){
  Serial.println(var);if(var =="STATE"){if(ledState){return"ON";}else{return"OFF";}}returnString();}voidsetup(){// 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_P(200,"text/html", index_html, processor);});// Start ElegantOTA
  AsyncElegantOTA.begin(&server);// Start server
  server.begin();}voidloop(){
  ws.cleanupClients();digitalWrite(ledPin, ledState);}

查看原始代码

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

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

2. 按如下方式编辑您的platformio.ini文件:

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

2.保存并编译您的代码——点击构建图标。

3 . 现在,在 VS Code 的资源管理器选项卡中,您可以检查以下路径(或类似路径)的项目文件夹下是否有firmware.bin文件:

.pio/build/esp12e/ firmware.bin

4.现在您只需使用 ElegantOTA 页面上传该文件。转到您的 ESP IP 地址,然后是/update. 确保选择了固件选项。

5.单击 “选择文件”,浏览计算机中的文件夹并选择项目文件。

6.等到进度条达到 100%。

7.完成后,单击返回按钮。

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

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

因为我们还为这个新的网络服务器添加了 OTA 功能,所以如果需要的话,我们可以在未来上传一个新的草图。您只需要转到 ESP8266 IP 地址,然后是/update.

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

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

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

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

带有来自文件系统 (LittleFS) 文件的 Web 服务器

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

为了向您展示如何做到这一点,我们将创建一个新的网络服务器来提供来自 LittleFS 的文件:HTML、CSS 和 JavaScript 文件,以构建一个远程控制 ESP8266 GPIO 的网页。

将以下代码复制到您的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 credentialsconstchar* ssid ="REPLACE_WITH_YOUR_SSID";constchar* 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#defineNUM_OUTPUTS4// Assign each GPIO to an outputint outputGPIOs[NUM_OUTPUTS]={2,4,12,14};// Initialize LittleFSvoidinitLittleFS(){if(!LittleFS.begin()){
    Serial.println("An error has occurred while mounting LittleFS");}
  Serial.println("LittleFS mounted successfully");}// Initialize WiFivoidinitWiFi(){
  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;}voidnotifyClients(String state){
  ws.textAll(state);}voidhandleWebSocketMessage(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());}}}voidonEvent(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;}}voidinitWebSocket(){
  ws.onEvent(onEvent);
  server.addHandler(&ws);}voidsetup(){// Serial port for debugging purposes
  Serial.begin(115200);// Set GPIOs as outputsfor(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();}voidloop(){
  ws.cleanupClients();}

查看原始代码

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

constchar* ssid ="REPLACE_WITH_YOUR_SSID";constchar* 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

更新固件

插入网络凭据后,保存并编译代码。

转到 ESP IP 地址,然后/update并如前所示上传新固件。

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

更新文件系统

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

在 VS Code 中,单击PIO图标并转到Project Tasks > env:esp12e(或类似的)> Platform > Build Filesystem Image这将从保存在数据文件夹中的文件创建一个.bin文件。

构建文件系统映像后,您应该在以下路径(或类似路径)中有一个littlefs.bin文件:

.pio/build/esp12e/ littlefs.bin

这是您应该上传以更新文件系统的文件。

转到您的 ESP IP 地址,然后是 /update. 确保选择了 文件系统 选项并选择littlefs.bin文件。

上传成功后,点击返回按钮。并转到根(/) URL。

您应该可以访问以下使用Web Socket协议控制 ESP8266 输出的网页。

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

如果你需要更新你的项目,你只需要转到你的 ESP8266 IP 地址,然后是/update.

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

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值