pubsubclient: MQTT Subscribe not working

I am very new to ESP8266 and MQTT. So Apologies if I haven’t done it properly. I am using test.mosquitto.org server and trying to publish and subscribe the data. I am able to publish the data but subscribe part is not working. Nevertheless, I have tested subscribe part between two mobile and I am able to receive the data but I am not getting any data in the callback routine though I subscribed explicitly in the code. I have attached my code for your reference.

`

include <ESP8266WiFi.h>

include <PubSubClient.h>

define wifi_ssid “”

define wifi_password “”

define mqtt_server “test.mosquitto.org”

define mqtt_user “test”

define mqtt_password “test”

define topic1 “SmartIOT/Temperature”

define topic2 “SmartIOT/Humidity”

define topic3 “SmartIOT/Switch”

void callback(char* topic, byte* payload, unsigned int length); WiFiClient espClient; PubSubClient client(mqtt_server, 1883, callback, espClient); void setup() { Serial.begin(115200); setup_wifi(); //client.setServer(mqtt_server, 1883); client.subscribe(topic3); }

// Callback function void callback(char* topic, byte* payload, unsigned int length) { // In order to republish this payload, a copy must be made // as the orignal payload buffer will be overwritten whilst // constructing the PUBLISH packet. Serial.println("Incoming data : "); Serial.println(topic); //Serial.println(payload); // Allocate the correct amount of memory for the payload copy byte* p = (byte*)malloc(length); // Copy the payload to the new buffer memcpy(p,payload,length); //client.publish(“outTopic”, p, length); // Free the memory free(p); }

void setup_wifi() { delay(10); // We start by connecting to a WiFi network Serial.println(); Serial.print(“Connecting to “); Serial.println(wifi_ssid); WiFi.begin(wifi_ssid, wifi_password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print(”.”); } Serial.println(“”); Serial.println(“WiFi connected”); Serial.println("IP address: "); Serial.println(WiFi.localIP());

} void reconnect() { // Loop until we’re reconnected while (!client.connected()) { Serial.print(“Attempting MQTT connection…”); // Attempt to connect if (client.connect(“TestMQTT”)) { //* See //NOTE below Serial.println(“connected”);

    } else {
        Serial.print("failed, rc=");
        Serial.print(client.state());
        Serial.println(" try again in 5 seconds");
        // Wait 5 seconds before retrying
        delay(5000);
    }
}

} //NOTE: if a user/password is used for MQTT connection use: //if(client.connect(“TestMQTT”, mqtt_user, mqtt_password)) { void pubMQTT(String topic,float topic_val){ Serial.print(“Newest topic " + topic + " value:”); Serial.println(String(topic_val).c_str()); client.publish(topic.c_str(), String(topic_val).c_str(), true); } //Variables used in loop() long lastMsg = 0; float t1 = 75.5; float t2 = 50.5; void loop() { if (!client.connected()) { reconnect(); client.subscribe(topic3); } client.loop(); //2 seconds minimum between Read Sensors and Publish long now = millis(); if (now - lastMsg > 2000) { lastMsg = now; //Read Sensors (simulate by increasing the values, range:0-90) t1 = t1>90 ? 0 : ++t1; t2 = t2>90 ? 0 : ++t2; //Publish Values to MQTT broker pubMQTT(topic1,t1); pubMQTT(topic2,t2); } } `

About this issue

  • Original URL
  • State: open
  • Created 8 years ago
  • Comments: 72 (6 by maintainers)

Most upvoted comments

I solved the problem by calling: if (!client.connected()) reconnect(); & client.loop(); every 100 ms instead of every loop If you are not flashing the code to the ESP but are using an arduino connected to the ESP via serial I think the problem is calling these functions every loop causes the serial interface to be overwhelmed with status messages blocking the incoming message. I am a newbie programmer especially with the ESP & MQTT so I’m not sure… But my setup is now working (After a week of tearing my hair out!!) Richard

