# Sprintf() with float values

**URL:** <https://forum.arduino.cc/t/sprintf-with-float-values/937562>\
**Category:** Programming\
**Created:** [December 19, 2021, 11:07pm UTC](https://forum.arduino.cc/t/sprintf-with-float-values/937562 "2021-12-19T23:07:33Z")\
**Posts on this page:** 16\
**Page:** 1

<div class="post-metadata">

**Author:** ![l-p-g](https://avatars.discourse-cdn.com/v4/letter/l/e9a140/32.png) [@l-p-g](https://forum.arduino.cc/u/l-p-g)\
**Post date:** [December 19, 2021, 11:07pm UTC](https://forum.arduino.cc/t/sprintf-with-float-values/937562/1 "2021-12-19T23:07:33Z")

</div>

I have an issue when sending floats to sprint(). I'm pretty sure the issue I have is that i'm using the signed int specifier on values that return floats which is causing my sprintf to go out of whack (See screenshot below where the println is normal but sprint is messed up).

That being said I can't seem to find a good resource showing how to use the %f specifier on sprintf(). I know I need to specify the decimal points but my Google-Fu is failing me trying to find the formatting that %f expects. The only link I've found is the one below but it lacks what I'm looking for.

> **[C library function - sprintf()](https://www.tutorialspoint.com/c_standard_library/c_function_sprintf.htm)**
>
> The C library function int sprintf(char \*str, const char \*format, ...) sends formatted output to a string pointed to, by str.

Here's my code and a screenshot showing the issue.

```cpp
int LED = 13;
int loopCounter = 0;  
const int pressureInput = A1; //select the analog input pin for the pressure transducer
const int pressureZero = 97; //analog reading of pressure transducer at 0psi
const int pressureMax = 921.6; //analog reading of pressure transducer at 100psi
const int pressuretransducermaxPSI = 100; //psi value of transducer being used
const int baudRate = 9600; //constant integer to set the baud rate for serial monitor
const int sensorreadDelay = 500; //constant integer to set the sensor read delay in milliseconds
int pressureValue = 0; //variable to store the value coming from the pressure transducer
int pressurePSI = 0;
void setup()
{
  pinMode(LED, OUTPUT);
  Serial.begin(baudRate);
}

void loop()
{
  digitalWrite(LED, HIGH); 
  pressureValue = analogRead(pressureInput);
  float voltage = (pressureValue*5.0)/1024.0;

  //for some off reason the voltage calculation returns < 0 randomly
  if (voltage >= 0)
  {
    pressurePSI = ((pressureValue-pressureZero)*pressuretransducermaxPSI)/(pressureMax-pressureZero);
   
    char buffer[80];
    sprintf(buffer,"{\"psi\": \"%d\",\"voltage\": \"%d\",\"analogRead\": \"%d\",\"loop\": \"%d\"}", pressurePSI,voltage, pressureValue, loopCounter);
    Serial.println(buffer);
    Serial.println(pressurePSI);
    Serial.println(voltage);
    Serial.println(pressureValue);
    Serial.println(loopCounter);
  }

  delay(sensorreadDelay); //delay in milliseconds between read values
  digitalWrite(LED, LOW);
  loopCounter++;
  
  if (loopCounter == 2000)
  {
    loopCounter = 0;
  }
}

```

 ![image](https://europe1.discourse-cdn.com/arduino/original/4X/e/f/b/efb90105d84e20890d85db11b010ebc7c474dadf.png)

---

<div class="post-metadata">

**Author:** ![seanboe](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/seanboe/32/676361_2.png) [@seanboe](https://forum.arduino.cc/u/seanboe)\
**Post date:** [December 19, 2021, 11:11pm UTC](https://forum.arduino.cc/t/sprintf-with-float-values/937562/2 "2021-12-19T23:11:33Z")

</div>

The `%d` modifier is used for integers. For floats, use the `%f` modifier.

---

<div class="post-metadata">

**Author:** ![hzrnbgy](https://avatars.discourse-cdn.com/v4/letter/h/90db22/32.png) [@hzrnbgy](https://forum.arduino.cc/u/hzrnbgy)\
**Post date:** [December 19, 2021, 11:13pm UTC](https://forum.arduino.cc/t/sprintf-with-float-values/937562/3 "2021-12-19T23:13:20Z")

</div>

```cpp
sprintf(buffer, "%.2f %.2f %.2f", 1.00, 3.14, 6.7890)

```

I think Arduino IDE by default does not enable floats with sprintf...

---

<div class="post-metadata">

**Author:** ![l-p-g](https://avatars.discourse-cdn.com/v4/letter/l/e9a140/32.png) [@l-p-g](https://forum.arduino.cc/u/l-p-g)\
**Post date:** [December 19, 2021, 11:16pm UTC](https://forum.arduino.cc/t/sprintf-with-float-values/937562/4 "2021-12-19T23:16:01Z")

</div>

> sprintf(buffer, "%.2f %.2f %.2f", 1.00, 3.14, 6.7890)  
> I think Arduino IDE by default does not enable floats with sprintf...

is the .2 in %.2f telling sprintf to expect a number followed by two decimals?

---

<div class="post-metadata">

**Author:** ![l-p-g](https://avatars.discourse-cdn.com/v4/letter/l/e9a140/32.png) [@l-p-g](https://forum.arduino.cc/u/l-p-g)\
**Post date:** [December 19, 2021, 11:17pm UTC](https://forum.arduino.cc/t/sprintf-with-float-values/937562/5 "2021-12-19T23:17:43Z")

</div>

> [@seanboe](#):
>
> The `%d` modifier is used for integers. For floats, use the `%f` modifier.

I don't want to be a d1ck and sound ungrateful but did you read the question? I know I need to use %f but I don't know how to tell it the decimal points to expect.

---

<div class="post-metadata">

**Author:** ![hzrnbgy](https://avatars.discourse-cdn.com/v4/letter/h/90db22/32.png) [@hzrnbgy](https://forum.arduino.cc/u/hzrnbgy)\
**Post date:** [December 19, 2021, 11:18pm UTC](https://forum.arduino.cc/t/sprintf-with-float-values/937562/6 "2021-12-19T23:18:15Z")

</div>

It means print to two decimal points. **3.14161238721387124358123475124877651** would be printed as **3.14**

---

<div class="post-metadata">

**Author:** ![l-p-g](https://avatars.discourse-cdn.com/v4/letter/l/e9a140/32.png) [@l-p-g](https://forum.arduino.cc/u/l-p-g)\
**Post date:** [December 19, 2021, 11:19pm UTC](https://forum.arduino.cc/t/sprintf-with-float-values/937562/7 "2021-12-19T23:19:58Z")

</div>

Cool, that's exactly what I was looking for. Any idea how sprint would behave if I tell it to expect 4 decimal points and only 2 are sent?

---

<div class="post-metadata">

**Author:** ![hzrnbgy](https://avatars.discourse-cdn.com/v4/letter/h/90db22/32.png) [@hzrnbgy](https://forum.arduino.cc/u/hzrnbgy)\
**Post date:** [December 19, 2021, 11:21pm UTC](https://forum.arduino.cc/t/sprintf-with-float-values/937562/8 "2021-12-19T23:21:45Z")

</div>

I dont have personal experience with this but my guess is it will append two zeroes

3.14 becomes 3.1400

You would have to check it to make sure...

---

<div class="post-metadata">

**Author:** ![anon94801460](https://avatars.discourse-cdn.com/v4/letter/a/278dde/32.png) [@anon94801460](https://forum.arduino.cc/u/anon94801460)\
**Post date:** [December 19, 2021, 11:22pm UTC](https://forum.arduino.cc/t/sprintf-with-float-values/937562/9 "2021-12-19T23:22:20Z")

</div>

A floating point number does not contain a specific number of digits after the decimal point.

With 32 bit floats, you get about 6 or 7 meaningful digits, total. With 64 bit doubles, in the few Arduino MCUs where doubles are actually implemented, you get about 15 meaningful digits, total.

As stated above, on most Arduinos, sprint() **does not** support floats or doubles.

---

<div class="post-metadata">

**Author:** ![Blackfin](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/blackfin/32/238871_2.png) [@Blackfin](https://forum.arduino.cc/u/Blackfin)\
**Post date:** [December 19, 2021, 11:32pm UTC](https://forum.arduino.cc/t/sprintf-with-float-values/937562/10 "2021-12-19T23:32:56Z")

</div>

Look into using dtostrf():

```cpp
float fPI = PI;
char
    szStr[30],
    szF[6];

    
void setup( void )
{
    Serial.begin(115200);
    dtostrf( fPI, 4, 2, szF );
    sprintf( szStr, "PI is %s", szF );
    Serial.println( szStr );
    
}//setup

void loop( void )
{
}//loop

```

---

<div class="post-metadata">

**Author:** ![mrburnette](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/mrburnette/32/702556_2.png) [@mrburnette](https://forum.arduino.cc/u/mrburnette)\
**Post date:** [December 19, 2021, 11:35pm UTC](https://forum.arduino.cc/t/sprintf-with-float-values/937562/11 "2021-12-19T23:35:09Z")

</div>

It appears you are trying to create a JSON'ish output for downstream. Many downstream tools like nodeRED can easily postprocess the data.

[https://www.stm32duino.com/viewtopic.php?t=959](https://www.stm32duino.com/viewtopic.php?t=959)

 ![image](https://europe1.discourse-cdn.com/arduino/original/4X/5/0/d/50d0818a74eb90ca8ad302e50a53d2a486f6a5b0.png)

---

<div class="post-metadata">

**Author:** ![gfvalvo](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/gfvalvo/32/1013044_2.png) [@gfvalvo](https://forum.arduino.cc/u/gfvalvo)\
**Post date:** [December 19, 2021, 11:55pm UTC](https://forum.arduino.cc/t/sprintf-with-float-values/937562/12 "2021-12-19T23:55:08Z")

</div>

> [@l-p-g](#):
>
> Cool, that's exactly what I was looking for. Any idea how sprint would behave if I tell it to expect 4 decimal points and only 2 are sent?

It's not the number to of digits to "expect" or how many are "sent". It's the number to print. As already noted, a [32-bit floating point number](https://en.wikipedia.org/wiki/Single-precision_floating-point_format) is good for 5-7 significant digits. You can print out beyond that, but those extra digits will be garbage.

You should read this: [https://www.cplusplus.com/reference/cstdio/printf/](https://www.cplusplus.com/reference/cstdio/printf/)

---

<div class="post-metadata">

**Author:** ![l-p-g](https://avatars.discourse-cdn.com/v4/letter/l/e9a140/32.png) [@l-p-g](https://forum.arduino.cc/u/l-p-g)\
**Post date:** [December 20, 2021, 12:47pm UTC](https://forum.arduino.cc/t/sprintf-with-float-values/937562/13 "2021-12-20T12:47:11Z")

</div>

Thank you @anon94801460 @Blackfin, Now I understand why sprtinf wasn't working with %f. I went ahead and implemented dtostrf and everything is working now.

Final code for anyone else who may be stumble upon this:

```cpp
int LED = 13;
int loopCounter = 0;  
const int pressureInput = A1; //select the analog input pin for the pressure transducer
const int pressureZero = 97; //analog reading of pressure transducer at 0psi
const int pressureMax = 921.6; //analog reading of pressure transducer at 100psi
const int pressuretransducermaxPSI = 100; //psi value of transducer being used
const int baudRate = 9600; //constant integer to set the baud rate for serial monitor
const int sensorreadDelay = 500; //constant integer to set the sensor read delay in milliseconds
int pressureValue = 0; //variable to store the value coming from the pressure transducer
int pressurePSI = 0;

void setup()
{
  pinMode(LED, OUTPUT);
  Serial.begin(baudRate);
}

void loop()
{
  digitalWrite(LED, HIGH); 
  pressureValue = analogRead(pressureInput);
  float voltage = (pressureValue*5.0)/1024.0;

  pressurePSI = ((pressureValue-pressureZero)*pressuretransducermaxPSI)/(pressureMax-pressureZero);

  char vBuffer[15];
  dtostrf(voltage,4,2, vBuffer);
 
  char buffer[80];    
  sprintf(buffer,"{\"psi\": \"%d\",\"voltage\": \"%s\",\"analogRead\": \"%d\",\"loop\": \"%d\"}", pressurePSI, vBuffer, pressureValue, loopCounter);
  Serial.println(buffer);
  //Serial.println(pressurePSI);
  //Serial.println(voltage);
  //Serial.println(pressureValue);
  //Serial.println(loopCounter);

  delay(sensorreadDelay); //delay in milliseconds between read values
  digitalWrite(LED, LOW);
  loopCounter++;
  
  if (loopCounter == 2000)
  {
    loopCounter = 0;
  }
}

```

---

<div class="post-metadata">

**Author:** ![l-p-g](https://avatars.discourse-cdn.com/v4/letter/l/e9a140/32.png) [@l-p-g](https://forum.arduino.cc/u/l-p-g)\
**Post date:** [December 20, 2021, 12:50pm UTC](https://forum.arduino.cc/t/sprintf-with-float-values/937562/14 "2021-12-20T12:50:51Z")

</div>

> It appears you are trying to create a JSON'ish output for downstream. Many downstream tools like nodeRED can easily postprocess the data.
> 
> [Serial output directly into NodeRED - Arduino for STM32](https://www.stm32duino.com/viewtopic.php?t=959)

So yes, you are correct that I'm sending the data to another system and in fact I am using Node-Red upstream. However, I want to separate the data at the moment of ingestion, and formatting it into JSON directly out of the Arduino allows me to program node-red to separate the deserialized objects without the need for conversion.

Unless there is something I'm missing here. How else would node separate multiple incoming values without the need to write some logic to split based on a separator?

---

<div class="post-metadata">

**Author:** ![mrburnette](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/mrburnette/32/702556_2.png) [@mrburnette](https://forum.arduino.cc/u/mrburnette)\
**Post date:** [December 20, 2021, 2:45pm UTC](https://forum.arduino.cc/t/sprintf-with-float-values/937562/15 "2021-12-20T14:45:08Z")

</div>

> [@l-p-g](#):
>
> I want to separate the data at the moment of ingestion, and formatting it into JSON directly out of the Arduino allows me to program node-red to separate the deserialized objects without the need for conversion.

Which is perfectly normal. However, NodeRED can treat payloads differently as described in the documentation for JSON:  
[https://nodered.org/docs/user-guide/messages](https://nodered.org/docs/user-guide/messages)

> The Function node allows you to run any JavaScript code against the message. This gives you complete flexibility in what you do with the message, but does require familiarity with JavaScript and is unnecessary for many simple cases. More information about writing Functions is available [here](https://nodered.org/docs/writing-functions).  
> The Change node provides a lot of functionality without needing to write JavaScript code. Not only can it modify message properties, but it can also access flow- and global-context.  
> It provides four basic operations:
> 
> - `Set` a property to a value,
> - `Change` a String property by performing a search and replace,
> - `Delete` a property,
> - `Move` a property.

The take-away IMO is that one should approach a solution appropriate to their need and comfortable enough that they can support and extend the software.

---

<div class="post-metadata">

**Author:** ![system](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/system/32/1140315_2.png) [@system](https://forum.arduino.cc/u/system)\
**Post date:** [June 18, 2022, 2:45pm UTC](https://forum.arduino.cc/t/sprintf-with-float-values/937562/16 "2022-06-18T14:45:44Z")

</div>

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.
