Floating Point Reading: Temperature Over USBUART

If you have been following the posts from the beginning, your application can print messages to the USB connected serial port, and get typed characters from the keyboard. See the previous post, PSoC USB UART: A Debugging Tool, here https://socmaker.com/?p=168. (Note I updated it as I found another issue.)

Header File Collection Bin

In my projects, I am often adding header files as I create new modules. Keeping track of what to add where becomes an issue at times. Since I am inherently lazy, my shortcut is to create a “main.h” file and put all my header files in it.

This slows the compile process. However, with a small program that is written for PSOC’s, you usually won’t notice it. Here is my main.h now:

#ifndef _MAIN_H_
    #define _MAIN_H_
/* ========================================
 * Copyright Wade Maxfield, 2020
 * All Rights Reserved
 * LICENSED SOFTWARE.
 *  Under the GPL v3 license
 * This license does not override previous licenses
 * Some information may be Proprietary to 
 * Cypress (http://www.cypress.com) for their
 * PSoC 5LP®--Cypress Semiconductor and
 * only usable on their devices.
 * PROPERTY OF Wade Maxfield.
 * Commercial license available
 * ========================================
*/  
#include <project.h>
#include "parseCommands.h"
#include "USBSerial.h"
#include "ds18b20.h"

#endif

In all of my “c” files, I now have one line:

#include "main.h"

Get Ready To Print!

In order to print out the temperature as a real number, we need to use floating point. In C, printf() and sprintf() are used to do floating point. (there are tutorials for sprintf and printf, google “sprintf tutorial.”)

These two library functions require a lot of workspace (called “heap”) and stack space (where return from function address information is kept). The stack space is needed because a lot of recursive (google it) function calls are made when parsing the command string.

Unfortunately, the default settings of the PSOC Creator do not support floating point. Even so, it is very easy to set up.

Build Settings

Open your project in PSOC Creator, go to the Project menu, and near the bottom is “Build Settings…” Choose that, and a dialog appears. Open the “ARM GCC” by clicking on the “+” and open Linker by clicking on the “+” and the click on General. In the list on the right, near the bottom is “use newlib-nano Float Formatting.” Click on the False to make it True. Click OK.

It should look something like this:

This change is enough to compile and attempt to run with an sprintf() statement included in your code. However, it will act peculiarly, and crash at odd times. That is because you don’t have enough room allocated for the resources used by sprintf. To handle this, you must modify system wide settings.

Heap and Stack

To use floating point, we have to increase the amount of heap and stack space available to our program. Click on the “+” by Design Wide Resources, and when it drops down, locate “System” and double click on it. On the next screen, near the middle, you will find the selections for heap and stack. I have shrunk the window to show it here:

Change the Heap Size setting by clicking in the yellow part under the “Value” heading. Make it 0x7ff. This value (around 2,000 bytes) is enough for a lot of code. Change Stack Size to 0x1000. This value is around 4,000 bytes, also enough for most programs. If you are using the PSOC 5 CY8CKIT-059, you have 64,000 bytes of ram, so you have plenty of space still left.

Adding Code to do the Print

Add in a command letter for printing the Temperature in the parseCommands.c file. I used the letter “T”. Here is my code. Note two things: 1) #include “main.h”, and 2) in the case ‘t’: I added case ‘T’: (That way, I don’t worry about the caps lock setting), and 3) The curly bracket { after the case and before the break }break; (the bracket allows me to define variables and externs without complaints from the compiler.) See following:

/* ========================================
 * Copyright Wade Maxfield, 2020
 * All Rights Reserved
 * LICENSED SOFTWARE.
 *  Under the GPL v3 license
 * This license does not override previous licenses
 * Some information may be Proprietary to 
 * Cypress (http://www.cypress.com) for their
 * PSoC 5LP®--Cypress Semiconductor and
 * only usable on their devices.
 * PROPERTY OF Wade Maxfield.
 * Commercial license available
 * ========================================
*/
#include "main.h"

