Go Down

Topic: How to select the printf runtime library? (Read 2082 times) previous topic - next topic

PeterH

I'm trying to print out a float number for debugging purposes, using
Code: [Select]

float foo;

(snip)

printf("%2.2f", foo);


This prints a "?" instead of the number I'm looking for. From the documentation for the AVR runtime library <stdio.h> I can see this is the expected behaviour when the default runtime libraries are used:

Quote from: www.nongnu.org
Since the full implementation of all the mentioned features becomes fairly large, three different flavours of vfprintf() can be selected using linker options. The default vfprintf() implements all the mentioned functionality except floating point conversions.

If the full functionality including the floating point conversions is required, the following options should be used:

   -Wl,-u,vfprintf -lprintf_flt -lm


This is fine, except that I'm not invoking the compiler and linker myself, the Arduino IDE is doing it for me and I don't see any way within the IDE to change the linker options. Have you got any idea of possible ways to print floating point values? I really would prefer not to roll my own formatter if I can help it.

cmiyc

Print to where?

Why not use the Arduino "Serial.print()" and "Serial.println()" instead?
Capacitor Expert By Day, Enginerd by night.  ||  Personal Blog: www.baldengineer.com  || Electronics Tutorials for Beginners:  www.addohms.com

PaulS

The %f format specifier is not supported on the Arduino. A few seconds searching would have revealed a variety of alternatives.
The art of getting good answers lies in asking good questions.

maniacbug

Quote

Arduino IDE is doing it for me and I don't see any way within the IDE to change the linker options.


Don't roll your own formatter, roll your own development environment :)  Then the linker will never get in your way again.

PeterH


The %f format specifier is not supported on the Arduino. A few seconds searching would have revealed a variety of alternatives.


I've found that empirically, but I haven't seen that documented anywhere (except in the AVR documentation I linked to, which is not Arduino-specific, and suggests that it's available as an option).

Nobody has suggested any way to access that option, so I guess we don't have access to set the AVR compiler options used by the Arduino IDE.

I'm finding out what API is available and what it does using the Reference link on the arduino.cc home page and then drilling down into individual functions and libraries from there. (That's how I came to the AVR vprinft documentation.) I'm grateful for what documentation there is there, but it seems rather sparce. Is there anywhere else I should have looked to find out exactly what is available within this API?

I'm aware that I could use the Serial.print methods, and I recall seeing a mention that IO Streams were supported. Both are, in my opinion, a very poor substitute for good old printf. I'm reluctant to mix and match between different mechanisms to perform output. Firstly because it's inelegant, but also because it's conceivable that in future I might want this type of diagnostic stuff to go somewhere other than the standard Serial port, and by using an API that accesses stdout I have a very handy mechanism to control the whole lot in one go. If there are any other solutions to print a float, I'm open to suggestions. Meantime, I kludged a wrapper round printf that formats the float for me.


stimmer

There's a function called dtostrf that might be what you need. Use it like this:
Code: [Select]
  char s[80];
  float val=12.34;
  char width=8,prec=1;
  dtostrf(val,width,prec,s);Serial.println(s);


If you really need the full printf you'll have to change the Arduino source (which isn't too difficult). Or you can use avr-ar to modify the libc.a file. Library .a files are archives and modifying them is as easy/hard as managing zip files on dos used to be.
avr-ar t libc.a should list what's in the library, avr-nm x libraryname.a objname.o extracts, avr-nm d lib.a obj.o deletes and (I think) avr-nm r lib.a obj.o adds.
Which libc.a is the right one depends on the processor; try avr5 first.
Due VGA library - http://arduino.cc/forum/index.php/topic,150517.0.html

sbr_


There's a function called dtostrf that might be what you need.


There's also the PString lib to print to a char buffer. It only supports float printing with the same options as Serial.print() (using Print formatting as well), but it's a pretty useful utility anyway for "printing" to LCDs and such. For non-floats, sprintf-like formatting can be applied.

Go Up