2 Replies Latest reply on Dec 6, 2018 9:26 PM by MoTa_728816

    printf and float rhapsody (aka, yet another printf and floating topic)

    MoTa_728816

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

       

      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