Pubsubclient: Library Conflict with ArduinoOTA.h When Using ESP8266

Created on 11 Aug 2016  路  9Comments  路  Source: knolleary/pubsubclient

When I start to use "client.connect(MQTTClientID, MQTTUsername, MQTTPassword)" I lose the ability to upload sketches using OTA. I am using mosquitto on a local Linux machine.

Please note, in purpose of showing my code on this website, I could not use "<" after #include because it makes the name of the library disappear so I removed it.

include ESP8266WiFi.h>

include ESP8266mDNS.h>

include WiFiUdp.h>

include ArduinoOTA.h>

include PubSubClient.h>

//***********************************
typedef unsigned long UL;
typedef unsigned int UI;

//************ Customizables ******************

define MQTT_SERVER "192.168.1.8"

define MQTTClientID "20160802184820" //

define MQTTUsername "a"

define MQTTPort 1883

define MQTTPassword "123456"

const char* ssid = "myssid";
const char* password = "mypass";

define MQTTTopicPub "pubTopic"

define MQTTTopicSub "subTopic"

define inPin 2

define connection_msg "connected!"

void callback(char* topic, byte* payload, unsigned int length);
void reconnect();

WiFiClient espClient;
PubSubClient client(MQTT_SERVER, MQTTPort, callback, espClient);

String commandReceived="";

void setup() {

Serial.begin(115200);
Serial.println("Booting");
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
while (WiFi.waitForConnectResult() != WL_CONNECTED) {
// while (WiFi.status() != 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((const char *)"123");

ArduinoOTA.onStart( {
Serial.println("Start");
});
ArduinoOTA.onEnd( {
Serial.println("\nEnd");
});
ArduinoOTA.onProgress( {
Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
});
ArduinoOTA.onError( {
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());

pinMode(inPin, INPUT_PULLUP); // pin 2 should be pulled down

millis();

// MQTT
reconnect();

}

void loop() {
ArduinoOTA.handle();

if (!client.connected()) {
reconnect();
}

delay(5000);
client.publish(MQTTTopicPub, connection_msg);
client.loop();

}

//***********************//
void reconnect() {
// Loop until we're reconnected
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
// Attempt to connect
if (client.connect(MQTTClientID, MQTTUsername, MQTTPassword)) {
Serial.println("connected");
// Once connected, publish an announcement...
client.publish(MQTTTopicPub, connection_msg);
// ... and resubscribe
client.subscribe(MQTTTopicSub);
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
// Wait 5 seconds before retrying
delay(5000);
}
}
}

void callback(char* topic, byte* payload, unsigned int length) {
Serial.print("Message arrived [");
Serial.print(topic);
Serial.print("] ");
commandReceived="";
for (int i = 0; i < length; i++) {
Serial.print((char)payload[i]);
commandReceived+=(char)payload[i];
}
Serial.println();
}

Most helpful comment

Thanks @Suxsem - good to have confirmation it can work 馃憤

All 9 comments

Guys, please help.

So what exactly do you see happen? I've never used ArduinoOTA so I don't know what you are expecting.

Well, actually ArduinoOTA is used to let developers to upload firmware through WIFI without a physical wires. What happens is I lose the ability to upload new firmware via WIFI connection once the function "client.connect(MQTTClientID, MQTTUsername, MQTTPassword)" is called.

That suggests that whilst the hardware has an active network connection open it cannot accept OTA requests. Not sure what to suggest here. You may want to ask the question of the people behind ArduinoOTA whether they would expect it work when the ESP has an active open TCP connection. I can't find anything definitive to say whether that should work or not.

I don't have any problem with ArduinoOTA + mqtt

this is the boilerplate script that I use (that supports auto reconnection of wifi AND mqtt):

#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <ArduinoOTA.h>

#define DEFAULTssid "***"
#define DEFAULTpsw "***"
#define MQTTid "***"
#define MQTTip "***"
#define MQTTport 1883
#define MQTTuser "***"
#define MQTTpsw "***"
#define MQTTpubQos 1
#define MQTTsubQos 1

void mqttDataCb(char* topic, byte* payload, unsigned int length);
void mqttConnectedCb();
void mqttDisconnectedCb();
void processNet();

boolean pendingDisconnect = true;

WiFiClient wclient;
PubSubClient client(MQTTip, MQTTport, mqttDataCb, wclient);

// #################### mqtt ####################

void mqttDataCb(char* topic, byte* payload, unsigned int length) {
  char* message = (char *) payload;
  message[length] = 0;
}

void mqttConnectedCb() {
  client.subscribe("sometopic", MQTTsubQos);
  client.publish(MQTTid "/status", "1", 2, true);
}

void mqttDisconnectedCb() {  

}

// #################### setup e loop ####################

void setup() {

  ArduinoOTA.setHostname(MQTTid);

  WiFi.mode(WIFI_STA);
  WiFi.begin(DEFAULTssid, DEFAULTpsw);

}

void processNet() {
  if (WiFi.status() == WL_CONNECTED) {
    ArduinoOTA.begin();
    ArduinoOTA.handle();
    if (client.connected()) {
      client.loop();
    } else {
      if (client.connect(MQTTid, MQTTuser, MQTTpsw, MQTTid "/status", 2, true, "0")) {
          pendingDisconnect = false;
          mqttConnectedCb();
      }
    }
  } else {
    if (client.connected())
      client.disconnect();
  }
  if (!client.connected() && !pendingDisconnect) {
    pendingDisconnect = true;
    mqttDisconnectedCb();
  }
}

void loop() {

  processNet();

}

hope it helps

Thanks @Suxsem - good to have confirmation it can work 馃憤

@mhmayyan i noticed the "delay(5000);" in loop()
i'm not sure but i suspect that "ArduinoOTA.handle();" must be called much more frequently than 1 time every (at least) 5 seconds.

Thanks guys

I know now the reason of my problem.

The library ArduinoOTA needs more memory (ROM) like what is available on ESP-12E. My mistake is I used ESP-01 version which has limited memory (ROM) compared to ESP-12E.

Thanks a lot guys.

I use ArduinoOTA with esp-01 (512kb rom).
be sure to:
1) don't have a huge script
2) in the Arduino IDE, choose "flash size": "512k no spiffs"

be sure to reflash the script with CABLE, then you can do OTA

Was this page helpful?
0 / 5 - 0 ratings