1

for one week I am searching for a solution at my ESP32 project (development over Arduino IDE): In my project I execute the following step:

  1. Read Temperature via BME280
  2. Ask time at NTP server (via time.h)
  3. Write data so string
  4. Send String via mqtt to mqtt broker (via PubSubClient)

All works fine but only if I not add the timestamp like this (without a timestamp):

String jsonString="{\"temperature\":"+String(bme.readTemperature())+",\"humidity\":"+String(bme.readHumidity())+",\"pressure\":"+String(bme.readAltitude(SEALEVELPRESSURE_HPA))+",\"deviceID\":\""+deviceID+"\",\"@timestamp\":\"\"}";

But if I add the timestamp the PubSubClient don't send the data.:

String jsonString="{\"temperature\":"+String(bme.readTemperature())+",\"humidity\":"+String(bme.readHumidity())+",\"pressure\":"+String(bme.readAltitude(SEALEVELPRESSURE_HPA))+",\"deviceID\":\""+deviceID+"\",\"@timestamp\":\""+printFormattedTime()+"\"}";

The function printFormattedTime():

String printFormattedTime()
{
  struct tm timeinfo;
  if(!getLocalTime(&timeinfo)){
    Serial.println("Failed to obtain time");
    return String("Failed to obtain time");
  }
  char timeStringBuff[50]; //50 chars should be enough
  strftime(timeStringBuff, sizeof(timeStringBuff), "%Y-%B-%d %H:%M:%S", &timeinfo);
  //print like "const char*"
  Serial.println(timeStringBuff);
  
  return String(timeStringBuff);
}

As I said: all works fine until I add the function that returns the String with time format.

I also tested another NTPClient (NTPClient.h) but without success.

Any idea?

Thanks

2
  • your problem probably has nothing to do with the MQTT server ... it all had to do with building a valid jsonString variable ... use serial.print() function to debug the problem with the string variable ...... add the content of the two versions of jsonString to your question above
    – jsotola
    Jun 18, 2019 at 1:08
  • It could maybe but I print out the string already. This all works fine. And as I wrote If I add the timestamp variable I doesn't work but without it works. Are there any further debugging features from PubSubClient?
    – ssd_rider
    Jun 19, 2019 at 14:56

1 Answer 1

1

First thing -- I don't trust the String data type.

When I use it, I eventually get allocation errors. Memory management doesn't seem to work well. I don't know when it re-allocates and when it uses the char array I supply.

Therefore, were I trying to fix this in my code, I would change the function to not return a String, but instead to pass it a char buffer address and size, like you are passing to strftime. I would not use the overloaded "+" operator with the String datatype, and instead would use strcat and strcpy to construct the json string.

This is what I do in my Arduino IOT devices.

I also am a luddite. I have had less than favorable experiences using C++ in resource-constrained environments. Big IOT commercial system I build now use C++, but the scale of their application processors is GigaHertz and Gigabytes.

The problem here might be that the String conversion of the char array is not making a copy of the array. When you return from the function, the array (which is on the stack) goes out of scope, and the stack space is reused by another function call. You could read the code for the char to String conversion, or you could switch to only use the char type, so you are no dependent on the undocumented features of unknown libraries.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.