| ESP8266其中一个优势就是可以无线更新其固件。这种编程方式称为空中编程(OTA,Over-The-Air)。 
 ESP8266中的OTA编程是什么? OTA编程使您可以通过Wi-Fi更新/上传到ESP8266的新程序,而无需通过USB将ESP8266连接到计算机。 
 当没有物理访问ESP模块时,OTA功能就派上用场。此外,它减少了在维护过程中更新每个ESP模块所需的时间。 
 OTA的一个主要优点是,单个中间位置可以将更新发送给同一网络上的多个ESP。唯一的缺点是,您必须在上传的每个草图中包含一段OTA代码,以便在下一个更新中使用OTA。 
 3个ESP8266使用OTA的简单步骤 1.  安装Python 2.7.X系列:第一步是在计算机上安装Python 2.7.x系列。 2.  串口上传基本的OTA固件:串口上传包含OTA固件的草图。这是为了执行OTA后续更新的必要步骤。 3.  上载新的草图:您现在可以从Arduino IDE将新草图上传到ESP8266。 
 第1步:安装Python 2.7.x系列 要使用OTA功能,如果尚未在计算机上安装Python 2.7.x,则必须首先安装。 
 从Python官方网站下载Windows(MSI安装程序)的Python 2.7.x。 
  
 启动安装程序并继续安装向导。确保在自定义Python 2.7.x节中启用“Add python.exe to Path”选项。 
  
 第2步:串口上传基本的OTA固件 由于ESP8266的出厂镜像中未带OTA升级功能,因此您必须首先通过串口将OTA固件加载到ESP8266上。 
 首先需要更新固件以执行OTA后续更新。Arduino IDE的ESP8266附加组件包括一个OTA库以及一个基本示例。只需导航到File > Examples > ArduinoOTA > BasicOTA。 
  在开始上传草图之前,您必须使用网络凭据修改以下两个变量,以便ESP8266可以连接到现有网络。 复制代码const char* ssid = "..........";
const char* password = "..........";
完成后,继续上传草图。 复制代码#include <ESP8266WiFi.h>
#include <ESP8266mDNS.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 8266
  // ArduinoOTA.setPort(8266);
  // Hostname defaults to esp8266-[ChipID]
  // ArduinoOTA.setHostname("myesp8266");
  // 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);
  });
  ArduinoOTA.onEnd([]() {
    Serial.println("\nEnd");
  });
  ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
    Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
  });
  ArduinoOTA.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();
}
现在,打开串口显示器,然后按ESP8266上的复位按钮。 如果一切正常,您应该看到路由器分配的动态IP地址。  
  
 第3步:上传新草图 现在,让我们上传一个新的草图。请记住,您必须在上传的每个草图中包含OTA代码。 否则,您将失去OTA功能,并且将无法执行下一次的空中编程。 因此,建议您修改前面的代码以包含新代码。 
 例如,我们将在基本的OTA代码中包含一个简单的LED闪烁草图。 切记使用网络凭据修改SSID和密码变量。 复制代码#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h>
#include <WiFiUdp.h>
#include <ArduinoOTA.h>
const char* ssid = "..........";
const char* password = "..........";
//variabls for blinking an LED with Millis
const int led = D0; // ESP8266 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 8266
  // ArduinoOTA.setPort(8266);
  // Hostname defaults to esp8266-[ChipID]
  // ArduinoOTA.setHostname("myesp8266");
  // 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);
  });
  ArduinoOTA.onEnd([]() {
    Serial.println("\nEnd");
  });
  ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
    Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
  });
  ArduinoOTA.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);
  }
}
 将上述草图复制到您的Arduino IDE后,导航到Tools > Port菜单。 查找类似的东西:sp8266-xxxxxx at your_esp_ip_address。 如果您无法找到它,则可能需要重新启动IDE。 
  
 选择端口,然后点击上传按钮。 新草图将在几秒钟内上传。 这时板载的LED应开始闪烁。 |