Float to Array - can't find solution

Hello all,

Firstly, thank you for taking the time to read my question here. I appreciate your time.

I am new to Arduino and electronics. I have PHP programming experience so the programming is not totally foreign though I am learning new bits each day.

I have a simple task I am trying to complete, display to a 4 digit 7-seg display using a serial register. I have the thing hooked up and working when I specify the numbers individually, but I am having difficulty getting my float into a char array so I can parse it and determine where the decimal need displayed etc when getting the number from a temp sensor or potentiometer etc.

So, I have tried dtostrf() and it seems to be flaky at best. I have tried to do straight math for determining, but am having problems with that. I have tried sprintf() and it produces a ?.

I have seen multiple ways, but can't find one that works for me and is rock solid.

My latest math based version is this..... The test number with no decimal works no problem and I get each digit properly... but when it comes to the decimal point, I am lost as to how to get it int it's own var.

temp = 127.4; // float to determine decimal
// temp = 1324; // normal 4-digit number

int d; int c; int b; int a;

  a = temp / 1000;   // returns proper number
  b = (temp - (a * 1000)) / 100; 
  c = (temp - ( (a * 1000) + (b * 100) ) ) / 10;
  d = (temp - ( (a * 1000) + (b * 100) + (c * 10) ) );

So, if someone can assist me in what the easiest way to get a float into a char array with the decimal point in it's own array item, I would appreciate it.

stdio.h library sprintf() fills a char buffer with formatted output.

Variant of printf() that sends the formatted characters to string s.

Formatting reference is lower down the same page.

So, I have tried dtostrf() and it seems to be flaky at best.

What do you mean by "flaky"? It works fine for me.

char buf[8];
void setup() {
  Serial.begin(9600);
  dtostrf(123.45,7,2,buf);
  Serial.println(buf);
  dtostrf(123.45,7,1,buf);
  Serial.println(buf);
}
void loop(){}

Result:

 123.45
  123.4

sprintf will handle floats, but only if you enable the floating point version in the IDE.

Where did the floating point temperature come from? It would probably be easier to work the the raw data.

If you want to separate the integer and fractional parts of the float, you could try something like this (for positive numbers only).

float f = 123.45;
int if = f; //integer part
float frac = f - if; //fractional part
int ifrac = 10.0*frac;  //first decimal place as integer (OR...)
int i2frac = 100.0*frac //first two decimal places as integer

Using the StaticString library

etk::StaticString<20> ss; //make a staticstring with a max length of 20 chars
float f = 123.45; //make a float
ss = 123.45; //assign float to sss
//ss now contains "123.45" in ASCII
Serial.println(ss.c_str());

char c1 = ss[0]; // c1 = '1'
char c2 = ss[1]; //c2 = '2' . . . and so on

Floats are monumentally slow on AVR's.
Floats are 'dirty'. 1.0 can become .999999 very easily.

If you can work with fixed-point integers, 32-bit longs are capable of 9 digits all 0 to 9 and sign.
Those are about 100x as fast as floats.

Using sprintf() you can format the decimal place in between integer prints and add a label too.

PS, didn't a fast divide by 10 algorithm come out of a thread just for faster printing?