Float and sprintf, Atollic TrueStudio, STM32F407 - Page 1
Forum section: electronics / general

author: Dawid
author_rank: Contributor
timestamp: March 18, 2017, 05:10:10 pm
content: Hi,I try to send readings from ADC via UART. I recalculate value to a voltage and save to float type variable and then I'm trying to transform that variable to an char array. To do that I use sprintf:Code:sprintf(buffer, "%f", fADCreading);SendStringToPC(buffer);but it gives me... nothing in my terminal. It sends integers but not float.I tried different ways and I cannot find any solution.Any ideas? I didn't find anybody with similar problem.

author: nctnico
author_rank: Super Contributor
timestamp: March 18, 2017, 05:27:21 pm
content: The printf library you are using may not have floating point support. Look that up in the manual. Also use snprintf so the buffer cannot overflow if you declare it too small: snprintf(buffer, sizeof(buffer), ...

author: Dawid
author_rank: Contributor
timestamp: March 18, 2017, 10:41:57 pm
content: Ok, apparently it does work in my IDE. I worked that out splitting integer part and fraction manually. Thank you.

author: Jeroen3
author_rank: Super Contributor
timestamp: March 18, 2017, 11:04:53 pm
content: You could use thechprintffrom ChibiOS. It's easy to modify the code for your needs.But the conversion to fixed point should work too.

author: obiwanjacobi
author_rank: Super Contributor
timestamp: March 19, 2017, 06:31:28 am
content: I can't remember exactly but wasn't there a flag/setting to enable floating point related functions?It will take up more flash of course - that's why it's off by default.

author: FreddyVictor
author_rank: Regular Contributor
timestamp: March 19, 2017, 08:00:58 am
content: alternatively try something like (not tested!):sprintf(buffer, "%d.%.1d", (int16_t) fADCreading,(int8_t) ((fADCreading-(int16_t)fADCreading)*10.0)); // gives 1 decimal placebut on a '407, you're not really lacking in space !

author: Dawid
author_rank: Contributor
timestamp: March 19, 2017, 10:41:14 am
content: Nope, I get something like this: 1dI have done something like this (2 decimal places):Code:int int_buff;uint fraction_buff;int_buff = (int)(t_ADCMachineStruct.ADC_ReadingConverted[t_ADCMachineStruct.Cnt]);fraction_buff = (uint)(((t_ADCMachineStruct.ADC_ReadingConverted[t_ADCMachineStruct.Cnt])-((uint)t_ADCMachineStruct.ADC_ReadingConverted[t_ADCMachineStruct.Cnt]))*100);sprintf(buffer, "\n\nADC fraction: %d.", int_buff); //convert integer part to stringSendStringToPC(buffer); //send integer part via serialsprintf(buffer, "%d", fraction_buff); //convert fractional part to stringposition = strlen(buffer); //check how long the fractional part isstrncpy(buffer_2,"0000", 1-(position-1)); //add zeros if the fractional part is like 0.01 (if not 1.01 will be 1.1)strcat(buffer_2, buffer); //glue possible zeros with the fractional partSendStringToPC(buffer_2);send fractional part via serialWHat do you think?

author: ealex
author_rank: Frequent Contributor
timestamp: March 19, 2017, 12:56:20 pm
content: usually floating point printf / scanf is disabled from the make-file / compiler options.depending on your environment you can try adding "LDFLAGS += -u _printf_float -u _scanf_float" in the linker optionslook on the support pages for your IDE / toolchain - there should be some options for that.for example, from cypress :http://www.cypress.com/knowledge-base-article/floating-point-support-printf-and-scanf-gnu-arm-compiler-kba89724

author: FreddyVictor
author_rank: Regular Contributor
timestamp: March 19, 2017, 06:38:22 pm
content: Quote from: Dawid on March 19, 2017, 10:41:14 amseems overly complex !the "%.1d" in my code forces sprintf to automatically pad with 1 zeroI just tried the code I posted & it appears to work ok on a STM32F401 using EmBitz (ARM GCC compiler)really not sure why Atollic isn't working correctlyanyway, to do 2 decimal placesshouldbe:Code:sprintf(buffer, "%d.%.2d", (int16_t) fADCreading,(int8_t) ((fADCreading-(int16_t)fADCreading)*100.0)); // gives 2 decimal places

author: Dawid
author_rank: Contributor
timestamp: March 19, 2017, 11:47:43 pm
content: ealex:Could you please give me a hint which are the linker options I should go? I tried all possible field and using your command I get the error:"arm-atollic-eabi-gcc: error: LDFLAGS: No such file or directoryarm-atollic-eabi-gcc: error: +=: No such file or directory"If I use just "-u _printf_float -u _scanf_float" nothing happens...FreddyVictor:yes, I know it is too complex but I didn't find better way to do that. It works somehow for now but I would like to improve it in the future.

author: capt bullshot
author_rank: Super Contributor
timestamp: March 20, 2017, 02:54:38 pm
content: Atollic is based on gcc. So there somewhere should be an option to select between different C standard libs (like -specs=nosys.specs or -specs=tiny.specs) to tell the linker which library to be used. For example tiny.specs wouldn't print floats, nosys.specs does.From here on, you are on your own, since all of the IDEs wrapped around the gcc tools hide these options somewhere in the project configuration dialogs using no common naming style. I do not know which place Atollic chose.

author: Dawid
author_rank: Contributor
timestamp: March 20, 2017, 10:50:29 pm
content: I think I got it. When creating a new project option like 'use tiny_printf' has to be unticked... And now my code is twice bigger but formatting also works.I think I have to start study Eclipse. Any hints where to start, some manuals? I really want to learn that.EDIT: actually I found that if I remove the tiny_printf.c file from my project it also helps, so even created with that option ticked I can undo that.