user53417: 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?

user21371: What is happening is that the variables you declared for mqttTemp etc are stored in memory something like this
variable   memory address
mqttPres @ 1000-1004 (5 bytes)
mqttHum  @ 1005-1010 (6 bytes)
mqttTemp @ 1011-1015 (6 bytes)

For a start, you only have enough room (with the mandatory NUL byte string terminator) for 4, 5 and 5 characters
When you convert pressure, the NUL byte is being placed as the first byte in mqttHum, therefore, when printing mqttHum you get an empty string output (since the first byte is NUL)
To really see what's happening, here's some code that illustrates the issue
char mqttTemp[6] = "TTTTT";
char mqttHum[6] = "HHHHH";
char mqttPres[5] = "PPPP";
void setup() {
  float temp = 25.57;
  float hum = 40.15;
  float pres = 97684.39;


  Serial.begin(74880);
  // put your setup code here, to run once:
  delay(100);
  Serial.println("before");
  printThem();
  dtostrf(temp, 4, 2, mqttTemp);
  Serial.println("converted temp");
  printThem();
  dtostrf(hum, 4, 2, mqttHum);
  Serial.println("converted hum");
  printThem();
  dtostrf(pres, 5, 0, mqttPres);
  Serial.println("converted press");
  printThem();
}
void printThem()
{
  Serial.print("mqttPres ");
  Serial.print((unsigned long) &mqttPres, DEC);
  Serial.print(": ");
  for (int i = 0; i < 5; i++) {
    Serial.print((int) mqttPres[i], DEC);
    Serial.print(' ');
  }
  Serial.println();

  Serial.print("mqttHum  ");
  Serial.print((unsigned long) &mqttHum, DEC);
  Serial.print(": ");
  for (int i = 0; i < 6; i++) {
    Serial.print((int) mqttHum[i], DEC);
    Serial.print(' ');
  }
  Serial.println();

  Serial.print("mqttTemp ");
  Serial.print((unsigned long) &mqttTemp, DEC);
  Serial.print(": ");
  for (int i = 0; i < 6; i++) {
    Serial.print((int) mqttTemp[i], DEC);
    Serial.print(' ');
  }
  Serial.println();
}

void loop() {
  delay(50);
  // put your main code here, to run repeatedly:

}

The above outputs the following:
before
mqttPres 1073644748: 80 80 80 80 0 
mqttHum  1073644753: 72 72 72 72 72 0 
mqttTemp 1073644759: 84 84 84 84 84 0 
converted temp
mqttPres 1073644748: 80 80 80 80 0 
mqttHum  1073644753: 72 72 72 72 72 0 
mqttTemp 1073644759: 50 53 46 53 55 0 
converted hum
mqttPres 1073644748: 80 80 80 80 0 
mqttHum  1073644753: 52 48 46 49 53 0 
mqttTemp 1073644759: 50 53 46 53 55 0 
converted press
mqttPres 1073644748: 57 55 54 56 52 
mqttHum  1073644753: 0 48 46 49 53 0 
                     ^ ======== note the leading 0
mqttTemp 1073644759: 50 53 46 53 55 0 

The simplest fix, of course, is to declare your variables with the correct size
char mqttTemp[7]; // because -10.00 takes 6 characters + 1 for NULL
char mqttHum[7];  // because 100.00 takes 6 characters + 1 for NULL
char mqttPres[6]; // because 97684 takes 5 characters + 1 for NULL - if pressure can reach 100000 then use 7 here as well

and then use dtostrf correctly, i.e. the second argument is the total width, including . and a possible -
dtostrf(temp,6,2,mqttTemp);
dtostrf(hum,6,2,mqttHum);
dtostrf(pres,5,0,mqttPres);


53417: <p>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.</p>

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

<p>I declare my variables:</p>

<pre><code>float temp;
float hum;
float pres;

char mqttTemp[6];
char mqttHum[6];
char mqttPres[5];
</code></pre>

<p>Then I get my readings:</p>

<pre><code>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);
</code></pre>

<p>This returns:</p>

<p><code>Temp: 25.57 Hum: 40.15 Pres: 97684.39</code></p>

<p>Then I run the results through the function:</p>

<pre><code>dtostrf(temp,4,2,mqttTemp);
dtostrf(hum,4,2,mqttHum);
dtostrf(pres,5,0,mqttPres);
</code></pre>

<p>Then I output these to Serial:</p>

