Strange problem with "sprintf"

WizenedEE: Not directly related, but possibly useful: This will let you use printf rather than sprintf and not need to use a buffer. http://arduino.cc/forum/index.php/topic,120440.0.html

Thank you. I'll look into it. From first glance, it looks promising. Have to get into it more to be sure.

Thanks again!

-- Roger

bperrybap: What you can do is create a new AVR libc that has floating point support enabled by default. To do this you have to mess with the libc archive files.

Yes I know exactly what you mean. I may just do this.

The only problem is that if a new version of the IDE comes out, I may have to re-hack the code.

The primary thing I use the Arduino boards for is student projects. I am an engineer at the local University here and I support students (in Mechanical Engineering) who need to make senior design projects (usually "assistive devices" to help people who cannot walk or are blind, etc...).

I used to use Motorola 68HC11 "EVBU" boards, but they are larger, cost more and have fewer native I/O ports than the Atmel parts do. So, I switched over to the Arduino.

We build things like motorized lifts or wheelchairs, sonar based distance measuring for blind people, custom remote controls, radio linked devices, etc... all of which need microcontrollers to run the hardware.

If I depend on a "custom" version of the IDE and compiler code, then it will be impossible for others to replicate the projects unless they have the hacked code (we publish the projects with the National Science Foundation).

It would be embarrassing to have someone from another school call me and say "hey your damn thing doesn't work!".

That's a big reason why I need to have code work in "official" IDE releases.

Hopefully the code designers are listening! :)

-- Roger

bperrybap: What you can do is create a new AVR libc that has floating point support enabled by default.

You are the MAN!!! It worked like a champ!

By the way, the original sketch I posted above uses 6952 bytes with FP enabled and 5046 bytes without (1906 bytes more). No big deal when I have 32K on an UNO and 256K on a MEGA.

Lastly, I made your instructions into a little script to make the patch easier. It's a BASH script, but Windoze people should be able to make a BATCH file out of it easily......

EDIT: DON'T USE THIS SCRIPT - USE THE NEW ONE IN [u]POST #16[/u]

#!/bin/bash ################################################################################ # fixfp - script to install floating point support into Arduino printf library # # For more information, see this post: # http://arduino.cc/forum/index.php/topic,124809.msg938573.html#msg938573 ################################################################################

