Important changes to forums and questions
All forums and questions are now archived. To start a new conversation or read the latest updates go to forums.mbed.com.
6 years, 4 months ago.
MQTT connection get lost, using it with Thread reading Serial Data
Hi Guys, I'm facing a problem with MQTT connection with Mosquito Broker. The program flow is as:
- Opening Serial for Debug msgs
- Opening a thread reading serial data from Enocean sensor
- Starting the Ethernet and MQTT connections
- In the while(1) loop, I'm just checking if the connection is still alive, I'm publishing Serial Data Packet to MQTT broker.
Everything works fine, if i keep sending data from my Enocean sensor and buttons, But the problem arises when there is no sensor/button sending data through MQTT.
- The connection get lost from MQTT broker.
- I have tried to reconnect again, but in the main loop the method client.isConnected() always return true even if it has lost connection with MQTT broker.
- I have also tried using client.yield() in the while(1) loop, but it get everything stuck. No thing works at all by adding yield.
Please guide.
include the mbed library with this snippet
#include "mbed.h" #include "rtos.h" // change this to 0 to output messages to serial instead of LCD #define USE_LCD 0 #define MQTTCLIENT_QOS2 1 #include "easy-connect.h" #include "MQTTNetwork.h" #include "MQTTmbed.h" #include "MQTTClient.h" Serial pc(USBTX, USBRX); // Serial port for Debug messages Serial enocean(p28, p27); // tx, rx --> Serial Communication with EnOcean Transiver DigitalOut led1(LED1); // Connection information LED DigitalOut led2(LED2); DigitalOut led3(LED3); Thread thread_ENOCEAN; char c[30]; char buf[30]; volatile int i = 0; // Network and MQTT const char* hostname = "192.168.10.5"; int port = 1883; char* topic = "hellomqtt/topic"; int rc; // generate a unique random Client-ID char str[20] ="mbed-clientID-0001"; // Interupt Routine to read in data from serial port void Rx_intt() { c[i++] = LPC_UART2->RBR; led2 = !led2; return; } void enocean_thread() { enocean.baud(57600); enocean.attach(&Rx_intt, Serial::RxIrq); i = 0; } int main(int argc, char* argv[]) { pc.baud(9600); NetworkInterface* network = easy_connect(false); MQTTNetwork mqttNetwork(network); MQTT::Client<MQTTNetwork, Countdown> client(mqttNetwork); rc = mqttNetwork.connect(hostname, port); MQTTPacket_connectData data = MQTTPacket_connectData_initializer; data.MQTTVersion = 3; str[18] = 0; data.clientID.cstring = str; rc = client.connect(data); led1 = 1; MQTT::Message message; // Opening thread for Enocean Serial Data thread_ENOCEAN.start(enocean_thread); while(1) { if(!client.isConnected()) { led1 = 0; rc = client.disconnect(); mqttNetwork.disconnect(); network = easy_connect(false); MQTTNetwork mqttNetwork(network); MQTT::Client<MQTTNetwork, Countdown> client(mqttNetwork); rc = mqttNetwork.connect(hostname, port); MQTTPacket_connectData data = MQTTPacket_connectData_initializer; data.MQTTVersion = 3; str[18] = 0; data.clientID.cstring = str; rc = client.connect(data); } if(i > 20 && client.isConnected()) { rc = client.connect(data); led1 = 1; led2 = 0; memcpy(buf, c, i); message.qos = MQTT::QOS0; message.retained = false; message.dup = false; message.payload = (void*)buf; message.payloadlen = 21;//strlen(buf)+1; rc = client.publish(topic, message); //pc.printf("Length: %i\n",sizeof(buf)); for(int j=0; j<21;j++) { pc.putc(buf[j]); } i = 0; } //client.yield(100); } }
1 Answer
6 years, 4 months ago.
Hello sohaib,
Did you try to add a null character (0) at the end of your message? This will tell the Broker that this is the end of your message and stop listening. Otherwise, it will wait because it thinks that there is more message to be sent.
Please let me know if you have any questions!
-Peter, team Mbed
If this solved your question, please make sure to click the "Thanks" link below!
Hey Peter, Thanks for the quick reply. I have used the following to add null character (0)
if(i > 20 && client.isConnected()) { rc = client.connect(data); led1 = 1; led2 = 0; memcpy(buf, c, i); buf[21] = 0x00; message.qos = MQTT::QOS0; message.retained = false; message.dup = false; message.payload = (void*)buf; message.payloadlen = 22;//strlen(buf)+1; rc = client.publish(topic, message); //pc.printf("Length: %i\n",sizeof(buf)); for(int j=0; j<21;j++) { pc.putc(buf[j]); } i = 0; }
As I know the Enocean msg contain 21 bytes packet so i appended 0x00 at Byte 22. But the problem has not been resolved yet. Again, i'm losing the connection with MQTT broker. Please advise.
posted by 03 Aug 2018Hi,
If the problem only occurs when there is no sensor/button data, can you just put an if statement to check for that and only publish when you have data?
Peter
posted by 03 Aug 2018Hi Peter, I'm already doing that, I'm receiving the Enocean Sensor/button data in a separate thread. And in the while(1) loop, when i receive the whole packet, only then i publish the msg to MQTT.
Waiting for your kind response.
posted by 03 Aug 2018Hello, why are you calling client.connect() everytime before you publishing your data?
-Peter
posted by 14 Aug 2018Hi Peter,
I need to make sure if the connection is intact before sending the message to MQTT server.
posted by 15 Aug 2018Hi, Isn't that what client.isConnect() doing? Reading the MQTTClient library, the connect function is trying to create a connection between your board and the MQTT Broker. So it seems that you are creating new connection everytime you publish, which can be an issue.
-Peter
posted by 15 Aug 2018
Hi Peter,
I have also checked by removing the line of code. There was no difference.
Actual problem i'm facing is unexpected behavior of client.isConnected() method. It's is always returning me true whether the client is connected with MQTT server or not.
posted by sohaib qamar 16 Aug 2018Hi, Which board are you using?
-Peter
posted by Peter Nguyen 16 Aug 2018I'm using LPC1768 board.
Sohaib.
posted by sohaib qamar 16 Aug 2018