Advertisement

ESP32网络编程-OTA方式升级固件(基于Arduino IDE)

阅读量:

OTA方式升级固件(基于Arduino IDE)

文章目录

采用Arduino IDE平台的固件升级方法进行ESP32系统更新优化

本节将详细介绍ESP32的OTA功能特点及其实现原理

具体实现步骤如下

  1. ESP32 OTA功能解析

ESP32以其独特的编程魅力受到广泛关注,主要通过Over-The-Air(OTA)方式进行固件更新。本文旨在详细阐述如何在Arduino IDE环境中完成固件升级操作。

1、ESP32的OTA介绍

固件更新支持 Wi-Fi 下载并安装最新的版本到 ESP32 设备上,并不需要将设备与计算机建立连接。

在无法进行物理访问的情况下, 该系统会自动启用 OTA 功能以发挥其作用. 另一方面, 在维护过程中对每个 ESP 模块进行更新的操作时间得到了显著的减少.

在OTA平台中作为核心优势,单一中心节点能够同时发送至该网络内的多个ESP节点。

该方案的一个不足之处在于,在所有上传的固件代码中都需包含相应的OTA码条目(OTAs),以便后续更新时能够应用这些码条目。

2、OTA升级固件方式

在 ESP32 中实现 OTA 功能有两种方法:

  • 基本OTA:基于Arduino IDE提供的网络接口实现固件升级
  • Web页面更新:利用网络浏览器完成固件的更新操作

每一种都有其自身的优点,因此您可以使用最适合您的项目的一种。

本文将详细阐述完成基本 OTA 的流程。在下一篇文章中将对 Web 方式更新固件进行详细讨论。

3、软件准备

  • Arduino IDE

在前面的文章中,如何搭建ESP32的Arduino IDE开环境,主参考:

ESP32-Arduino-开发实例:Arduino开发环境配置建立

4、硬件准备

  • ESP32开发板
  • LED
  • 220欧姆电阻

5、代码实现

在Arduino IDE中,通过Basic OTA方式升级固件按如下步骤执行:

1)第一步,在计算机上安装Python 2.7.x 系列程序。

第二步是通过串口通信发送Basic OTA固件。这一步骤旨在支持后续通过OTA方式实现升级。

因ESP32默认固件无法通过OTA方式进行固件升级而受限,在此情况下,则需将Basic OTA固件上传至ESP32装置中进行安装配置。具体而言,在文件管理界面下可找到所需代码文件的具体位置为:File > Examples > ArduinoOTA > BasicOTA

在这里插入图片描述

在执行固件上传操作前,需要修改相关网络凭证变量,并确保ESP32能够接入现有网络。

复制代码
    const char* ssid = "..........";
    const char* password = "..........";

修改完成之后,便可以上传固件代码了:

复制代码
    #include <WiFi.h>
    #include <ESPmDNS.h>
    #include <WiFiUdp.h>
    #include <ArduinoOTA.h>
    
    const char* ssid = "..........";
    const char* password = "..........";
    
    void setup() {
      Serial.begin(115200);
      Serial.println("Booting");
      WiFi.mode(WIFI_STA);
      WiFi.begin(ssid, password);
      while (WiFi.waitForConnectResult() != WL_CONNECTED) {
    Serial.println("Connection Failed! Rebooting...");
    delay(5000);
    ESP.restart();
      }
    
      // Port defaults to 3232
      // ArduinoOTA.setPort(3232);
    
      // Hostname defaults to esp3232-[MAC]
      // ArduinoOTA.setHostname("myesp32");
    
      // No authentication by default
      // ArduinoOTA.setPassword("admin");
    
      // Password can be set with it's md5 value as well
      // MD5(admin) = 21232f297a57a5a743894a0e4a801fc3
      // ArduinoOTA.setPasswordHash("21232f297a57a5a743894a0e4a801fc3");
    
      ArduinoOTA
    .onStart([]() {
      String type;
      if (ArduinoOTA.getCommand() == U_FLASH)
        type = "sketch";
      else // U_SPIFFS
        type = "filesystem";
    
      // NOTE: if updating SPIFFS this would be the place to unmount SPIFFS using SPIFFS.end()
      Serial.println("Start updating " + type);
    })
    .onEnd([]() {
      Serial.println("\nEnd");
    })
    .onProgress([](unsigned int progress, unsigned int total) {
      Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
    })
    .onError([](ota_error_t error) {
      Serial.printf("Error[%u]: ", error);
      if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed");
      else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed");
      else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed");
      else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed");
      else if (error == OTA_END_ERROR) Serial.println("End Failed");
    });
    
      ArduinoOTA.begin();
    
      Serial.println("Ready");
      Serial.print("IP address: ");
      Serial.println(WiFi.localIP());
    }
    
    void loop() {
      ArduinoOTA.handle();
    }

