
OTA-программирование ESP8266 (Over-The-Air) в Arduino IDE
Одна из лучших особенностей ESP8266 заключается в том, что его прошивку можно обновлять по беспроводной сети. Такой вид программирования называется «Over-The-Air» (OTA) — «по воздуху».
Что такое OTA-программирование в ESP8266?
OTA-программирование позволяет обновлять/загружать новую программу на ESP8266 по Wi-Fi без необходимости подключать ESP8266 к компьютеру через USB.
Функция OTA очень полезна, когда нет физического доступа к модулю ESP. Кроме того, она сокращает время, необходимое для обновления каждого модуля ESP при техническом обслуживании.
Одно из ключевых преимуществ OTA заключается в том, что одна центральная точка может отправить обновление на несколько модулей ESP в одной сети.
Единственный недостаток — вы должны включать OTA-код в каждый скетч, который загружаете, чтобы иметь возможность использовать OTA при следующем обновлении.
3 простых шага для использования OTA с ESP8266
Установка Python 2.7.x: Первый шаг — установить серию Python 2.7.x на ваш компьютер.
Загрузка базовой OTA-прошивки через серийный порт: Загрузите скетч, содержащий OTA-прошивку, через серийный интерфейс. Это обязательный шаг для выполнения последующих обновлений по воздуху.
Загрузка нового скетча по воздуху (Over-The-Air): Теперь вы можете загружать новые скетчи на ESP8266 из Arduino IDE по воздуху.
Шаг 1: Установка Python 2.7.x
Для использования функции OTA необходимо сначала установить Python 2.7.x, если он ещё не установлен на вашем компьютере.
Скачайте Python 2.7.x для Windows (MSI-установщик) с официального сайта Python.
Запустите установщик и пройдите через мастер установки.
Убедитесь, что в разделе «Customize Python 2.7.X» включена опция «Add python.exe to Path».
Шаг 2: Загрузка базовой OTA-прошивки через серийный порт
Поскольку заводская прошивка ESP8266 не поддерживает функцию OTA-обновления, сначала необходимо загрузить OTA-прошивку на ESP8266 через серийный интерфейс.
Это обязательный шаг для выполнения последующих обновлений по воздуху.
Дополнение ESP8266 для Arduino IDE включает OTA-библиотеку, а также пример BasicOTA. Просто перейдите в 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();
}
Теперь откройте монитор порта (Serial Monitor) на скорости 115200 бод и нажмите кнопку RST на ESP8266. Если всё в порядке, вы должны увидеть динамический IP-адрес, назначенный вашим маршрутизатором. Запишите его.
Шаг 3: Загрузка нового скетча по воздуху (Over-The-Air)
Теперь давайте загрузим новый скетч по воздуху.
Помните, что вы должны включать OTA-код в каждый скетч, который загружаете. В противном случае вы потеряете возможность OTA и не сможете выполнить следующую загрузку по воздуху. Поэтому рекомендуется модифицировать предыдущий код, добавив в него ваш новый код.
В качестве примера мы добавим простой скетч мигания светодиодом (Blink) в базовый OTA-код. Не забудьте изменить переменные SSID и password, указав учётные данные вашей сети.
Изменения в коде выделены синим цветом.
#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);
}
}
Обратите внимание, что мы не использовали функцию delay() для мигания светодиода. Это связано с тем, что функция delay() приостанавливает программу. Если следующий OTA-запрос будет сгенерирован, пока ESP8266 находится в паузе, ожидая завершения delay(), ваша программа пропустит этот запрос.
После копирования приведённого выше скетча в Arduino IDE перейдите в Tools > Port. Найдите что-то вроде: esp8266-xxxxxx at your_esp_ip_address. Если вы не можете его найти, возможно, потребуется перезапустить IDE.
Выберите порт и нажмите кнопку «Upload» (Загрузить). Новый скетч загрузится за считанные секунды. Встроенный светодиод должен начать мигать.