December 30, 2015

How to sprintf a float with Arduino

Arduino has a small limitation in sprintf function that does not print correctly float numbers.
The following test sketch demonstrates the problem

void setup()
{
  Serial.begin(115200);
}
 
void loop()
{
  float f = 123.12F;
  Serial.print("Original value: ");
  Serial.println(f);

  char str[50];
  sprintf(str, "String value: %f", f);
  Serial.println(str);
  
  Serial.println();
  delay(2000);
}

You can see from the screenshot below that the float is always formatted a question mark '?'.


Using integer trick


There is a little trick to correctly print the float value using sprintf.

sprintf(str, "String value: %d.%02d", (int)f, (int)(f*100)%100);


This trick works well only with positive numbers and formats the float with two fixed decimals.



Using dtostrf function


A better solution is to use the dtostrf function. It it is more flexible and works well also with negative numbers.
These two lines of code will write a string into the buffer with strcpy function and the append the float value using the dtostrf function.

strcpy(str, "String value using dtostrf: ");
dtostrf(f, 2, 2, &str[strlen(str)]);



6 comments:

  1. Programming is very interesting and creative thing if you do it with love. Your blog code helps a lot to beginners to learn programming from basic to advance level. I really love this blog because I learn a lot from here and this process is still continuing.
    Love from Pro Programmer

    ReplyDelete
  2. This comment has been removed by the author.

    ReplyDelete
  3. This comment has been removed by the author.

    ReplyDelete
  4. The integer method is neat, but it has a little quirk: 12.4 is printed as "12.40" (it's OK) and 12.04 is printed as "12.4" (and it is confusing)

    ReplyDelete
    Replies
    1. You are right the example is not working perfectly.
      This should work.
      sprintf(str, "String value: %d.%02d", (int)f, (int)(f*100)%100);

      I have corrected the example.
      Thank you.

      Delete
  5. for negative floats just use an abs()-fuction:
    sprintf(str, "String value: %d.%02d", (int)f, abs((int)(f*100)%100));

    ReplyDelete