sprintf problem

This is one of those moments where I have just been looking at the same piece of code too long and can't see the error which must be right in front of me. I even slept on it and came back to it this morning...

Here's my code snippet:

  char cInfo[64];
  float fTemp;
  float fHum;
  // Read temperature & humidity
  fTemp = dht.readTemperature();
  fHum = dht.readHumidity();
Serial.print(F("T: "));
Serial.print(F(" - H: "));

  // Format output
  sprintf(cInfo, "%02u/%02u/%4u,%02u:%02u:%02u,%.2f,%.2f", day(), month(), year(), hour(), minute(), second(), fTemp, fHum);

  // Output info to file

Normally this code should be used to print out the current date, time, temperature and humidity as a comma-separated list to a file. But when I looked at the file the temperature and humidity values were question marks. That's when I started adding the debug serial outputs to see. The problem happens just after the sprintf call.

The result of the above code looks like this:

T: 18.90 - H: 34.70

The first line confirms, to me, that the temperature and humidity values are being read properly and stored in their float variables. The second line shows me what was just written to the file.

The problem appears to be in the sprintf conversion. I have tried using "%f", "%2.2f", "%2f" and "%d". That last one was a desperate measure and produced spurious numbers.

I'm sure this is something simple I'm missing... but I just can't see it.

Thank you in advance for any suggestions or directions you may point me in.

The Arduino IDE uses the avr gcc compiler. That compiler has a set of default libraries included. But ..... not the floating point library for sprintf. So every float results into a question mark.

If you use the avr gcc compiler (without the Arduino IDE) it is possible to link those libraries and have a sprintf working with floats. But the code size increases. I don't know how to do that with the Arduino, but it is possible.

Many of us would like the Arduino to include that library by default. But that is not yet the case.

I think "dtostrf()" is the workaround.

I have tried using "%f", "%2.2f", "%2f" and "%d".

None of those formats look good to me. %f and %d are OK.

If you want a floating point number with 2 decimal places, you need something like %6.2f, where the first number ( 6 ) is the total number of characters and the second ( 2 ) is the number of digits after the decimal point.

I was unaware of the problems with floats and sprintf within Arduino. Krodal's comments pointed me in the right direction and I started looking for problems of that type here. I found even more info, and a solution I was able to apply, in a different thread here:


Michinyon : All of my sprintf arguments are perfectly fine within C and C++. The formats I mentioned, %f, %2.2f, %2f and %d are all valid and should have worked. It's Arduino that has a bug with %f not me. :) Obviously using %d on a float is going to produce spurious values. But that was out of desperation. :~

Krupski : Thank you for your extremely helpful suggestion of pde.jar. I will look in to that possibility in the future. However this sketch is the beginnings of a project which is going to soon run up against the memory space wall and I can't spare the 1.5k for this one. 8)

Thanks all and I, like many others I assume, look forward to the day that %f works properly within the standard Arduino libraries.

Krupski, that is a cool feature addition. If you want it to live forever, get it into the Arduino mainline by packaging up and posting a pull request to the core guys on the Arduino github: https://github.com/arduino/Arduino