I'm programming an ESP32 with Arduino and am publishing MQTT messages using the standard pubsubclient library.
In my loop below, I have noticed my "Inside loop" gets published, however, the second message of variable jsonObjChar
never seems to get published to the topic? There aren't any errors in the serial monitor.
void loop(){
String temperature = String(readDHTTemperature());
String humidity = String(readDHTHumidity());
String light = String(readLDRLight());
String jsonObj = "{";
jsonObj.concat("\"deviceId\":\"123456\"");
jsonObj.concat(",");
jsonObj.concat("\"messageType\":\"ambientSensorReading\"");
jsonObj.concat(",");
jsonObj.concat("\"temperature\":\"");
jsonObj.concat(temperature);
jsonObj.concat("\"");
jsonObj.concat(",");
jsonObj.concat("\"humidity\":\"");
jsonObj.concat(humidity);
jsonObj.concat("\"");
jsonObj.concat(",");
jsonObj.concat("\"light\":\"");
jsonObj.concat(light);
jsonObj.concat("\"}");
delay(1000);
int jsonObjCharLength = jsonObj.length() + 1;
char jsonObjChar[jsonObjCharLength];
jsonObj.toCharArray(jsonObjChar, jsonObjCharLength);
Serial.println("PREPARED");
Serial.println(jsonObjChar);
const char topic[13] = "prototype001";
client.publish(topic, "inside loop");
client.publish(topic, jsonObjChar);
// ... and resubscribe
client.subscribe("prototype001");
delay(5000);
}
The variable jsobObjChar
seems to be fine, when I print it out to the serial monitor, it looks like an ordinary string (I've structured in JSON format to be handled on the server side)
20:13:41.494 -> PREPARED
20:13:41.494 -> {"deviceId":"123456","messageType":"ambientSensorReading","temperature":"25.10","humidity":"49.90","light":"2592"}
20:13:46.521 ->
If it helps, I'm using cloudmqtt.
Any help would be greatly appreciated!!!
Try to get rid of strings, they will fracture your heap and cause crashes. Define global fixed charBuffers (big enough to take the largest message) and helper (tmp chars) for conversion and other things) Do not define const chars in the loop do it before setup so the compiler places them in the stack and is not using heap during runtime. I changed your code to this principle and added an extra delay between messages:
const char topic[13] = "prototype001"; // goes to the stack
char jsonObjChar [256] = '\0'; // set it large enough goes to the stack not heap!
char numBuffer [16] = '\0'; //tmpBuffer for conversion of ints to char
void loop(){
if (!client.connected()) {
reconnect();
}
strcpy (jsonObj, "{"); // Initialize/clear char by using strcpy
strcat(jsonObj, "\"deviceId\":\"123456\""); // strcat append
strcat(jsonObj,",");
strcat(jsonObj,"\"messageType\":\"ambientSensorReading\"");
strcat(jsonObj,",");
strcat(jsonObj,"\"temperature\":\"");
// conversion only needed if temperature is an int, if its char use strcat(jsonObj,readDHTTemperature());
itoa (readDHTTemperature(), numBuffer, 10); // Converts an int to a char array
strcat(jsonObj,numbuffer);
strcat(jsonObj,"\"");
strcat(jsonObj,",");
strcat(jsonObj,"\"humidity\":\"");
// if already char use strcat(jsonObj,readDHTHumidity());
itoa (readDHTHumidity(), numBuffer, 10);
strcat(jsonObj,numbuffer);
strcat(jsonObj,"\"");
strcat(jsonObj,",");
strcat(jsonObj,"\"light\":\"");
// if char strcat(jsonObj,readLDRLight());
itoa (readLDRLight(),numBuffer. 10);
strcat(jsonObj,numbuffer);
strcat(jsonObj,"\"}");
delay(1000);
Serial.println("PREPARED");
Serial.println(jsonObjChar);
client.publish(topic, "inside loop");
delay(1000); // for test onl<
client.publish(topic, jsonObjChar);
// ... and resubscribe
client.subscribe("prototype001");
delay(5000);
client.loop();
}
If it works - fine. If not the next debug step would be to look whats received at the server.