Руководство по OTA-программированию ESP8266 NodeMCU в Arduino IDE

OTA-программирование ESP8266 (Over-The-Air) в Arduino IDE

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

  1. Установка Python 2.7.x: Первый шаг — установить серию Python 2.7.x на ваш компьютер.

  2. Загрузка базовой OTA-прошивки через серийный порт: Загрузите скетч, содержащий OTA-прошивку, через серийный интерфейс. Это обязательный шаг для выполнения последующих обновлений по воздуху.

  3. Загрузка нового скетча по воздуху (Over-The-Air): Теперь вы можете загружать новые скетчи на ESP8266 из Arduino IDE по воздуху.

Шаг 1: Установка Python 2.7.x

Для использования функции OTA необходимо сначала установить Python 2.7.x, если он ещё не установлен на вашем компьютере.

Скачайте Python 2.7.x для Windows (MSI-установщик) с официального сайта Python.

Скачивание Python 2.7.x

Запустите установщик и пройдите через мастер установки.

Установка Python 2.7.x на ПК

Убедитесь, что в разделе «Customize Python 2.7.X» включена опция «Add python.exe to Path».

Включение опции Add Python.exe to Path при установке Python

Шаг 2: Загрузка базовой OTA-прошивки через серийный порт

Поскольку заводская прошивка ESP8266 не поддерживает функцию OTA-обновления, сначала необходимо загрузить OTA-прошивку на ESP8266 через серийный интерфейс.

Это обязательный шаг для выполнения последующих обновлений по воздуху.

Дополнение ESP8266 для Arduino IDE включает OTA-библиотеку, а также пример BasicOTA. Просто перейдите в File > Examples > ArduinoOTA > BasicOTA.

Открытие скетча BasicOTA в Arduino IDE

Прежде чем начать загрузку скетча, вам необходимо изменить следующие две переменные, указав учётные данные вашей сети, чтобы 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-адрес, назначенный вашим маршрутизатором. Запишите его.

Запишите IP-адрес, назначенный ESP8266 NodeMCU

Шаг 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.

Выбор OTA-порта в Arduino IDE

Выберите порт и нажмите кнопку «Upload» (Загрузить). Новый скетч загрузится за считанные секунды. Встроенный светодиод должен начать мигать.

Мигание встроенного светодиода ESP8266 NodeMCU