Check the data flowing to the server using WireShark. Use a debugger? Write log files? Use brain?

@hudanar please don’t ask your own questions on other issues.

My guess is you are using the same clientid for both clients and they are kicking each other off the broker. Make use you give each client a unique id

Thank you so much xibriz! After loosing a couple hours dealing with this problem, when trying to connect to my local MQTT broker, I could discover my error thanks to your post. It happend that was I using same client ID of another Wemos D1 that was already connected to this broker. That made impossible to receive subscriptions from server (eventhough, I could publish any topic on it without any problem) My solution was to use a similar code than the one you suggested but using client MAC Address instead, to avoid any further error (even copying the code to another sketch) and making it easy to trace the device communication within mosquitto mqtt broker log. Great!

@Noodleyman Try changing the mqtt_client_id. If you have more than one ESP using the same mqtt_client_id subscription won’t work. Add a random number at the end or something as the example code shows.

// Create a random client ID
String clientId = "ESP8266Client-";
clientId += String(random(0xffff), HEX);

For me, adding client.loop() twice after each client.subscribe(topic) call in reconnect resolved this issue (I did not have to add this for just a single topic but did have to after subscribing to two or more topics.

On Mon, Aug 20, 2018 at 9:27 AM, tsknightstorm notifications@github.com wrote:

This seems to be a common problem even after years. Also I have the problem, that I can connect and send MQTT messages without problems, but my callback function is not called at all. Last year, almoast the same code worked fine. I think the main thing I did is updating all libraries. After reading the full storry here and working 2 full days, I would be very happy if someone can help me anf maybe also others with answer.

Hardware:

  • ESP8266 12-F
  • RPi 3 with Mosquitto
  • Win10 and AtmelStudio / visual Micro

My Code: I added many delays for tests. Of corse, I do not let them all stay in my code. Also I post just the MQTT part. I splited the WiFi code and some logic things with buttons to other .cpp / .h files. ` #define mqtt_waitTimeMs 100

WiFiClient wifiClient; PubSubClient mqttClient(wifiClient);

void mqtt_setup(void){ delay(200); // Loop until we’re reconnected while(! mqttClient.connected()){ Serial.print("Setup MQTT \t| ");

String mqttClientID = _generateUniqID();

mqttClient.setServer(mqtt_server,mqtt_port); delay(100); mqttClient.setCallback(_mqtt_callback); delay(100);

Serial.print(“Attempting MQTT connection…”); // Attempt to connect if( mqttClient.connect(mqttClientID.c_str(), mqtt_user, mqtt_password)){

  // subscribe to Topics
  _mqtt_subscribe();
  
  Serial.println("connected...rc=" + String(mqttClient.state()));
  
  if (mqttClient.publish("debug", mqttClientID.c_str())) { // comment for start
  	Serial.println("MQTT Publish ok");
  }else {
  	Serial.println("Publish failed!...");
  }
  Serial.println();

}else{ Serial.print(“failed, rc=”); Serial.print( mqttClient.state()); Serial.println(" try again in 5 seconds"); // Wait 5 seconds before retrying, blocking because nothing should run without connection delay(5000); } }

}

void mqtt_loop(void){ static long oldTimeMs = millis();

if( (millis()-oldTimeMs) > mqtt_waitTimeMs){ mqtt_setup(); //to reconnect oldTimeMs = millis(); } mqttQueue_DequeueAndSend();

}

void mqtt_publish(String topic, byte payload){ mqttQueue_Enqueue(topic, payload); }

void mqtt_publish_directOut(char* topic, char* payload){ if ( mqttClient.publish(topic, payload) ){ Serial.println(“OK”); }else{ Serial.println(" ERROR: Send MQTT fail…"); } }

void _mqtt_callback(char* topic, byte* payload , unsigned int length){ Serial.println(“…Debug: MQTT callback”);

byte numPayload = _bytePToInt(payload, length); byte numInChannel; byte numOutChannel;

if(_inTopicToChannel(topic, &numInChannel)){ led_setValue(numInChannel, numPayload); } if(_outTopicToChannel(topic, &numOutChannel)){ switch_setState(numOutChannel, numPayload); }

Serial.println( "Receive MQTT\t| topic: " + String(topic) + "\t| payload: " + String(numPayload) + "\t| channel: " + String(numInChannel) );

}

void _mqtt_subscribe(void){ Serial.println(“…Debug: MQTT Subscribe start”); mqttClient.subscribe(“debug”); // subscribe to update LED’s for(int i = 0; i < numberOfLed; i++){ if(mqttClient.subscribe(mqtt_inTopicString[i].c_str())){ Serial.println(“…Debug: MQTT Subscribe true”); }else{ Serial.println(“…Debug: MQTT Subscribe false”); } delay(100); }

// subscribe to update switch states for(int i = 0; i < numberOfSwitch; i++){ //mqttClient.subscribe((char*)mqtt_outTopicString[i].c_str()); //////////// mqtt connection crashes with both arrays subscribed delay(100); } Serial.println(“…Debug: MQTT Subscribe end”);

} `

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/knolleary/pubsubclient/issues/163#issuecomment-414378507, or mute the thread https://github.com/notifications/unsubscribe-auth/AduW1kvvw0NewYYLcA3RCrKXZQC5iEnFks5uSuOHgaJpZM4Ifkl7 .

I am using ESP8266 to publish and subscribe the the data on RPi mosquito broker. I did not gone through all comments mentioned above. I am able to publish data to mosquito broker but while subscribing, the data callback function not working or called and data not displayed on serial monitor.

Finally I have solved this problem. If you are using the client.loop(); function in code, use dalay(100) after client.loop() function code line. I think to subscribe message takes some delay to run callback function.

If this solution works fine let me know. Happy Arduino programming.

In my case it had to do with the message size.

The maximum message size, including header, is 128 bytes by default. This is configurable via MQTT_MAX_PACKET_SIZE in PubSubClient.h

I am very new to ESP8266 and MQTT. So Apologies if I haven’t done it properly. I am using test.mosquitto.org server and trying to publish and subscribe the data. I am able to publish the data but subscribe part is not working. Nevertheless, I have tested subscribe part between two mobile and I am able to receive the data but I am not getting any data in the callback routine though I subscribed explicitly in the code. I have attached my code for your reference.

I found a buffer overrun in pubsubclient.cpp. After changing the buffer size with client.setBufferSize(<desired buffer size>); runs everything flawlessly.

Thanks a lot! With your comment, you were able to bring me to solve my problem… It was too obviouse…

I never did call client.loop()…

At some point, I must have deleted this line by acident and while reading the comments in this forum, I was thinking that everyboadi is talking about the general loop not this particular function.

Thank you for quickly reply

Now work using delay(100) after client.loop() But if you use something like below not work.

unsigned long now = millis(); if (now - lastLoop > 100) { client.loop(); lastLoop = now;
}

However it seems unstable because sometimesit does not receive the package.

Thank a lot.

Hi Knolleary, Picking up the issue…Mqtt_Esp8266 example doesn’t receive/serial print on inTopic (publishes outTopic fine) nor toggle LED. See Serial Output below. Two other clients connected and receive publish outTopic and published inTopics. Wemos D1 mini is ESP8266 module.

serial output: WiFi connected IP address: 192.168.1.96 Attempting MQTT connection…connected Publish message: hello world #1 Publish message: hello world #2 Publish message: hello world #3 Publish message: hello world #4 Publish message: hello world #5 Publish message: hello world #6 Publish message: hello world #7 Publish message: hello world #8 Publish message: hello world #9 Publish message: hello world #10 Publish message: hello world #11 Publish message: hello world #12 Publish message: hello world #13 Publish message: hello world #14 Publish message: hello world #15