I thought this would be easy. I have 2 integers that I cast to floats and divide, I then try to format the output with sprintf..
char* str = " ";
int i1 = 5;
int i2 = 10;
float f = ((float)i1)/((float)i2);
sprintf(str, "%f%c", f, 0x00);
I get a question mark. Why? I have tried doubles as well, same thing. The float value is correct, if I do a print to Serial and monitor the output it works fine.
What I actually want is %5.1f but it just doesn't work.
The problem is not sprintf() but really the IDE.
AVR libc does have floating support for xxprintf() routines.
But because floating point takes a considerable amount of code space,
there are multiple versions of the xxprintf() routines.
The default version of sprintf() does not support floating point.
You could link in the floating point version, but the IDE has the linker
options hard coded in the JAVA code.
Because of this you are SOL using the Arduino IDE.
However, you could leave the standard Arduino IDE behind and switch
over to mpide.
mpide allows you to set the compiler and linker options so you
could set the options you need using that version of the "arduino" IDE.
mpide is not currently up to 1.0 functionality though.
If all you need is something as simple as %5.1f then you could create the two parts
separately using integer math.
It would be smaller as the guts under sprintf() eats up about 1.8k or
so of code.
The same thing was bugging me for a day or so; not being able to inject the proper linker options to link against the float enabled versions of the necessary libs.
I ended up building 2 environments (both solving the problem):
setting up an Eclipse environment with the Arduino plugin (where AVR toolchain, so Linker options can be fine-tuned) /working on a larger project, it was a must, anyway/
forking and patching the Arduino IDE to take additional preferences and call the avr-gcc accordingly /for simpler sketches it is the faster option, also the Serial Monitor is lacking from the Eclipse project/
indeed, the binary size gets larger /more or less, depending on the optimization options passed/, but I wonder how larger the binary would get if I reimplemented printf/scanf with some 'proprietary' hacks to get the float values printed properly (from argument lists, especially)... ]
Here's a quick and dirty function to convert a float to a formatted ASCII string:
/*----------------------------------------------------------------------------*/
/* f2a() - convert x to string with l places left of decimal point and r on */
/* the right. Returns a pointer to the string in an internal buffer. */
/* Written by Morris Dovey (mrdovey@iedu.com) */
/*----------------------------------------------------------------------------*/
char *f2a(float x,unsigned char l,unsigned char r)
{ static unsigned char buffer[16];
unsigned char digits=0,*p,q=r,sign=x<0;
float fract,round;
unsigned long whole;
if (sign) x = -x;
for (round=0.5; q--; round/=10);
x += round;
whole = x;
fract = x - whole;
do ++digits; while (whole /= 10);
whole = x;
digits += sign;
if (l > digits) digits = l;
p = buffer + digits;
do *--p = whole % 10 + '0'; while (whole /= 10);
if (sign) *--p = '-';
while (p != buffer) *--p = ' ';
p = buffer + digits;
*p++ = '.';
while (r--)
{ fract *= 10;
whole = fract;
fract -= whole;
*p++ = whole + '0';
}
*p = '\0';
return buffer;
}