风筝
发表于: 2022-11-7 19:53:23 | 显示全部楼层

ESP32其中一个优势就是可以无线更新其固件。这种编程方式称为空中编程(OTA,Over-The-Air)。


ESP32中的OTA编程是什么?

OTA编程使您可以通过Wi-Fi更新/上传到ESP32的新程序,而无需通过USB将ESP32连接到计算机。


当没有物理访问ESP模块时,OTA功能就派上用场。此外,它减少了在维护过程中更新每个ESP模块所需的时间。


OTA的一个主要优点是,单个中间位置可以将更新发送给同一网络上的多个ESP。唯一的缺点是,您必须在上传的每个草图中包含一段OTA代码,以便在下一个更新中使用OTA。


在ESP32中实施OTA的方法

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

●    基本OTA  - 使用Arduino IDE提供更新。

●    网页更新OTA  - 更新是通过网页浏览器提供的。

每种方式都有自己的优势,因此您可以选用最适合您项目的其中一种。


本文将为您介绍实现基本OTA的过程。 如果您想了解有关网页更新OTA的更多信息,请查看本篇文章。


3个ESP32使用OTA的简单步骤

1.  安装Python 2.7.X系列:第一步是在计算机上安装Python 2.7.x系列。

2.  串口上传基本的OTA固件:串口上传包含OTA固件的草图。这是为了执行OTA后续更新的必要步骤。

3.  上载新的草图:您现在可以从Arduino IDE将新草图上传到ESP32。


第1步:安装Python 2.7.x系列

要使用OTA功能,如果尚未在计算机上安装Python 2.7.x,则必须首先安装。从Python官方网站下载Windows(MSI安装程序)的Python 2.7.x

Download-Python-2.7.x-Series.jpg


启动安装程序并继续安装向导。

Install-Python-2.7.x-Series-On-PC.jpg


确保在自定义Python 2.7.x节中启用“Add python.exe to Path”选项。

Enable-Add-Python.exe-to-Path-While-Python-Installation.jpg


第2步:串口上传基本的OTA固件

由于ESP32的出厂镜像中未带OTA升级功能,因此您必须首先通过串口将OTA固件加载到ESP32上。


首先需要更新固件以执行OTA后续更新。Arduino IDE的ESP32附加组件包括一个OTA库以及一个基本示例。只需导航到File > Examples > ArduinoOTA > BasicOTA

Open-ESP32-BasicOTA-Sketch-In-Arduino-IDE.jpg


在开始上传草图之前,您必须使用网络凭据修改以下两个变量,以便ESP8266可以连接到现有网络。

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

完成后,继续上传草图。

  1. #include <WiFi.h>
  2. #include <ESPmDNS.h>
  3. #include <WiFiUdp.h>
  4. #include <ArduinoOTA.h>

  5. const char* ssid = "..........";
  6. const char* password = "..........";

  7. void setup() {
  8.   Serial.begin(115200);
  9.   Serial.println("Booting");
  10.   WiFi.mode(WIFI_STA);
  11.   WiFi.begin(ssid, password);
  12.   while (WiFi.waitForConnectResult() != WL_CONNECTED) {
  13.     Serial.println("Connection Failed! Rebooting...");
  14.     delay(5000);
  15.     ESP.restart();
  16.   }

  17.   // Port defaults to 3232
  18.   // ArduinoOTA.setPort(3232);

  19.   // Hostname defaults to esp3232-[MAC]
  20.   // ArduinoOTA.setHostname("myesp32");

  21.   // No authentication by default
  22.   // ArduinoOTA.setPassword("admin");

  23.   // Password can be set with it's md5 value as well
  24.   // MD5(admin) = 21232f297a57a5a743894a0e4a801fc3
  25.   // ArduinoOTA.setPasswordHash("21232f297a57a5a743894a0e4a801fc3");

  26.   ArduinoOTA
  27.     .onStart([]() {
  28.       String type;
  29.       if (ArduinoOTA.getCommand() == U_FLASH)
  30.         type = "sketch";
  31.       else // U_SPIFFS
  32.         type = "filesystem";

  33.       // NOTE: if updating SPIFFS this would be the place to unmount SPIFFS using SPIFFS.end()
  34.       Serial.println("Start updating " + type);
  35.     })
  36.     .onEnd([]() {
  37.       Serial.println("\nEnd");
  38.     })
  39.     .onProgress([](unsigned int progress, unsigned int total) {
  40.       Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
  41.     })
  42.     .onError([](ota_error_t error) {
  43.       Serial.printf("Error[%u]: ", error);
  44.       if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed");
  45.       else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed");
  46.       else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed");
  47.       else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed");
  48.       else if (error == OTA_END_ERROR) Serial.println("End Failed");
  49.     });

  50.   ArduinoOTA.begin();

  51.   Serial.println("Ready");
  52.   Serial.print("IP address: ");
  53.   Serial.println(WiFi.localIP());
  54. }

  55. void loop() {
  56.   ArduinoOTA.handle();
  57. }
