westfw:
There's some discussion here: How to safely and reasonably convert a float or double to string or char array? - #31 by krupski - Programming Questions - Arduino Forum
Krupski has modified the IDE to include new options (which requires the ability to edit and compile the IDE sourcecode), and/or suggests that you simply overwrite the vprintf library with a copy of vprintf_flt instead (which is sort of heavy-handed - it'll affect many avrs at the same time.)
My "heavy handed" method was meant to allow a person to do a "quick and dirty" test to see how the floating point code actually performed and was not meant as "the solution" to the problem.
For the newer IDE, all that's required is to edit one of the "recipe" files to use the float versions of the printf library.
Also note that there are TWO files involved... one that supports printf and one that supports scanf.
Almost nobody (as far as I know) needs or uses scanf, so if ONLY the printf float code is linked, you get all the printf functionality with only about 1.5K of extra load.
Getting back to editing the recipe file, that does work, but (at least as far as I'm concerned), there should be a quick and easy user preference checkbox to enable or disable the float code as desired.
When I'm working on a sketch and don't need float, all I do is "click it off" and I get my 1.5K back. If I need it, click it on. To have to edit a file each time I wanted to make the switch is (again IMHO) absurd.
This is my Preferences window (growing all the time! (click for full size):

Concerning printf itself, using fdevopen is simple, but tricky. To get the results desired (for example, separate stdout and stderr), the fdevopen calls need to be made in the correct order. Also, to prevent memory leaks, streams and file pointers need to be both closed and NULL'd... again in the proper order.
I've written a tiny library which does this. It provides a pre-instantiated object (STDIO) and supports .open, .close and a few other useful but not often used functions. The pre-instantiated is OK because of course you need only one (and indeed can't use more than one!).
In fact, the nicest way to use it is to add the two files (.h and .cpp) to the main Arduino directory (that has wiring*, hardwareserial*, etc..) and then just #include it in Arduino.h.
Then it's always available and uses ZERO memory if it's not used. I even have it pre-load into Hardwareserial so that serial prints automatically work. All that's required is this:
// in .begin (at the very end of the function)
STDIO.open (*this); // connect stdin/out/err to current serial stream
// in .end (at the very end of the function)
STDIO.close(); // close standard streams
Using "*this" automatically connects it to the proper serial port. If you use "Serial3.begin", then printf is automatically connected to port #3.
To make it REALLY perfect, a slightly edited Print.cpp and Print.h needs to be used. This library does a few things such as PROPERLY handling the "\n" character so that you don't have to use "\r\n" every time. It also provides print_P (for progmem strings), print_E (for EEPROM strings) and properly handles and prints uint64_t and int64_t numbers and doesn't use a fixed buffer to do so.
The "printfloat" code is 100% backward compatible with the original, but it also supports an optional parameter to allow specifying the number string length (like printf does - enabling lining up the number columns properly).
The handling of "\r\n" is done in the (char) section of print - others such as the bare write() are not affected.
The printing from PROGMEM has been improved to handle printing strings that happen to lie past the 64K boundary (whereas before Arduino would just crash):
size_t Print::print_P (const void *str)
{
size_t n = 0;
char c;
#if defined (pgm_read_byte_far)
while ((c = pgm_read_byte_far (str + n))) {
#else
while ((c = pgm_read_byte_near (str + n))) {
#endif
print ((char) c);
n++;
}
return n;
}
Simple change, but it works.
It's kinda discouraging when these simple solutions are available, yet virtually every day I read some of the "knowledgeable" Arduino users telling n00bs "it can't be done" or "it takes gigabytes of extra flash".
Oh well, as they say "you can lead a horse to water - but you can't make him drink".
