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)
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 samemqtt_client_idsubscription won’t work. Add a random number at the end or something as the example code shows.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:
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 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