Weird dtostrf() behaviour - please help!

I'm building a weather station using an ESP32 and BME280. I'm feeding the data via MQTT and Python into a database that is then used to make a nice dashboard for the data.

The MQTT message needs to be a char, and the sensor readings are floats, so I'm using dtostrf() to convert them. This works fine for the temperature and pressure readings, but for some reason not for the humidity reading.

I declare my variables:

float temp;
float hum;
float pres;

char mqttTemp[6];
char mqttHum[6];
char mqttPres[5];

Then I get my readings:

temp = mySensor.readTempC();
Serial.print("Temp: ");
Serial.print(temp);
hum = mySensor.readFloatHumidity();
Serial.print("Hum: ");
Serial.print(hum);
pres = mySensor.readFloatPressure();
Serial.print("Pres: ");
Serial.print(pres);

This returns:

Temp: 25.57 Hum: 40.15 Pres: 97684.39

Then I run the results through the function:

dtostrf(temp,4,2,mqttTemp);
dtostrf(hum,4,2,mqttHum);
dtostrf(pres,5,0,mqttPres);

Then I output these to Serial:

Serial.print("Temperature: ");
Serial.print(mqttTemp);
Serial.print("Humidity: ");
Serial.print(mqttHum);
Serial.print("Pressure: ");
Serial.print(mqttPres);

Which gives me:

Temperature: 25.57
------------------------------
Humidity: 
------------------------------
Pressure: 97684

There is also no message sent via MQTT for humidity, but it works perfectly for the other two readings. What gives?

char mqttPres[5];

is too short to contain 97684.

So its closing 0 probably lands in the first byte of mqttHum.

Use sprintf :

char myText[38] = "Temp: 25.57 Hum: 40.15 Pres: 97684.39";
sprintf(myText,"Temp:%6.2f Hum:%6.2f Pres:%9.2f",temp,hum,pres);

lesept:
Use sprintf :

char myText[38] = "Temp: 25.57 Hum: 40.15 Pres: 97684.39";

sprintf(myText,“Temp:%6.2f Hum:%6.2f Pres:%9.2f”,temp,hum,pres);

You forgot to specify how to activate %f in sprintf, it is not available in the standard configuration.

Or the safer snprintf() which will not write outside the designated buffer size.

Be aware that snprintf() doesn't eliminate all overrun bugs because if there is an overrun there will be no trailing null char on the string.

Also on ASE: https://arduino.stackexchange.com/questions/61036/why-is-dtostrf-not-working-for-this-one-value

OP, if you're going to sprinkle the same question all over the place despite the fact that it is mostly the same people, then please at least be courteous enough to link them so that the people on one site don't waste time giving you answers you already have. Just a little common courtesy.

I'll leave you to link the ASE question to here.

MorganS: Be aware that snprintf() doesn't eliminate all overrun bugs because if there is an overrun there will be no trailing null char on the string.

Or does it?

Whandall: You forgot to specify how to activate %f in sprintf, it is not available in the standard configuration.

It is for an ESP32 (at least I've been doing this for a long time)

Delta_G: Also on ASE: https://arduino.stackexchange.com/questions/61036/why-is-dtostrf-not-working-for-this-one-value

OP, if you're going to sprinkle the same question all over the place despite the fact that it is mostly the same people, then please at least be courteous enough to link them so that the people on one site don't waste time giving you answers you already have. Just a little common courtesy.

Noted. I was unaware it was 'mostly the same people'.

The answer here:

https://arduino.stackexchange.com/a/61038/53417

Solved my issue. As Whandall said, I hadn't made the buffers big enough.

[quote author=Coding Badly link=msg=4035842 date=1548661895] Or does it?

[/quote] Thankyou. I re-read an online reference before posting but didn't find a specific answer. Other string functions can fail to place the null and I just assumed it was the same.