cancel
Showing results for 
Search instead for 
Did you mean: 

Code Examples

Esteemed Contributor

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) ;

002_UART_UartPutString_d.JPG

(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"

000-Use_newlib_nano_Float_Formatting.JPG

(2.2) Expand the heap

Project > Design Wide Resources > System

Heap Size (byte) 0x80 -> 0x200 (value may vary depending on your requirement)

001-Heap_0x200.JPG

003_UART_UartPutString_f.JPG

(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)

004_iprintf.JPG

(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)

004_printf.JPG

Attached are my sample programs for CY8CKIT-044.

moto

0 Likes
Reply
2 Replies
Moderator
Moderator

Hello Moto san,

Such an informative post ! Thanks for your contribution to the community.

Best Regards,
VRS

0 Likes
Reply
Esteemed Contributor

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

0 Likes
Reply
Top labels