Just change to the directory where the library is (in Linux it's "arduino-1.0.1/hardware/tools/avr/lib/avr/lib/avr5") and run the script. It will patch the library.

Thanks again!

-- Roger

krupski:
It worked like a champ!

I figured it should.
I had just tried it on my own system to make sure to get all the names and paths correct.

Lastly, I made your instructions into a little script to make the patch easier. It’s a BASH script, but Windoze people should be able to make a BATCH file out of it easily…

The issue for the Windoze folks is finding the gnu bin tools
(ar in particular as it is not a native tool for windows)
They actually have all of them, including a bash shell, make, cp, echo, etc…
(they are part of the winAVR package that is shipped with the IDE).
They just don’t know where to find them much less how to use them.
The easiest thing to do (and I have done this in the past) is to write
a batch file that locates the Arduino install area then finds the tools, then
patches the PATH environment to include it, then fires up the shell executable and runs
the very same shell script.
The batch file sets up the environment so you can jump to “*nix” and leave
the DOS/Win world behind to get some real work done.

BTW, there are a few other “patches” that can be done to the AVR core library code
to make it more efficient and smaller to get back most of that code space.
For example the head/tail indexes in the ring_buffer structure in
HardwareSerial.cpp
Given the current code, those need to be unsigned chars vs unsigned ints.
The current code would break if the buffers were ever larger than 256 since the current code
does not properly deal with the atomic issues of multiple byte access (for the int).
By changing it to unsigned chars you can pick up a few hundred bytes of code space
not to mention have faster running code.

— bill

bperrybap: BTW, there are a few other "patches" that can be done to the AVR core library code to make it more efficient and smaller to get back most of that code space.

I would be VERY interested in seeing any and all patches or changes you have. Thank you!

-- Roger

bperrybap: RE: floating point patch

Bill,

I found that the sscanf function also needs to be patched!

Here is an updated script to do the entire patch:

#!/bin/bash
################################################################################
# fixfp - script to install floating point support into Arduino printf library
#
# open software - use, modify, distribute freely
#
# For more information, see this post:
# http://arduino.cc/forum/index.php/topic,124809.msg938573.html#msg938573
################################################################################

STATUS=0

## Exit if libc.a isn't here
test -e libc.a
if [ ${?} -ne 0 ]; then {
    echo "File 'libc.a' not found - exiting"
    exit 0
} fi

test -e libc.a.orig
let STATUS+=${?}

test -e vfprintf_flt.o
let STATUS+=${?}

test -e vfscanf_flt.o
let STATUS+=${?}

## Don't re-apply the patch (would ruin the backup libc.a)
if [ $STATUS -eq 0 ]; then {
    echo "Floating point patch already performed - exiting"
    exit 0
} else {
    cp libc.a libc.a.orig
    ar -dv libc.a vfprintf_std.o
    ar -dv libc.a vfscanf_std.o
    ar -xv libprintf_flt.a vfprintf_flt.o
    ar -xv libscanf_flt.a vfscanf_flt.o
    ar -rv libc.a vfprintf_flt.o
    ar -rv libc.a vfscanf_flt.o
    echo "Floating point patch installed."
} fi

(edit): If you are using a different OS and/or do not wish to patch your files, you may instead download [u]THIS[/u] package (a .ZIP file) which contains the patched versions of "libc.a". Then, locate the "libc.a" files in your Arduino distribution, rename all of them to something like "libc.a.backup" (to preserve the original), then copy the new "libc.a" files from the ZIP archive into your distribution.

Take note of the different versions for different processor directories. They must all go in the proper places! Zipfile contents:

Archive: libc_all.zip Length Name


581202 avr25/libc.a 584430 avr3/libc.a 584474 avr31/libc.a 581702 avr35/libc.a 580574 avr4/libc.a 581058 avr5/libc.a 581106 avr51/libc.a 581218 avr6/libc.a 581490 avrxmega5/libc.a 581650 avrxmega7/libc.a 583910 libc.a


6402814 11 files

You will now have full floating point support for the "sprintf" and "sscanf" functions.

NOTE that this updated library will cause your compiled sketches to be approximately 1500 bytes larger due to the floating point code. You may go back to the original library at any time simply by deleting the patched "libc.a" files and renaming your backups back to "libc.a".

Thanks to bperrybap for the original idea!

-- Roger

krupsi, I would like to use your patch on Windows, how to proceed?

What are those commands, and where to find those files?

cp libc.a libc.a.orig
ar -dv libc.a vfprintf_std.o
ar -dv libc.a vfscanf_std.o
ar -xv libprintf_flt.a vfprintf_flt.o
ar -xv libscanf_flt.a vfscanf_flt.o
ar -rv libc.a vfprintf_flt.o
ar -rv libc.a vfscanf_flt.o

Thanks

guix:
krupsi, I would like to use your patch on Windows, how to proceed?

What are those commands, and where to find those files?

cp libc.a libc.a.orig

ar -dv libc.a vfprintf_std.o
ar -dv libc.a vfscanf_std.o
ar -xv libprintf_flt.a vfprintf_flt.o
ar -xv libscanf_flt.a vfscanf_flt.o
ar -rv libc.a vfprintf_flt.o
ar -rv libc.a vfscanf_flt.o




Thanks

Sorry… I know virtually nothing about Windows. But I assume the AVR libraries are the same for any platform… I attached a ZIP file of all the floating point versions of “libc.a”. You can try them if you like… rename your originals to something like “libc_original.a” then replace them with the new ones in the ZIP file and try it. If it doesn’t work, you can just go back to the originals.

Hope this helps…

– Roger

libc_all.zip (954 KB)

Yes it does :D

Thanks a lot, it's working! Karma++;

guix: Yes it does :D

Thanks a lot, it's working! Karma++;

Awesome! Glad I could help.

-- Roger

guix: krupsi, I would like to use your patch on Windows, how to proceed?

What are those commands, and where to find those files?

cp libc.a libc.a.orig
ar -dv libc.a vfprintf_std.o
ar -dv libc.a vfscanf_std.o
ar -xv libprintf_flt.a vfprintf_flt.o
ar -xv libscanf_flt.a vfscanf_flt.o
ar -rv libc.a vfprintf_flt.o
ar -rv libc.a vfscanf_flt.o

Thanks

cp is the "copy" command in unix. It can be found in: {installdir}\hardware\tools\avr\utils\bin\cp.exe

ar is the "archive" command for creating archive files also known as libraries when using compiler tools. It can be found in: {installdir}\hardware\tools\avr\avr\bin\avr.exe

BTW, if you google: man cp man ar you can get information on these commands.

--- bill

bperrybap: BTW, if you google: man cp man ar you can get information on these commands. --- bill

I gave him a copy of the floating point versions of "libc.a" for all the AVR directories, he installed them (on a Windows based system) and they worked.

FYI, I "patched" not only sprintf, but also sscanf since both of the originals were non-floating-point versions.

The AVR libraries themselves are the same in all distributions (Linux, Windows, MacOS), so they can be dropped into any system.

I REALLY wish the IDE had config options for specifying compile, link and AVRDUDE flags instead of having them all hard coded.

I may work on the IDE to add those features and then post the code......

-- Roger

(edit): Added a karma++ for you for the original idea which worked flawlessly. Thanks!

krupski: I REALLY wish the IDE had config options for specifying compile, link and AVRDUDE flags instead of having them all hard coded.

I may work on the IDE to add those features and then post the code......

mpide and Pauls latest Teensy version of the IDE for his Teensy 3.0 support this. But they support it through boards.txt or other configuration files rather than some way from the IDE itself.

Not sure what is happening to the official toolset for DUE support. (Will it be a separate IDE or a combined like mpide or Paul's IDE? still no word on this). If it is a combined IDE, then it might be possible to play with some of the flags.

Another down and dirty way to set some flags is write some small wrapper scripts that set/modify the commmandline options and then call the real command. --- bll

bperrybap:

krupski: I REALLY wish the IDE had config options for specifying compile, link and AVRDUDE flags instead of having them all hard coded.

I may work on the IDE to add those features and then post the code......

mpide and Pauls latest Teensy version of the IDE for his Teensy 3.0 support this. But they support it through boards.txt or other configuration files rather than some way from the IDE itself.

Not sure what is happening to the official toolset for DUE support. (Will it be a separate IDE or a combined like mpide or Paul's IDE? still no word on this). If it is a combined IDE, then it might be possible to play with some of the flags.

Another down and dirty way to set some flags is write some small wrapper scripts that set/modify the commmandline options and then call the real command. --- bll

Well, my idea was to extent "preferences.txt" by adding entries to it, adding corresponding menu items to the GUI and finally support code in the Editor and Compiler classes.

Rather than cryptic options like "-Wl,-u,vfprintf -lprintf_flt -lm", the menu would, for example, say something like "[ # ] Enable floating point? (approx. 1500 bytes larger code)" and then supply the proper options based on the boolean "yes" or "no".

There would also be an "advanced" option where various configs could be added manually so that all in all there would be NO limitations on what a user could do.

It's obvious to me that the IDE was written to support "noobs" and present them limited options (i.e. limited ways to screw up their system), but advanced options SHOULD be available to those who want them.

As far as modifying the command line idea... I tried that. I renamed the AVR-GCC file, then made a little shell script to call the compiler with added command line options. It didn't work (don't know if I screwed up or if it just can't work)... but then your idea of "fixing" libc.a solved the whole problem, so the project dropped off my radar screen.

Oh well... thanks again for all your help!

(btw, you said you had other patches and ideas.. I would LOVE to know what they are).

-- Roger

Hey Folks,

To support floats in xxprintf() family functions, you can recompile the Arduino IDE with a slight change to the linker options. Suffice it to say, it's a pretty straight forward process and I've detailed it here: http://josh.to/silvia/rebuilding-the-arduino-ide-to-support-sprintf-with-floats/

I hope this helps everyone.

Cheers,

Josh.

joshblake:
Hey Folks,

To support floats in xxprintf() family functions, you can recompile the Arduino IDE with a slight change to the linker options. Suffice it to say, it’s a pretty straight forward process and I’ve detailed it here: http://josh.to/silvia/rebuilding-the-arduino-ide-to-support-sprintf-with-floats/

I hope this helps everyone.

Cheers,

Josh.

Awesome! Thanks for that. I had been looking through the “Compiler.java” code to find where to add that line, but wasn’t making any progress.

Now it works… and I also added an option to the “Preferences” to enable or disable floating point.

One good thing about the Arduino 1.5 IDE is that the compiler & linker options are no longer hard coded. You can change them by simply editing the platform.txt and boards.txt files. This allows you to set options all the way down to the specific board type if you want to, which is nice since you won't have to hard code the options to be the same for all builds.

--- bill

bperrybap: One good thing about the Arduino 1.5 IDE is that the compiler & linker options are no longer hard coded. You can change them by simply editing the platform.txt and boards.txt files. This allows you to set options all the way down to the specific board type if you want to, which is nice since you won't have to hard code the options to be the same for all builds.

--- bill

That's nice to know. Have you found the v1.5 IDE to be stable? I am afraid of beta software... especially because I use it at work to develop student project software. I can't afford to have some strange bug ruin a student's project when their grade depends on it.

Krupski: Have you found the v1.5 IDE to be stable?

No. So much software that calls itself "beta" these days is not even close to "beta". Beta used to mean feature freeze and moving toward code freeze and final release. These day's these young kids doing development don't seem to follow much of a development process and seem to call something beta as soon as they push it out of the lab. Then they continue to make feature changes. The IDE seems to be still changing features and tossing in things. Generally all good, but things are still breaking and not fully working especially when mixed environments that have AVR as well as ARM or in some cases just AVR. In their defense, they don't recommend using 1.5 on AVR. I ran into several issues that would not be easy for a novice to deal with and a few versions that would not come up at all if AVR libraries were in your sketchbook. You might want to play with it to get a feel for it, but I definitely don't think it is anywhere close to being ready as a product that can be used for student needs.

Eventually the two IDEs will merge back into one that will claim to work for multiple processors, then maybe a few months or quarters later it will be a stable product that is actually pretty nice. Not sure when that will be.

--- bill

bperrybap:
In their defense, they don’t recommend using 1.5 on AVR.
I ran into several issues that would not be easy for a novice to deal with
and a few versions that would not come up at all if AVR libraries were in your
sketchbook.
You might want to play with it to get a feel for it, but I definitely don’t think
it is anywhere close to being ready as a product that can be used for student needs.

Eventually the two IDEs will merge back into one that will claim to work
for multiple processors, then maybe a few months or quarters later it will be a stable
product that is actually pretty nice. Not sure when that will be.

— bill

Thanks for the assessment. Since my 1.0.3 IDE is up and running nicely, along with my additions (the “Upload, then Monitor” button and the “Floating point enable/disable” option), I’ll stick with it until 1.5.x becomes THE version to have.

I do like the idea of more control over the environment that 1.5 has, but for the sake of stability, I’ll stick with 1.0.3 for now.

Do you know if the AVR library code base has been updated in 1.5? ← I found the answer… the code is exactly the same… checked it with “diff” - they are all the same.