复制代码

现在,打开串口显示器,然后按ESP32上的EN按钮。 如果一切正常,您应该看到路由器分配的动态IP地址。

Note-Down-IP-Address-Allotted-to-ESP32.jpg


第3步:上传新草图

现在,让我们上传一个新的草图。请记住,您必须在上传的每个草图中包含OTA代码。 否则,您将失去OTA功能,并且将无法执行下一次的空中编程。 因此,建议您修改前面的代码以包含新代码。


例如,我们将在基本的OTA代码中包含一个简单的LED闪烁草图。 切记使用网络凭据修改SSID和密码变量。

  1. #include <WiFi.h>
  2. #include <ESPmDNS.h>
  3. #include <WiFiUdp.h>
  4. #include <ArduinoOTA.h>

  5. const char* ssid = "..........";
  6. const char* password = "..........";

  7. //variabls for blinking an LED with Millis
  8. const int led = 2; // ESP32 Pin to which onboard LED is connected
  9. unsigned long previousMillis = 0;  // will store last time LED was updated
  10. const long interval = 1000;  // interval at which to blink (milliseconds)
  11. int ledState = LOW;  // ledState used to set the LED

  12. void setup() {

  13. pinMode(led, OUTPUT);
  14.   
  15.   Serial.begin(115200);
  16.   Serial.println("Booting");
  17.   WiFi.mode(WIFI_STA);
  18.   WiFi.begin(ssid, password);
  19.   while (WiFi.waitForConnectResult() != WL_CONNECTED) {
  20.     Serial.println("Connection Failed! Rebooting...");
  21.     delay(5000);
  22.     ESP.restart();
  23.   }

  24.   // Port defaults to 3232
  25.   // ArduinoOTA.setPort(3232);

  26.   // Hostname defaults to esp3232-[MAC]
  27.   // ArduinoOTA.setHostname("myesp32");

  28.   // No authentication by default
  29.   // ArduinoOTA.setPassword("admin");

  30.   // Password can be set with it's md5 value as well
  31.   // MD5(admin) = 21232f297a57a5a743894a0e4a801fc3
  32.   // ArduinoOTA.setPasswordHash("21232f297a57a5a743894a0e4a801fc3");

  33.   ArduinoOTA
  34.     .onStart([]() {
  35.       String type;
  36.       if (ArduinoOTA.getCommand() == U_FLASH)
  37.         type = "sketch";
  38.       else // U_SPIFFS
  39.         type = "filesystem";

  40.       // NOTE: if updating SPIFFS this would be the place to unmount SPIFFS using SPIFFS.end()
  41.       Serial.println("Start updating " + type);
  42.     })
  43.     .onEnd([]() {
  44.       Serial.println("\nEnd");
  45.     })
  46.     .onProgress([](unsigned int progress, unsigned int total) {
  47.       Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
  48.     })
  49.     .onError([](ota_error_t error) {
  50.       Serial.printf("Error[%u]: ", error);
  51.       if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed");
  52.       else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed");
  53.       else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed");
  54.       else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed");
  55.       else if (error == OTA_END_ERROR) Serial.println("End Failed");
  56.     });

  57.   ArduinoOTA.begin();

  58.   Serial.println("Ready");
  59.   Serial.print("IP address: ");
  60.   Serial.println(WiFi.localIP());
  61. }

  62. void loop() {
  63.   ArduinoOTA.handle();  
  64.   
  65. //loop to blink without delay
  66.   unsigned long currentMillis = millis();
  67.   if (currentMillis - previousMillis >= interval) {
  68.   // save the last time you blinked the LED
  69.   previousMillis = currentMillis;
  70.   // if the LED is off turn it on and vice-versa:
  71.   ledState = not(ledState);
  72.   // set the LED with the ledState of the variable:
  73.   digitalWrite(led,  ledState);
  74.   }

  75. }
复制代码

将上述草图复制到您的Arduino IDE后,导航到Tools > Port 菜单。 查找类似的东西:esp32-xxxxxx at your_esp_ip_address。 如果您无法找到它,则可能需要重新启动IDE。

Select-OTA-Port-in-Arduino-IDE.jpg


选择端口,然后点击上传按钮。 新草图将在几秒钟内上传。完成后板载的LED应开始闪烁。


跳转到指定楼层
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

主题 54 | 回复: 107



手机版|

GMT+8, 2024-11-21 16:58 , Processed in 0.056645 second(s), 8 queries , Gzip On, MemCache On. Powered by Discuz! X3.5

YiBoard一板网 © 2015-2022 地址:河北省石家庄市长安区高营大街 ( 冀ICP备18020117号 )

快速回复 返回顶部 返回列表