FloatToString.h

I have been successfully using some FloatToString code (originally by Tim Hirzel) for sme time, but curiously it is my Sketches directory as a ".h" file and is initialized using:

#include "FloatToString.h"
char valBuffer[15];

Later it is called using this (for example):

FloatToString(valBuffer, volts,2);

And here is the contents of FloatToString.h

// floatToString.h. Tim Hirzel tim@growdown.com March 2008
// If you don't save this as a .h, you will want to remove the default arguments 
// uncomment this first line, and swap it for the next.  
// (I don't think keyword arguments compile in .pde files)

#include "Arduino.h"

//  write a float value to string, outstr is returned string.
char * FloatToString(char * outstr, float value, int places, int minwidth=0, bool rightjustify=false) {
    int i, digit;
    int c = 0, tenscount = 0, extra = 0;
    int charcount = 1;
    float tens = 0.1;
    float tempfloat = value;
    // make sure we round properly. this could use pow from <math.h>, 
    // but doesn't seem worth the import. if this rounding step isn't 
    // here, the value 54.321 prints as 54.3209
    float d = 0.5;                               // calculate rounding term d:   0.5/pow(10,places)  
    if (value < 0) d *= -1.0;
    for (i = 0; i < places; i++) d/= 10.0;       // divide by ten for each decimal place
    tempfloat +=  d;                             // this small addition, plus truncation, will round values properly 

    if (value < 0)tempfloat *= -1.0;             // first get value tens to be the large power of ten less than value    
    while ((tens * 10.0) <= tempfloat) {tens *= 10.0; tenscount += 1;}

    if (tenscount > 0) charcount += tenscount; else charcount += 1;
    if (value < 0) charcount += 1; charcount += 1 + places;

    minwidth += 1;                                // count the null final character
    if (minwidth > charcount){        
        extra = minwidth - charcount;
        charcount = minwidth;}

    if (extra > 0 and rightjustify) {for (int i = 0; i< extra; i++) {outstr[c++] = ' ';} }

    if (value < 0) outstr[c++] = '-';            // write the negative sign if needed

    if (tenscount == 0) outstr[c++] = '0';

    for (i=0; i< tenscount; i++) {
        digit = (int) (tempfloat/tens);
        itoa(digit, &outstr[c++], 10);
        tempfloat = tempfloat - ((float)digit * tens);
        tens /= 10.0;}
                                                 // if no places after decimal, stop now and return
    if (places > 0) outstr[c++] = '.';           // otherwise, write the point and continue on

                                                 // now write out each decimal place by shifting digits one by one 
    for (i = 0; i < places; i++) {               // into the ones place and writing the truncated value
        tempfloat *= 10.0; 
        digit = (int) tempfloat;
        itoa(digit, &outstr[c++], 10);
        tempfloat = tempfloat - (float) digit;}  // once written, subtract off that digit

    if (extra > 0 and not rightjustify) {
        for (int i = 0; i< extra; i++) {outstr[c++] = ' ';}}

    outstr[c++] = '\0'; return outstr;
}

Three questions if I may:

  1. how do I change this so the ".h" file becomes a normal ".ino" and I don't have to use #include etc ?
  2. why doesn't this compile if I change the #include to #include <FloatToString.h> ?
  3. is there a more elegant way to convert float to string ?

TIA

  1. how do I change this so the ".h" file becomes a normal ".ino" and I don't have to use #include etc ?

Copy and paste. But, why?

  1. why doesn't this compile if I change the #include to #include <FloatToString.h> ?

Because #include <> and #include "" cause the compiler to look in different places for the file. The file is in the "" place, not the <> place.

3) is there a more elegant way to convert float to string ?

There is a dtostrf() function.

PaulS:

  1. how do I change this so the ".h" file becomes a normal ".ino" and I don't have to use #include etc ?

Copy and paste. But, why?

