OTA code no longer working (same code)

For some reason this simple code is not working, i.e. the hostname is not showing up in Arduino IDE ports. I’m sure it’s something dumb I am doing but I have spent a couple of hours and got nowhere.

BasicOTA example works perfectly on my Wemos D1 mini (ESP8266). I know my code is a cut down version but I’m sure I’ve seen this working in the past.

Anyone spot my mistake?

//Test_13
//
//Libraries
#include <ESP8266WiFi.h>  //for WiFi connection
#include <ESP8266mDNS.h>  //for OTA updates
#include <WiFiUdp.h>      //for OTA updates
#include <ArduinoOTA.h>   //for OTA updates


//WiFi credentials
char ssid[] = "";  //Enter your WIFI Name
char pass[] = "";  //Enter your WIFI Password


char *client_id = "OTA_Client_Name"; // Used for OTA hostname, needs to be a char or c_str, can't be a String



void setup()
{
  // Add support for OTA***************************************
  ArduinoOTA.onError([](ota_error_t error) {
    ESP.restart();
  });
  ArduinoOTA.setHostname(client_id);
  ArduinoOTA.begin();  /* setup the OTA server */
  // **********************************************************
  
  Serial.begin(74880);    // This is the native baud rate of most NodeMCUs, using this baud rate you will be able to see MCU and Debug messages in the serial monitor
  setup_wifi();
}



void setup_wifi() {
  delay(10);
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, pass);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}


void loop ()
{
  // Add support for OTA***************************************
  ArduinoOTA.handle();
  // **********************************************************
 
}

Yet somehow moving the OTA code to void setup_wifi works:

//Test_13
//
//Libraries
#include <ESP8266WiFi.h>  //for WiFi connection
#include <ESP8266mDNS.h>  //for OTA updates
#include <WiFiUdp.h>      //for OTA updates
#include <ArduinoOTA.h>   //for OTA updates


//WiFi credentials
char ssid[] = "";  //Enter your WIFI Name
char pass[] = "";  //Enter your WIFI Password


char *client_id = "OTA_Name"; // Used for OTA hostname, needs to be a char or c_str, can't be a String



void setup()
{
  Serial.begin(74880);    // This is the native baud rate of most NodeMCUs, using this baud rate you will be able to see MCU and Debug messages in the serial monitor
  setup_wifi();
}



void setup_wifi() {
  delay(10);
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, pass);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());

  
    // Add support for OTA***************************************
  ArduinoOTA.onError([](ota_error_t error) {
    ESP.restart();
  });
  ArduinoOTA.setHostname(client_id);
  ArduinoOTA.begin();  /* setup the OTA server */
  // **********************************************************
  
}


void loop ()
{
  // Add support for OTA***************************************
  ArduinoOTA.handle();
  // **********************************************************
 
}

So I thought maybe the wifi has to connect first. But putting the OTA code in void setup() after calling setup_wifi() function also does not work…

Strange.

Anyone have any ideas on this?

It's happening to all of my devices as I update them over OTA.
e.g. I make a small code change, update over OTA, then lose OTA connectivty.

If I move the below code from void setup() into setup_wifi() function it works again after flashing with usb cable:

  // Add support for OTA***************************************
  ArduinoOTA.onError([](ota_error_t error) {
    ESP.restart();
  });
  ArduinoOTA.setHostname(client_id);
  ArduinoOTA.begin();  /* setup the OTA server */
  // **********************************************************

Maybe something to do with updating board manager for esp8266 to 2.6.3?
Can't think what else I have changed..

I haven't used ESP8266 since a long time, but on the ESP32 I had to increase timeout. Also try print if there is any error

