До этого урока мы загружали скетчи, подключая плату NodeMCU v3 к компьютеру через USB-разъём. Но используя соединение по WiFi можно загружать скетчи, буквально, «по воздуху». Для этого нужно добавить в вашу программу несколько участков кода и несколько библиотек. Первоначально, этот код придётся загрузить, пользуясь USB-соединением. Но в дальнейшем, можно составить собственный скетч и загрузить его пользуясь WiFi-соединением. Чтобы сохранить возможность загрузки собственных скетчей «по воздуху», в них надо добавить участки кода, для загрузки по WiFi.
Вот как выглядит скетч, для прошивки «по воздуху»
// Прошиваем NodeMCU v3 по воздуху
// ------------------ Эта часть кода должна быть включена в скетч ---------------
#include "ESP8266WiFi.h"
#include "ESP8266mDNS.h"
#include "WiFiUdp.h"
#include "ArduinoOTA.h"
// ------------------ Эти часть кода должна быть включена в скетч ---------------
// ------------------ Эти часть кода должна быть включена в скетч ---------------
// Замените эти константы на имя и пароль WiFi-сети
const char* ssid = "***********";
const char* password = "***********";
// ------------------ Эти часть кода должна быть включена в скетч ---------------
// Далее разместить код основного скетча
void setup() {
// ------------------ Эти часть кода должна быть включена в скетч ---------------
Serial.begin(115200);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
while (WiFi.waitForConnectResult() != WL_CONNECTED) {
Serial.println("Связь не установлена, повторяю попытку...");
delay(5000);
ESP.restart();
}
ArduinoOTA.onStart([]() {
Serial.println("Старт");
});
ArduinoOTA.onEnd([]() {
Serial.println("\nОкончание");
});
ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
Serial.printf("Выполняется: %u%%\r", (progress / (total / 100)));
});
ArduinoOTA.onError([](ota_error_t error) {
Serial.printf("Ошибка[%u]: ", error);
if (error == OTA_AUTH_ERROR) Serial.println("Ошибка аутентификации");
else if (error == OTA_BEGIN_ERROR) Serial.println("Неудачный старт");
else if (error == OTA_CONNECT_ERROR) Serial.println("Соединение прервано");
else if (error == OTA_RECEIVE_ERROR) Serial.println("Ошибка передачи данных");
else if (error == OTA_END_ERROR) Serial.println("Неудачное завершение");
});
ArduinoOTA.begin();
Serial.println("Для прошивки по воздуху готов...");
Serial.print("IP адрес: ");
Serial.println(WiFi.localIP());
// ------------------ Эти часть кода должна быть включена в скетч ---------------
// Далее разместить код основного скетча
}
void loop() {
// ------------------ Эти часть кода должна быть включена в скетч ---------------
ArduinoOTA.handle();
// ------------------ Эти часть кода должна быть включена в скетч ---------------
// Далее разместить код основного скетча
}
После загрузки этого скетча, микроконтроллер NodeMCU подключится к локальной WiFi –сети. В мониторе порта появится сообщение с каким IP он находится в сети.
В меню ArduinoIDE Инструменты/Порт появится дополнительная строчка с IP-адресом, по которому плата NodeMCU подсоединилась к WiFi-сети.
Выберите этот порт и теперь можно осуществить загрузку скетча «по воздуху». Перед компиляцией придётся ещё раз указать пароль локальной WiFi-сети в появившемся окне:
После компиляции начнётся загрузка вашего скетча
Интересно, что загрузка скетча происходит быстрее, чем по USB.
При создании скетчей с возможностью прошивки «по воздуху» надо помнить о следующих правилах:
• Не меняйте команду скорость связи с монитором порта: Serial.begin(115200); Она должна быть 115200.
• Компьютер, с которого происходит загрузка «по воздуху» и контроллер NodeMCU должны быть подключены к одной WiFi-сети.
• Чтобы сохранить возможность прошивки «по воздуху», в вашей программе должны присутствовать участки кода, указанные выше в базовом скетче.
• Порт для прошивки «по воздуху» в Arduino IDE появляется не сразу, для подключения микроконтроллера к WiFI-сети иногда уходит какое-то время.
Пример скетча мигания встроенного светодиода, который сохраняет возможность повторной загрузки «по воздуху»:
// Прошиваем NodeMCU v3 по воздуху
// ------------------ Эта часть кода должна быть включена в скетч ---------------
#include "ESP8266WiFi.h"
#include "ESP8266mDNS.h"
#include "WiFiUdp.h"
#include "ArduinoOTA.h"
// ------------------ Эта часть кода должна быть включена в скетч ---------------
// ------------------ Эта часть кода должна быть включена в скетч ---------------
// Замените эти константы на имя и пароль WiFi-сети
const char* ssid = "***********";
const char* password = "***********";
// ------------------ Эта часть кода должна быть включена в скетч ---------------
// Далее разместить код основного скетча
#define LED_BUILTIN D4
void setup() {
// ------------------ Эта часть кода должна быть включена в скетч ---------------
Serial.begin(115200);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
while (WiFi.waitForConnectResult() != WL_CONNECTED) {
Serial.println("Связь не установлена, повторяю попытку...");
delay(5000);
ESP.restart();
}
ArduinoOTA.onStart([]() {
Serial.println("Старт");
});
ArduinoOTA.onEnd([]() {
Serial.println("\nОкончание");
});
ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
Serial.printf("Выполняется: %u%%\r", (progress / (total / 100)));
});
ArduinoOTA.onError([](ota_error_t error) {
Serial.printf("Ошибка[%u]: ", error);
if (error == OTA_AUTH_ERROR) Serial.println("Ошибка аутентификации");
else if (error == OTA_BEGIN_ERROR) Serial.println("Неудачный старт");
else if (error == OTA_CONNECT_ERROR) Serial.println("Соединение прервано");
else if (error == OTA_RECEIVE_ERROR) Serial.println("Ошибка передачи данных");
else if (error == OTA_END_ERROR) Serial.println("Неудачное завершение");
});
ArduinoOTA.begin();
Serial.println("Для прошивки по воздуху готов...");
Serial.print("IP адрес: ");
Serial.println(WiFi.localIP());
// ------------------ Эта часть кода должна быть включена в скетч ---------------
// Далее разместить код основного скетча
pinMode(LED_BUILTIN, OUTPUT);
}
void loop() {
// ------------------ Эта часть кода должна быть включена в скетч ---------------
ArduinoOTA.handle();
// ------------------ Эта часть кода должна быть включена в скетч ---------------
// Далее разместить код основного скетча
digitalWrite(LED_BUILTIN, HIGH);
delay(1000);
digitalWrite(LED_BUILTIN, LOW);
delay(3000);
}
Добавленные участки кода, отвечающие за мигание светодиода выделены утолщённым подчёркнутым шрифтом.