Partly for my education, partly because it stands out as an annoying exception - none of my other function calls require me to include anything. I did try cut and paste recently but I get this error: 'FloatToString' was not declared in this scope??
(I also commented the line #include "Arduino.h" out as I assume it's redundant)

PaulS:

  1. why doesn't this compile if I change the #include to #include <FloatToString.h> ?

Because #include <> and #include "" cause the compiler to look in different places for the file. The file is in the "" place, not the <> place.

simple enough, thanks

PaulS:

3) is there a more elegant way to convert float to string ?

There is a dtostrf() function.

could you provide a pointer to info about that call please?

another question: why is this a ".h" file anyway? I thought header files are meant to be for pre-declarations, whereas this file is just code ?

another question: why is this a ".h" file anyway? I thought header files are meant to be for pre-declarations, whereas this file is just code ?

The preprocessor doesn't care what type of file you try to include. You could include a .cpp file or a .jpeg file if you wanted to. By convention, though, only .h files are #included.

Typically, a header file contains declarations only, but there isn't anything to preclude having executable code in the header file.

Partly for my education, partly because it stands out as an annoying exception - none of my other function calls require me to include anything.

What other function calls are you referring to? You should see some of the files I create for work. Some of them have 40 or 50 other header files included. Don't complain about having to include one lousy file...

I did try cut and paste recently but I get this error: 'FloatToString' was not declared in this scope??

So, we'd need to see how you did it. Generally, all ino files are merged for compilation as a single file. so the function should be in scope.

could you provide a pointer to info about that call please?

Sure, but so can google, so, I'll defer.

PaulS:

... none of my other function calls require me to include anything.

What other function calls are you referring to? ... Don't complain about having to include one lousy file...

My program is about 46,000 bytes, spread over 6 or 7 tabs in the IDE, so there are many other functions that are called from setup and/or loop. But they require zero (nil, zilch) #include statements (other than #includes for contributed libraries) so why should I have to start now, and it may only be required for this one only?!

PaulS:

I did try cut and paste recently but I get this error: 'FloatToString' was not declared in this scope??

So, we'd need to see how you did it. Generally, all ino files are merged for compilation as a single file. so the function should be in scope.

I'll attach the whole lot as a zip below, or later

PaulS:
... but so can google, so, I'll defer.

doh ... I should've thought of that! :blush:

CJ_09.zip (18.2 KB)

Which of those ino files is supposed to contain the FloatToString function?

Does this code work OK with negative numbers at all? Try -3.6.

PaulS:
Which of those ino files is supposed to contain the FloatToString function?

in FloatTostring.h. I provided the code to show all the other functions which don't need includes. That code compiles without errors.

But I've since succeeded in transferring it from the h file into zzMisc.ino so it compiles without errors also (new ZIP attached below). Now FloatToString function works without need for any include statement, same as all the other functions in the sketch. Excellent thanks again PaulS.

liudr:
Does this code work OK with negative numbers at all? Try -3.6

yes. I'm at latitude 34.815 degrees south, and my LCD is displaying "-34.815" as I write this.

ninja2:

liudr:
Does this code work OK with negative numbers at all? Try -3.6

yes. I'm at latitude 34.815 degrees south, and my LCD is displaying "-34.815" as I write this.

We are almost on opposite ends of the world then. My longitude is negative and latitude is positive :slight_smile:

I've managed to supersede FloatToSting using dtostrf() .... and it works. Yahoo :slight_smile:

I also discovered dtostre() for scientific notation (e.g. -3.482e+01 for -34.815). nice.

double excellent !!

liudr:
We are almost on opposite ends of the world then. My longitude is negative and latitude is positive :slight_smile:

indeed. google maps tells me you're around 46N 95W.... if you really want to be antipodal compared to Adelaide you'll need to get to 34.8N and 42W ... somewhere mid-Atlantic. Might be a bit awkward :astonished:

You could use a C character array type string and sprintf(). You might even already include string.h.