void setup_ota()
{
    // ArduinoOTA.setPort(3232);
    ArduinoOTA.setHostname(hostName);
    ArduinoOTA.setPasswordHash("xxxxxxxxxxxxxxxx");

    ArduinoOTA
        .onStart([]()
        {
            Serial.println("OTA Start");
        })

        .onEnd([]()
        {
            Serial.println("\nOTA End");
        })

        .onProgress([](unsigned int progress, unsigned int total)
        {
            Serial.printf("OTA Progress: %u%%\r", (progress / (total / 100)));
        })

        .onError([](ota_error_t error)
        {
            Serial.printf("OTA 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.setTimeout(20000);
    ArduinoOTA.begin();
}

Thank you @guix I will give that a try

You only need the include for ArduinoOTA.h.
ESP8266WiFi.h and WiFiUdp.h are included by ArduinoOTA.h

Here is how I use OTA.
In setup_wifi() I get the MAC address to use later to make a unique OTA hostname.
Here’s a starter sketch that you can use. To keep the main program clean, I like to put my setup functions in a separate tab.

Also, my WiFi credentials are in a separate file. This way all of my sketches just need to include this file:

#ifndef Kaywinnet         //include guards.
#define Kaywinnet

const char* my_ssid     = "yourSSID";
const char* my_password = "yourPassword";
const char* mqtt_server = "192.168.1.124";

#endif

Here is my main tab:
(You could put it all into a single tab, but I like the cleanliness of using tabs)

#include <ArduinoOTA.h>   //for OTA updates

//WiFi credentials
#include "D:\River Documents\Arduino\libraries\Kaywinnet.h"

#define hPrefix "Test-"

// setup_wifi globals
char macBuffer[24];       // Holds the last three digits of the MAC, in hex.
char hostNamePrefix[] = hPrefix;
char hostName[12];        // Holds hostNamePrefix + the last three bytes of the MAC address.


void setup()
{
  Serial.begin(115200);
  Serial.println();

  setup_wifi();
  start_OTA();

}


void loop (){ 
ArduinoOTA.handle();

// Do your loop stuff here

}

Here is my setup_wifi tab:

// setup_wifi
// ============================= Connect the ESP to the router =============================
// Connect to WiFi network so we can reach the MQTT broker and publish messages to topics.

/*
  Make sure you include at the start of the sketch:
  #include "ESP8266WiFi.h"   // Not needed if also using the Arduino OTA Library...
  #include "D:\River Documents\Arduino\libraries\Kaywinnet.h"  \\ WiFi credentials

  If using the OTA Library, put these at the start of the sketch.
  char macBuffer[24];       // Holds the last three digits of the MAC, in hex.
  char hostNamePrefix[] = "Drip-";
  char hostName[12];        // Holds hostNamePrefix + the last three bytes of the MAC address.
*/

void setup_wifi() {
  byte mac[6];                     //// the MAC address of your Wifi shield

  Serial.println(F("\n"));
  Serial.print(F("Connecting to "));
  Serial.println(my_ssid);


  WiFi.mode(WIFI_STA);
  WiFi.enableInsecureWEP();
  WiFi.begin(my_ssid, my_password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(WiFi.status()); Serial.print(F(" "));
  }
  Serial.println(F("\nWiFi connected, "));
  Serial.print(F("MAC Address: "));
  Serial.println(WiFi.macAddress());
  Serial.print(F("IP address: "));
  Serial.println(WiFi.localIP());


#ifdef __ARDUINO_OTA_H
  // Get the last three numbers of the mac address.
  // "4C:11:AE:0D:83:86" becomes "0D8386" in macBuffer.
  WiFi.macAddress(mac);
  snprintf(macBuffer, sizeof(macBuffer), "%02X%02X%02X", mac[3], mac[4], mac[5]);

  // Build hostNamePrefix + last three bytes of the MAC address.
  strcpy(hostName, hostNamePrefix);
  strcat(hostName, macBuffer);

  Serial.print(F("hostName = \""));
  Serial.print(hostName);
  Serial.println(F("\""));
#endif

}

And here is my start_OTA tab:

void start_OTA() {
  /*
    Make sure this in at the top of the sketch:
    #include <ArduinoOTA.h>
    Start loop() with:
    ArduinoOTA.handle();
  */

  //Hostname defaults to esp8266-[MAC address]
  ArduinoOTA.setHostname(hostName);                 // hostName is generated in 'setup_wifi'.
  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");
  
}

Hope this helps.

SteveMann:
Here is how I use OTA.......

Thank you very much for all of that! I have been meaning to sort out different tabs to store my credentials, this will give me a good start.

I will take some time to go through it all and report back.
Thanks :slight_smile:

FYI I get the same symptoms. Have OTA working on a few ESP8266's but on the ones where I have a seperate module for the Wifi setup and then the OTA setup code in the main void setup it doesnt work (network snoop doesnt see it sending any MDNS requests).

If I put the OTA setup code at the end of the Wifisetup module it works fine. No idea why this is happening but at least its working now.