char outMsg[64];
char commandBuffer[64];
int16_t commandBufferIndex;

int16_t debugPrint;

//-------------------------------------------
//-------------------------------------------
void init_parse() {
    uint16_t c=1;
    parse((char *)"v",&c);// show sign on message
}
//-------------------------------------------
//-------------------------------------------
void parse(char *RXBuffer, uint16_t *rxCountp) {
    int16_t rxCount = *rxCountp;
    static int16_t bufferIndex;    
    *rxCountp=0;// reset indicating we consumed buffer
    char c;
     
    for (bufferIndex =0 ; bufferIndex < rxCount; bufferIndex++) {
        c=commandBuffer[commandBufferIndex++]=RXBuffer[bufferIndex];
        printChar(c);
        if (c != '\r')
            continue;
        
        printChar('\n');
        commandBufferIndex=0;
        // we have received data from usb.  look at it and determine what to do
        switch(commandBuffer[0]) {
            case 0:
            case '\n':
            case '\r':
            default:                               
            case 'v':
            case 'V':
            printSignon:
                printMessage("\n\n\r--------\n\r");
                printMessage("commands: (press enter after command to execute)\n\r---------\n\r");
                printMessage(" D      -- Toggle Debug Print\n\r");
                printMessage(" T      -- Print Current Temperature\n\r");
                printMessage(" V      -- Version / help\n\r");
                printMessage("--\n\renter command>");
                
                return;
            
            
            case 'd': case 'D':
                debugPrint=!debugPrint;
                printMessage("Debug print now ");
                if (debugPrint)
                    printMessage("on\n\r");
                else
                    printMessage("off\n\r");
                    
                    goto printSignon;
            break;
                    
            case 't': case 'T':{
                extern float temperature;
                sprintf(outMsg,"\n\rTemperature=%f\n\r",temperature);
                printMessage(outMsg);
                goto printSignon;
            }break;                   
            }//switch(commandBuffer
    }//for()
    return;   
}
/* [] END OF FILE */

One More Thing!

You may have tried to compile and had it fail. The reason is there is a header file include which is missing. Add <stdio.h> to main.h:

#ifndef _MAIN_H_
    #define _MAIN_H_
/* ========================================
 * Copyright Wade Maxfield, 2020
 * All Rights Reserved
 * LICENSED SOFTWARE.
 *  Under the GPL v3 license
 * This license does not override previous licenses
 * Some information may be Proprietary to 
 * Cypress (http://www.cypress.com) for their
 * PSoC 5LP®--Cypress Semiconductor and
 * only usable on their devices.
 * PROPERTY OF Wade Maxfield.
 * Commercial license available
 * ========================================
*/  
#include <project.h>
#include <stdio.h>
#include "parseCommands.h"
#include "USBSerial.h"
#include "ds18b20.h"

#endif

Compile and Run

If you have done everything without error (never the case for me the first few times), you can run your program on the PSOC and plug in the USBUART on the end of the CY8CKIT-059.

Open in your terminal application at 115,200 baud (see previous posts, I use ‘screen’), and press enter. You should see the following:

--------
commands: (press enter after command to execute)
---------
 D      -- Toggle Debug Print
 T      -- Print Current Temperature
 V      -- Version / help
--
enter command>

Press T and then enter:

--------
commands: (press enter after command to execute)
---------
 D      -- Toggle Debug Print
 T      -- Print Current Temperature
 V      -- Version / help
--
enter command>t

Temperature=71.048752


--------
commands: (press enter after command to execute)
---------
 D      -- Toggle Debug Print
 T      -- Print Current Temperature
 V      -- Version / help
--
enter command>

Notice the temperature is printed out to a ridiculous number of digits. That is fine, and will be useful in the future.

Next Time

If everything works out, next time we will look at adding a millisecond timer and blinking an LED. This timer will be useful in the future.

Enjoy!

Add a Comment

Your email address will not be published. Required fields are marked *