- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
Although I'm relatively new here, I've already seen a plenty of questions
about how to print a float value and/or using printf(), including myself.
For a small MCU such as PSoC 4, using a float, especially "%f" format is an expensive operation.
So not providing printf() nor "%f" for default seems to be a reasonable decision for PSoC 4.
But for those who have been grown with Unix/Linux and/or Windows absence of those seem to be critical.
This reminds me the days of my early C language study when BDS-C was the only choice 😜
Anyway, hoping that following memo can be a reference for such questions I'm writing this.
To print out a floating value with PSoC 4, I think there are (at least) 4 methods.
I'm trying to show them in order of cost, which is memory/CPU usage as well as steps
required to implement the method.
(1) Using UART_UartPutString and sprintf with only "%d"
(2) Using UART_UartPutString and sprintf with "%f"
(3) Using iprintf with only "%d"
(4) Using printf with "%f"
Following are my sample trials.
(1) Using UART_UartPutString() and "%d"
(1.1) if the f_value is always equals to 0.0 or greater
sprintf(str, "%d.%02d", (int)(f_value), ((int)(f_value * 100))%100) ;
UART_UartPutString(str) ;
(1.2) if you want to round the f_value
sprintf(str, "%d.%02d", (int)(f_value + 0.005), ((int)(f_value * 100 + 0.5))%100) ;
UART_UartPutString(str) ;
(1.3) if the value can be negative
char sign = ' ' ;
if (f_value < 0.0) {
sign = '-' ;
}
sprintf(str, "%c%d.%02d", sign, (int)(f_value + 0.005), ((int)(f_value * 100 + 0.5))%100) ;
UART_UartPutString(str) ;
(2) Using UART_UartPutString() and "%f"
In the source code you can print f_value by
sprintf(str, "%f", f_value) ;
UART_UartPutString(str) ;
But to achieve this we need following 2 steps.
(2.1) In the Project > Build Settings > Linker > General
Set "User newlib-nano Float Formatting" as "True"
(2.2) Expand the heap
Project > Design Wide Resources > System
Heap Size (byte) 0x80 -> 0x200 (value may vary depending on your requirement)
(3) Using iprintf with "%d"
In the source code you can print f_value by
iprintf("%d.%02d\r\n", (int)f_value, ((int)(f_value * 100))%100) ;
(3.1) implement _write() for your UART
int _write(int file, char *ptr, int len)
{
int i ;
file = file ;
for (i = 0; i < len ; i++ ) {
UART_UartPutChar(*ptr++) ;
}
return len ;
}
(3.2) expand heap (may be required)
(4) Using printf() with "%f"
In the source code you can print f_value by
printf("%f\r\n", f_value) ;
(4.1) implement _write() for your UART
int _write(int file, char *ptr, int len)
{
int i ;
file = file ;
for (i = 0; i < len ; i++ ) {
UART_UartPutChar(*ptr++) ;
}
return len ;
}
(4.2) In the Project > Build Settings > Linker > General
Set "User newlib-nano Float Formatting" as "True"
Please refer to (2.2)
(4.2) Expand the heap
Project > Design Wide Rerouces > System
Heap Size (byte) 0x80 -> 0x400
Please refer to (2.3)
Attached are my sample programs for CY8CKIT-044.
moto
- Labels:
-
PSoC 345 LP
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello Moto san,
Such an informative post ! Thanks for your contribution to the community.
Best Regards,
VRS
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
OOPS!
For (1.3) one line was missing.
In the attached project it was OK, though.
(1.3) if the value can be negative
char sign = ' ' ;
if (f_value < 0.0) {
sign = '-' ;
f_value = -f_value ; // <-- this line was missing!
}
moto