save that file to a floatToString.h in your project directory and go to town. (On my mac, I have to restart Arduino before I can import the file in a pde). There is example/test code in the comments field at the bottom of the file.
With this function, I have it require a char * buffer be passed in that it writes to.
If I wanted to create a new string inside that function, and return that instead, I assume that woud require malloc?
Anyways, I figured passing in a buffer from the location of your choice would be preferable anyway.
Hope it comes in handy, and please let me know if you find any bugs!
I notice that your code uses and instead of && . not instead of ! , I was wondering why this syntax is used?
Heh I see you've highlighted the keywords, I had to read that sentence three times to correctly parse it ;D. I didn't even know you could use the keywords and and not in C!
mem I think your code is probably better, but I really need the right justify function for my OSD, since it makes changing numbers much easier to read. I think I'll try to combine both codes to get what I want...
Those "and" and "or" keywords come from iso646.h, which is automatically included, ostensibly to help people with "international" or "non-QWERTY" keyboards. To me it seems more problematic than useful. See http://en.wikipedia.org/wiki/Iso646.h.
I've looked around the forum, but couldn't find a FloatToStr function that actually worked with out any bugs.
Tim's code has some problem displaying zero.
Mem's code does not have proper rounding, does not allow setting text minimum width.
Don's code also has some issues displaying zero and negative values
So I've combined mem's code with Tim's code, and a little bit from Don. This hopefully should work as a compact sprintf() replacement that has no bugs (famous last words :D). Maybe it can be more efficient, but I think it's pretty good.
char * floatToString(char * outstr, double val, byte precision, byte widthp){
char temp[16];
byte i;
// compute the rounding factor and fractional multiplier
double roundingFactor = 0.5;
unsigned long mult = 1;
for (i = 0; i < precision; i++)
{
roundingFactor /= 10.0;
mult *= 10;
}
temp[0]='\0';
outstr[0]='\0';
if(val < 0.0){
strcpy(outstr,"-\0");
val = -val;
}
val += roundingFactor;
strcat(outstr, itoa(int(val),temp,10)); //prints the int part
if( precision > 0) {
strcat(outstr, ".\0"); // print the decimal point
unsigned long frac;
unsigned long mult = 1;
byte padding = precision -1;
while(precision--)
mult *=10;
if(val >= 0)
frac = (val - int(val)) * mult;
else
frac = (int(val)- val ) * mult;
unsigned long frac1 = frac;
while(frac1 /= 10)
padding--;
while(padding--)
strcat(outstr,"0\0");
strcat(outstr,itoa(frac,temp,10));
}
// generate space padding
if ((widthp != 0)&&(widthp >= strlen(outstr))){
byte J=0;
J = widthp - strlen(outstr);
for (i=0; i< J; i++) {
temp[i] = ' ';
}
temp[i++] = '\0';
strcat(temp,outstr);
strcpy(outstr,temp);
}
return outstr;
}
I'm having rounding problems with your function. I did try to write my own ftoa function, but also have the same rounding issues as with your function. Check out this:
Thanks for pointing out the mistake. I found out that there is a problem in the my function. Because the function itoa is used to convert numbers, and it is a integer (16bit) function, so there is a problem when you specify precision > 4 digits, the function therefore only works for values less than xxxx.xxxx.
I have modified it so that it uses ltoa instead, which uses long integers, so that should be plenty of digits. I'm also pretty much rewritten the function, so now it should be smaller and more efficient.
char * floatToString(char * outstr, double val, byte precision, byte widthp){
char temp[16]; //increase this if you need more digits than 15
byte i;
temp[0]='\0';
outstr[0]='\0';
if(val < 0.0){
strcpy(outstr,"-\0"); //print "-" sign
val *= -1;
}
if( precision == 0) {
strcat(outstr, ltoa(round(val),temp,10)); //prints the int part
}
else {
unsigned long frac, mult = 1;
byte padding = precision-1;
while (precision--)
mult *= 10;
val += 0.5/(float)mult; // compute rounding factor
strcat(outstr, ltoa(floor(val),temp,10)); //prints the integer part without rounding
strcat(outstr, ".\0"); // print the decimal point
frac = (val - floor(val)) * mult;
unsigned long frac1 = frac;
while(frac1 /= 10)
padding--;
while(padding--)
strcat(outstr,"0\0"); // print padding zeros
strcat(outstr,ltoa(frac,temp,10)); // print fraction part
}
// generate width space padding
if ((widthp != 0)&&(widthp >= strlen(outstr))){
byte J=0;
J = widthp - strlen(outstr);
for (i=0; i< J; i++) {
temp[i] = ' ';
}
temp[i++] = '\0';
strcat(temp,outstr);
strcpy(outstr,temp);
}
return outstr;
}
Would this be valid documentation for use of this function to add to the top of floatToString.h ?
Please correct where needed.
/*
* floatToString.h
*
* Usage: floatToString(buffer string, float value, precision, minimum text width)
*
* Example:
* char test[20]; // string buffer
* float M; // float variable to be converted
* // precision -> number of decimal places
* // min text width -> character output width, 0 = no right justify
*
* Serial.print(floatToString(test, M, 3, 7)); // call for conversion function
*
*/