此时,请使用 115200 波特率启动串行监视器。 然后按下 ESP32 上的 EN 键。 如果操作正常,请留意路由器分配的动态 IP 地址,并记录下来。

3)第三步,通过Arduino IDE的网络端口上传新的ESP32固件。

现在,让我们通过无线方式上传一个新的固件代码。

请记住,在上传的每个草图中都必须包含OTA代码。否则,在执行下一次无线上传时将无法实现其OTA能力。因此,请建议修改之前的代码以支持新的版本。

下面将LED闪烁功能添加到新的固件代码中。

复制代码
    #include <WiFi.h>
    #include <ESPmDNS.h>
    #include <WiFiUdp.h>
    #include <ArduinoOTA.h>
    
    const char* ssid = "..........";
    const char* password = "..........";
    
    //variabls for blinking an LED with Millis
    const int led = 2; // ESP32 Pin to which onboard LED is connected
    unsigned long previousMillis = 0;  // will store last time LED was updated
    const long interval = 1000;  // interval at which to blink (milliseconds)
    int ledState = LOW;  // ledState used to set the LED
    
    void setup() {
    
    pinMode(led, OUTPUT);
      
      Serial.begin(115200);
      Serial.println("Booting");
      WiFi.mode(WIFI_STA);
      WiFi.begin(ssid, password);
      while (WiFi.waitForConnectResult() != WL_CONNECTED) {
    Serial.println("Connection Failed! Rebooting...");
    delay(5000);
    ESP.restart();
      }
    
      // Port defaults to 3232
      // ArduinoOTA.setPort(3232);
    
      // Hostname defaults to esp3232-[MAC]
      // ArduinoOTA.setHostname("myesp32");
    
      // No authentication by default
      // ArduinoOTA.setPassword("admin");
    
      // Password can be set with it's md5 value as well
      // MD5(admin) = 21232f297a57a5a743894a0e4a801fc3
      // ArduinoOTA.setPasswordHash("21232f297a57a5a743894a0e4a801fc3");
    
      ArduinoOTA
    .onStart([]() {
      String type;
      if (ArduinoOTA.getCommand() == U_FLASH)
        type = "sketch";
      else // U_SPIFFS
        type = "filesystem";
    
      // NOTE: if updating SPIFFS this would be the place to unmount SPIFFS using SPIFFS.end()
      Serial.println("Start updating " + type);
    })
    .onEnd([]() {
      Serial.println("\nEnd");
    })
    .onProgress([](unsigned int progress, unsigned int total) {
      Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
    })
    .onError([](ota_error_t error) {
      Serial.printf("Error[%u]: ", error);
      if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed");
      else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed");
      else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed");
      else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed");
      else if (error == OTA_END_ERROR) Serial.println("End Failed");
    });
    
      ArduinoOTA.begin();
    
      Serial.println("Ready");
      Serial.print("IP address: ");
      Serial.println(WiFi.localIP());
    }
    
    void loop() {
      ArduinoOTA.handle();  
      
    //loop to blink without delay
      unsigned long currentMillis = millis();
      if (currentMillis - previousMillis >= interval) {
      // save the last time you blinked the LED
      previousMillis = currentMillis;
      // if the LED is off turn it on and vice-versa:
      ledState = not(ledState);
      // set the LED with the ledState of the variable:
      digitalWrite(led,  ledState);
      }
    
    }

建议避免采用delay()函数来控制LED闪烁。原因在于delay()函数会导致程序暂停运行。若在ESP32暂停等待Delay()完成时生成下一个OTA请求,则您的程序将无法接收到该请求。

复制上述代码到Arduino IDE后,在选项菜单中选择"工具 > 端口"。 在your_esp_ip_address位置搜索如下的内容: esp32-xxxxxx. 若未发现该内容,请重启IDE以获取最新配置文件.

在这里插入图片描述

选择端口并按上传按钮。 固件将在几秒钟内上传。 板载 LED 应开始闪烁。

在这里插入图片描述

全部评论 (0)

还没有任何评论哟~