OTA workaround for missing Arduino IDE OTA Network Port Name
Issue: Losing OTA network name/port/connection after a LAN upload in Arduino IDE or an "[ERROR]: No Answer" result during OTA upload.
I'm a newbie and I've been pulling my hair on this one. I gathered solutions I could get my hands on to correct this issue - gathered them into a workable workaround. I hope this will help someone who is in the same predicament as I am.
As an example I am uploading a simple sketch (of blinking / breathing LEDs) to show how to incorporate OTA upload functionality into a sketch. Please take note of the accompanying comments in the Arduino sketch to guide you in resolving some common issues. Thanks!
`/* OTA Basic Code (with workaround derived from BasicOTA.ino code examples)
-
Issue: Losing OTA network name/port/connection after a LAN upload in Arduino IDE or an "[ERROR]: No Answer" result during upload.
Sugg. workaround (tested with a more common esp8266 board, Bonjour framework, Windows 10, Arduino IDE 1.8.13):
-
Setup: Board: esp8266 by Amico Software: Bonjour, Arduino IDE, Python Bonjour https://support.apple.com/kb/DL999?locale=en_US Arduino IDE (1.8.13 nightly) https://www.arduino.cc/en/main/software Python 3.8.3 https://www.python.org/downloads/windows/
Optional (for diagnostics): Bonjour Browser https://hobbyistsoftware.com/bonjourbrowser -
In your sketch:
- include OTA basic code in the declaration, setup() and main loop() parts:
- Make sure mDNS service is setup, running, and accepting mDNS queries. See
MDNS.begin() function in setup() section of code. - if your esp8266 uses dynamic ip, your ip address may change when your host's lease expires from your router. It helps to update mDNS host/ip regularly in your main loop()). to effect such a change. See MDNS.update() in main loop() section.
-
In your Windows subsystem:
-
Arduino IDE uses mDNS to update its OTA port.
-
Please take note that your PC's DNS cache takes time to build itself. A change in your esp8266 OTA ssid will not be immediately shown. It will take time for your DNS subsystem to register the new name. (ie. your Arduino IDE may show either your previous ssid or none at all). Note: You can lose your port name during periods of inactivity.
You can do the following if you lose your OTA port in Arduino IDE:
- If you didn't change your esp8266 ssid, do a ping to initiate an mDNS request to
your esp8266:
> ping
.local - as soon as you get a ping response, return to your Arduino IDE and check the OTA port. It must be visible by now. - if you changed your ssid, it will help to flush your DNS cache to speed-up the rebuilding of your PC's DNS tables/cache. To flush your DNS cache, use the following DOS command: > ipconfig /flushdns
- If all things fail and you can't wait. Reboot your PC.
- If you didn't change your esp8266 ssid, do a ping to initiate an mDNS request to
your esp8266:
> ping
-
-
-
Reminder: A common mistake is to lose OTA capability in the next OTA session. To prevent this from happening, the OTA basic code MUST ALWAYS be included in your sketch payload (in declarations, setup() and loop() sections of your code).
Other OTA option using python script:
with useful modifications: https://github.com/esp8266/Arduino/blob/master/tools/espota.py
originally by Ivan Grokhotkov: https://gist.github.com/igrr/d35ab8446922179dc58c
*/
const char* mDNS_name = "myesp8266-ssid"; // we need to define our ssid explicitly
// ============================================== // Begin: OTA Block: Variable/Include statements
#include <ESP8266WiFi.h> #include <ESP8266mDNS.h> #include <WiFiUdp.h> #include <ArduinoOTA.h>
// may be shared with your sketch const char* ssid = "router-ssid"; const char* password = "router-passkey";
// ============================================== // End: OTA Block: Variable/Include statements
void setup() {
// ============================================== // Begin: OTA Block: setup() section
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(mDNS_name); // define explicitly, don't use defaults
// 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"); });
/* mDNS Responder:
We make sure mDNS service is setup, running, and accepting mDNS queries before running the rest of your sketch. */ while (!MDNS.begin(mDNS_name)) { Serial.println("Error MDNS responder not running!"); delay(1000); } Serial.println("mDNS responder ready to accept queries");
ArduinoOTA.begin(); Serial.println("OTA upload ready at:"); Serial.print("IP address: "); Serial.println(WiFi.localIP());
// ============================================== // End: OTA Block: setup() section
// ============================================== // Begin: Your sketch's: setup() section
pinMode(LED_BUILTIN, OUTPUT); // Initialize the LED_BUILTIN pin as an output pinMode(LED_BUILTIN_AUX, OUTPUT); // Initialize the LED_BUILTIN_AUX pin as an output
// ============================================== // End: Your sketch's: setup() section
}
void loop() {
// ============================================== // Begin: OTP Block: Main loop() section
MDNS.update(); // update our dynamic IP just in case our lease expired ArduinoOTA.handle();
// ============================================== // End: OTP Block: Main loop() section
// ============================================== // Begin: Your sketch's: Main loop() section
for(int j=0; j<6; j++){ digitalWrite(LED_BUILTIN, HIGH); digitalWrite(LED_BUILTIN_AUX, LOW); delay(150); digitalWrite(LED_BUILTIN_AUX, HIGH); digitalWrite(LED_BUILTIN, LOW); delay(150); }
digitalWrite(LED_BUILTIN_AUX, LOW); digitalWrite(LED_BUILTIN, LOW);
for(int j=0; j<6; j++){
for(int i=0; i<1023; i++){
analogWrite(LED_BUILTIN, i);
analogWrite(LED_BUILTIN_AUX, 1023-i);
delay(1);
}
for(int i=0; i<1024; i++){
analogWrite(LED_BUILTIN, 1023-i);
analogWrite(LED_BUILTIN_AUX, i);
delay(1);
}
}
digitalWrite(LED_BUILTIN_AUX, LOW); digitalWrite(LED_BUILTIN, LOW);
// ============================================== // End: Your sketch's: Main loop() section }`