,
Una característica muy útil en el campo del IoT es la posibilidad de programar un microcontrolador conectado, como un ESP8266, a través de Wi-Fi. Esta técnica se denomina programación Over-The-Air (OTA).
Material
- NodoMCU ESP8266
- Cable USB A macho
- Ordenador
- Red WiFi
Cómo funciona
En principio, el ESP8266 NodeMCU se programa a través del puerto USB. El ordenador comunica el programa al microcontrolador. Cuando dos dispositivos están conectados a la misma red Wi-Fi, pueden comunicarse entre sí. Esto significa que se puede cargar código a través de la red Wi-Fi sin tener que conectarse a cada microcontrolador.
También es posible cargar un código al NodeMCU cuando está configurado como un Punto de Acceso Wi-Fi. En este caso, el ordenador utilizado para la programación debe estar conectado a la red NodeMCU.
Añadir el firmware ArduinoOTA
La biblioteca ArduinoOTA está disponible al instalar el controlador ESP8266. Para implementar la programación OTA, necesita instalar el firmware. Para ello, puede utilizar el ejemplo BasicOTA.ino disponible en el IDE de Arduino.
Asegúrate de sustituir ssid y password por las credenciales de tu red WiFi.
#include <ESP8266WiFi.h> #include <ESP8266mDNS.h> #include <WiFiUdp.h> #include <ArduinoOTA.h> #ifndef STASSID #define STASSID "your-ssid" #define STAPSK "your-password" #endif const char* ssid = STASSID; const char* password = STAPSK; 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_FS type = "filesystem"; } // NOTE: if updating FS this would be the place to unmount FS using FS.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(); }
Asegúrese de anotar la dirección IP local del dispositivo (aquí: 192.168.1.78).
Una vez que haya cargado este código a través de serie, usted será capaz de cargar un código a través de Wifi. Pulsa el botón RST o EN en tu ESP y reinicia el IDE Arduino.
Edite su programa antes de subirlo
Colocamos el código de inicialización en la función initOTA(). Así será fácil copiarlo para otros proyectos. Y añadiremos una pantalla en el puerto serie para comprobar que el código ha sido modificado.
ATENCIÓN: El código para la inicialización de ArduinoOTA debe estar presente en todos los códigos que subas o perderás la posibilidad de hacer transmisión aérea.
#include <ESP8266WiFi.h> #include <ESP8266mDNS.h> #include <WiFiUdp.h> #include <ArduinoOTA.h> const char* ssid = "*******"; const char* password = "********"; unsigned long previousMillis; 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(); } initOTA(); Serial.println("Ready"); Serial.print("IP address: "); Serial.println(WiFi.localIP()); } void loop() { ArduinoOTA.handle(); if (millis() - previousMillis >= 500) { previousMillis = millis(); Serial.println(F("Code has been update")); } } void initOTA() { // 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_FS type = "filesystem"; } // NOTE: if updating FS this would be the place to unmount FS using FS.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(); }
Una vez que haya modificado su código, en «Tools> Port», seleccione su tarjeta en los puertos de red. (si no aparece el puerto de red, consulte el capítulo siguiente).
A continuación, puede cargar su código como lo haría con la comunicación serie.
Seleccione de nuevo el puerto serie y abra el monitor serie para comprobar que se ha modificado el código.
Si el puerto de red no se muestra en el IDE de Arduino
Si el puerto de red no está presente en las opciones del IDE de Arduino, tendrás que hacer una pequeña manipulación. Debes ir al Centro de redes y recursos compartidos
A continuación, ve a «Modificar la configuración del mapa».
Haga clic con el botón derecho en su red y vaya a propiedades
A continuación, puede desmarcar la casilla «Protocolo de Internet versión 6 (TCP
Si vuelves al IDE de Arduino, en » Tool > Port» deberías ver la opción de puerto de red.
Puede volver a comprobar IPv6 una vez que se reconozca su puerto de red.
Bonus: Visualización de mensajes de serie en OTA
La posibilidad de cargar un programa a través de Wi-Fi es muy útil, pero hay que tener en cuenta que se pierde la posibilidad de depurar con el monitor serie. Es posible crear una interfaz web en la que mostrar información del NodoMCU ESP8266.
Veremos aquí el uso de la librería RemoteDebug que nos permitirá conectarnos en telnet al microcontrolador y recuperar los mensajes enviados.
- Empieza por instalar la biblioteca descargando el ZIP o a través del gestor de bibliotecas.
- Crear un objeto RemoteDebug Debug; después de incluir el objeto
- Inicializar la depuración con Debug.begin(«ESP8266»);
- Luego reemplaza todos los Serial.print por Debug.print
#include <ESP8266WiFi.h> #include <ESP8266mDNS.h> #include <WiFiUdp.h> #include <ArduinoOTA.h> #include <RemoteDebug.h> const char* ssid = "******"; const char* password = "*******"; RemoteDebug Debug; unsigned long previousMillis; 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(); } // init remote debug Debug.begin("ESP8266"); initOTA(); Serial.println("Ready"); Serial.print("IP address: "); Serial.println(WiFi.localIP()); } void loop() { ArduinoOTA.handle(); Debug.handle(); if (millis() - previousMillis >= 500) { previousMillis = millis(); Debug.println(F("Code has been update")); } } void initOTA() { // Port defaults to 8266 // ArduinoOTA.setPort(8266); // Hostname defaults to esp8266-[ChipID] //ArduinoOTA.setHostname("ESP8266"); // 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_FS type = "filesystem"; } // NOTE: if updating FS this would be the place to unmount FS using FS.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(); }
Para ver los mensajes enviados a través de RemoteDebug, utilizaremos el software PuTTy que hemos visto varias veces antes. Para esta aplicación, configuraremos PuTTy en telnet utilizando la dirección IP recuperada del monitor serie.