<pre><code>Serial.print("Temperature: ");
Serial.print(mqttTemp);
Serial.print("Humidity: ");
Serial.print(mqttHum);
Serial.print("Pressure: ");
Serial.print(mqttPres);
</code></pre>

<p>Which gives me:</p>

<pre><code>Temperature: 25.57
------------------------------
Humidity: 
------------------------------
Pressure: 97684
</code></pre>

<p>There is also no message sent via MQTT for humidity, but it works perfectly for the other two readings. What gives?</p>
 21371: <p>What is happening is that the variables you declared for mqttTemp etc are stored in memory something like this</p>

<pre><code>variable   memory address
mqttPres @ 1000-1004 (5 bytes)
mqttHum  @ 1005-1010 (6 bytes)
mqttTemp @ 1011-1015 (6 bytes)
</code></pre>

<p>For a start, you only have enough room (with the mandatory NUL byte string terminator) for 4, 5 and 5 characters</p>

<p>When you convert pressure, the NUL byte is being placed as the first byte in mqttHum, therefore, when printing mqttHum you get an empty string output (since the first byte is NUL)</p>

<p>To really see what's happening, here's some code that illustrates the issue</p>

<pre><code>char mqttTemp[6] = "TTTTT";
char mqttHum[6] = "HHHHH";
char mqttPres[5] = "PPPP";
void setup() {
  float temp = 25.57;
  float hum = 40.15;
  float pres = 97684.39;


  Serial.begin(74880);
  // put your setup code here, to run once:
  delay(100);
  Serial.println("before");
  printThem();
  dtostrf(temp, 4, 2, mqttTemp);
  Serial.println("converted temp");
  printThem();
  dtostrf(hum, 4, 2, mqttHum);
  Serial.println("converted hum");
  printThem();
  dtostrf(pres, 5, 0, mqttPres);
  Serial.println("converted press");
  printThem();
}
void printThem()
{
  Serial.print("mqttPres ");
  Serial.print((unsigned long) &amp;mqttPres, DEC);
  Serial.print(": ");
  for (int i = 0; i &lt; 5; i++) {
    Serial.print((int) mqttPres[i], DEC);
    Serial.print(' ');
  }
  Serial.println();

  Serial.print("mqttHum  ");
  Serial.print((unsigned long) &amp;mqttHum, DEC);
  Serial.print(": ");
  for (int i = 0; i &lt; 6; i++) {
    Serial.print((int) mqttHum[i], DEC);
    Serial.print(' ');
  }
  Serial.println();

  Serial.print("mqttTemp ");
  Serial.print((unsigned long) &amp;mqttTemp, DEC);
  Serial.print(": ");
  for (int i = 0; i &lt; 6; i++) {
    Serial.print((int) mqttTemp[i], DEC);
    Serial.print(' ');
  }
  Serial.println();
}

void loop() {
  delay(50);
  // put your main code here, to run repeatedly:

}
</code></pre>

<p>The above outputs the following:</p>

<pre><code>before
mqttPres 1073644748: 80 80 80 80 0 
mqttHum  1073644753: 72 72 72 72 72 0 
mqttTemp 1073644759: 84 84 84 84 84 0 
converted temp
mqttPres 1073644748: 80 80 80 80 0 
mqttHum  1073644753: 72 72 72 72 72 0 
mqttTemp 1073644759: 50 53 46 53 55 0 
converted hum
mqttPres 1073644748: 80 80 80 80 0 
mqttHum  1073644753: 52 48 46 49 53 0 
mqttTemp 1073644759: 50 53 46 53 55 0 
converted press
mqttPres 1073644748: 57 55 54 56 52 
mqttHum  1073644753: 0 48 46 49 53 0 
                     ^ ======== note the leading 0
mqttTemp 1073644759: 50 53 46 53 55 0 
</code></pre>

<p>The simplest fix, of course, is to declare your variables with the correct size</p>

<pre><code>char mqttTemp[7]; // because -10.00 takes 6 characters + 1 for NULL
char mqttHum[7];  // because 100.00 takes 6 characters + 1 for NULL
char mqttPres[6]; // because 97684 takes 5 characters + 1 for NULL - if pressure can reach 100000 then use 7 here as well
</code></pre>

<p>and then use <code>dtostrf</code> <strong>correctly</strong>, i.e. the second argument is the total width, including <code>.</code> and a possible <code>-</code></p>

<pre><code>dtostrf(temp,6,2,mqttTemp);
dtostrf(hum,6,2,mqttHum);
dtostrf(pres,5,0,mqttPres);
</code></pre>
