PSoC 5 LP Getting String from UART for processing

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
dhsac_4153841
Level 1
Level 1

Dear,

I am writing code for getting string command & compare it with string for result.

But i am not able to concat char & convert it into string.

Can any one suggest how to  concat char to generate input command ?

0 Likes
1 Solution
lock attach
Attachments are accessible only for community members.
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Hi,

With PSoC Creator v4.2, when we set FIFO for UART RX, UART_RXISR which is the uart rx interrupt handler managing the fifo as ring buffer will be provided, so we only need to check if UART_GetRxBufferSize() is 0 or not.

001-UART_Config.JPG

So I changed my strategy to call get_str() in my main loop and when get_str() detects a delimiter,  I handle the received data as string.

main.c (excerpt)

=======================

<snip>

int get_str(void)

{

    int result = 0 ;

    uint8_t c ;

    if (UART_GetRxBufferSize()) {

        c = UART_GetByte() ;

        result = is_delimiter(c) ;

        if (result) { /* a string delimter was detected */

            str[str_index] = 0 ;

            str_index = 0 ;

        } else { /* still in the middle of a string */

            str[str_index++] = c ;

            if (str_index >= STR_LEN) { /* string is too long */

                str[STR_LEN] = 0 ;

                str_index = 0 ;

                result = -1 ;

            }

        }   

    }

    return( result ) ;

}

<snip>

int main(void)

{

    init_hardware() ;

 

    splash() ;

    prompt() ;

    for(;;)

    {

        if (get_str()) { /* a string was recived in str[] */

            do_command(str) ;

            prompt() ;

        }

    }

}

=======================

And my sample handles the first string as command and each command takes additional strings as arguments if the command requires additional argument(s), just like

led on

sum 1 2 3

In do_command() function I check the command string against available commands

then call handler function for the particular command or call "help" if the command is not known.

==================

void do_command(char *str)

{

    str2upper(str) ;

    if (strcmp(str, "LED") == 0) {

        do_led() ;

    } else if (strcmp(str, "SUM") == 0) {

        do_sum() ;

    } else if (strcmp(str, "AVE") == 0) {

        do_ave() ;

    } else {

        help() ;

    }

}

==================

Following is the TeraTerm log

000-TeraTerm-log.JPG

I hope this can be a little hint for you.

moto

View solution in original post

0 Likes
4 Replies
odissey1
Level 9
Level 9
First comment on KBA 1000 replies posted 750 replies posted

See example project of using UART for receiving commands here:

UART string reception garbage value

It utilizes a circular buffer to receive characters from UART Rx and split them into command messages when termination characters are found (0x0D and/or 0x0A). Each received message has one "command" byte followed by "value string":

   

<cmd><value string> <\r> [<\n>], example: R255\n (set red LED to 255).

  

odissey1

0 Likes
lock attach
Attachments are accessible only for community members.
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Hi,

With PSoC Creator v4.2, when we set FIFO for UART RX, UART_RXISR which is the uart rx interrupt handler managing the fifo as ring buffer will be provided, so we only need to check if UART_GetRxBufferSize() is 0 or not.

001-UART_Config.JPG

So I changed my strategy to call get_str() in my main loop and when get_str() detects a delimiter,  I handle the received data as string.

main.c (excerpt)

=======================

<snip>

int get_str(void)

{

    int result = 0 ;

    uint8_t c ;

    if (UART_GetRxBufferSize()) {

        c = UART_GetByte() ;

        result = is_delimiter(c) ;

        if (result) { /* a string delimter was detected */

            str[str_index] = 0 ;

            str_index = 0 ;

        } else { /* still in the middle of a string */

            str[str_index++] = c ;

            if (str_index >= STR_LEN) { /* string is too long */

                str[STR_LEN] = 0 ;

                str_index = 0 ;

                result = -1 ;

            }

        }   

    }

    return( result ) ;

}

<snip>

int main(void)

{

    init_hardware() ;

 

    splash() ;

    prompt() ;

    for(;;)

    {

        if (get_str()) { /* a string was recived in str[] */

            do_command(str) ;

            prompt() ;

        }

    }

}

=======================

And my sample handles the first string as command and each command takes additional strings as arguments if the command requires additional argument(s), just like

led on

sum 1 2 3

In do_command() function I check the command string against available commands

then call handler function for the particular command or call "help" if the command is not known.

==================

void do_command(char *str)

{

    str2upper(str) ;

    if (strcmp(str, "LED") == 0) {

        do_led() ;

    } else if (strcmp(str, "SUM") == 0) {

        do_sum() ;

    } else if (strcmp(str, "AVE") == 0) {

        do_ave() ;

    } else {

        help() ;

    }

}

==================

Following is the TeraTerm log

000-TeraTerm-log.JPG

I hope this can be a little hint for you.

moto

0 Likes

I would like to point out the differences in the two examples above. In first demo, the UART is idle until the Rx interrupt is fired. At this point, code enters interrupt routine and tries to read as many bytes from the UART buffer as available into the "message" string (new bytes are continue to arrive as buffer is being read - important for high speed), until a termination character is found. At this point a flag in the main loop is raised to signal that command "message" is available for processing. The buffer is set to hardware FIFO (size=4).

In second example, the Rx buffer is software (size>4). It is being continuously polled in the main loop, one byte at a time, until a termination character is found or a "timeout" occures.

Both examples will perform similarly at low UART speed and traffic, and low CPU load by other tasks. The difference will manifest at high UART baud rate, high UART traffic and high CPU load.

/ odissey1 

lock attach
Attachments are accessible only for community members.
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Dear Odissey1-san,

Thank you very much for your mention!

On this topic there are many points to discuss and/or care.

My point was utilizing the PSoC Creator provided isr and taking care of command and arguments.

But I must admit that I was not careful about the performance nor high band width situation.

So learning from your sample and suggestion I modified my project,

(1) added check_str() for non blocking and get_str() for blocking string acquisition.

(2) added my hand made isr to transfer the data from hardware buffer to rx_buf[] in ring buffer manner.

    uart_str_test_190417A

(3) again used PSoC Creator provided isr and let check_str() to test if UART_GetRxBufferSize() is 0 or not.

    uart_str_test_190417B

Being a lazy, I prefer to use PSoC Creator provided isr, but I hope that performance of  A and B are not very different.

TeraTerm Log of uart_str_test_190417A (own isr)

002-TeraTerm-logA.JPG

main.c of uart_str_test_190417A (own isr) 204 lines

====================

#include "project.h"

#include "stdio.h"

#include "string.h"

#define STR_LEN 32

#define RX_BUF_LEN 128

#define SPACE ' '

#define TAB '\t'

#define CR  '\r'

#define LF  '\n'

inline int is_delimiter(uint8_t c)

{

    int result = 0 ;

    switch(c) {

    case CR:

    case LF:

    case TAB:

    case SPACE:

        result = c ;

        break ;

    }

    return( result ) ;

}

volatile char          rx_buf[RX_BUF_LEN] ;

volatile int           rx_write_index = 0 ;

int           rx_read_index = 0 ;

char          str[STR_LEN+1] ; /* print buffer */

int           str_index = 0 ;

int           str_ready = 0 ;

CY_ISR(rx_isr)

{   

    int_rx_ClearPending() ;

    while(UART_GetRxBufferSize()) {

        rx_buf[rx_write_index] = UART_GetByte() ;

        rx_write_index = (rx_write_index + 1) % RX_BUF_LEN ;

    }

}

void print(char *str)

{

    UART_PutString(str) ;

}

void help(void)

{

    print("============== usage ===============\n") ;

    print("led {on | off}  : turn LED on or off\n") ;

    print("sum [ numbers ] : print sum of entered numbers\n") ;

    print("ave [ numbers ] : print average of entered numbers\n") ;

    print("help            : print this\n") ;

    print("=====================================\n") ;

}

void init_hardware(void)

{

    CyGlobalIntEnable; /* Enable global interrupts. */

   

    LED_Write(0) ;

       

    int_rx_ClearPending() ;

    int_rx_StartEx(rx_isr) ;

    UART_Start() ;

}

void splash(void)

{

    char str[64] ;

    sprintf(str, "PSoC 5LP UART Command Test (%s %s)\n", __DATE__, __TIME__) ;

    print(str) ;

}

void prompt(void)

{

    print("> ") ;

}

int check_str(void)

{

    int result = 0 ;

    uint8_t c ;

    while((result == 0) && (rx_read_index != rx_write_index)) {

        c = rx_buf[rx_read_index] ;

        rx_read_index = (rx_read_index + 1) % RX_BUF_LEN ;

        result = is_delimiter(c) ;

        if (result) { /* a string delimter was detected */

            str[str_index] = 0 ;

            str_index = 0 ;

        } else { /* still in the middle of a string */

            str[str_index++] = c ;

            if (str_index >= STR_LEN) { /* string is too long */

                str[STR_LEN] = 0 ;

                str_index = 0 ;

                result = -1 ;

            }

        }     

    }

    return( result ) ;

}

int get_str(void)

{

    int result = 0 ;

    while(result == 0) {

        result = check_str() ;

    }

    return( result ) ;

}

void str2upper(char *str)

{

    while(str && *str) {

        if (('a' <= *str) && (*str <= 'z')) {

            *str -= ('a' - 'A') ;

        }

        str++ ;

    }

}

void do_led(void)

{

    while(get_str() == 0) ;

    str2upper(str) ;

    if (strcmp(str, "ON") == 0) {

        LED_Write(1) ;

        print("LED is ON\n") ;

    } else {

        LED_Write(0) ;

        print("LED is OFF\n") ;

    }

}

void do_sum(void)

{

    uint8_t delimiter = 0 ;

    int sum = 0 ;

    int num ;

   

    while((delimiter != CR) && (delimiter != LF)) {

        delimiter = get_str() ;

        if (delimiter) {

            sscanf(str, "%d", &num) ;

            sum += num ;

        }

    }

    sprintf(str, "sum = %d\n", sum) ;

    print(str) ;

}

void do_ave(void)

{

    uint8_t delimiter = 0 ;

    int sum = 0 ;

    int count = 0 ;

    int num ;

   

    while((delimiter != CR) && (delimiter != LF)) {

        delimiter = get_str() ;

        if (delimiter) {

            sscanf(str, "%d", &num) ;

            sum += num ;

            count++ ;

        }

    }

    if (count == 0) {

        sprintf(str, "ave = 0\n") ;

    } else {

        sprintf(str, "ave = %d\n", sum/count) ;

    }

    print(str) ;   

}

void do_command(char *str)

{

    str2upper(str) ;

    if (strcmp(str, "LED") == 0) {

        do_led() ;

    } else if (strcmp(str, "SUM") == 0) {

        do_sum() ;

    } else if (strcmp(str, "AVE") == 0) {

        do_ave() ;

    } else {

        help() ;

    }

}

int main(void)

{

    init_hardware() ;

   

    splash() ;

    prompt() ;

    for(;;)

    {

        if (check_str()) { /* a string was recived in str[] */

            do_command(str) ;

            prompt() ;

        }

    }

}

====================

TeraTerm log of uart_str_test_190417B (PSoC Creator porvided isr)

003-TeraTerm-logB.JPG

main.c of uart_str_test_190417B (PSoC Creator porvided isr) 189 lines

====================

#include "project.h"

#include "stdio.h"

#include "string.h"

#define STR_LEN 32

#define RX_BUF_LEN 128

#define SPACE ' '

#define TAB '\t'

#define CR  '\r'

#define LF  '\n'

inline int is_delimiter(uint8_t c)

{

    int result = 0 ;

    switch(c) {

    case CR:

    case LF:

    case TAB:

    case SPACE:

        result = c ;

        break ;

    }

    return( result ) ;

}

char          str[STR_LEN+1] ; /* print buffer */

int           str_index = 0 ;

int           str_ready = 0 ;

void print(char *str)

{

    UART_PutString(str) ;

}

void help(void)

{

    print("============== usage ===============\n") ;

    print("led {on | off}  : turn LED on or off\n") ;

    print("sum [ numbers ] : print sum of entered numbers\n") ;

    print("ave [ numbers ] : print average of entered numbers\n") ;

    print("help            : print this\n") ;

    print("=====================================\n") ;

}

void init_hardware(void)

{

    CyGlobalIntEnable; /* Enable global interrupts. */

   

    LED_Write(0) ;

       

    UART_Start() ;

}

void splash(void)

{

    char str[64] ;

    sprintf(str, "PSoC 5LP UART Command Test (%s %s)\n", __DATE__, __TIME__) ;

    print(str) ;

}

void prompt(void)

{

    print("> ") ;

}

int check_str(void)

{

    int result = 0 ;

    uint8_t c ;

    while((result == 0) && (UART_GetRxBufferSize())) {

        c = UART_GetByte() ;

        result = is_delimiter(c) ;

        if (result) { /* a string delimter was detected */

            str[str_index] = 0 ;

            str_index = 0 ;

        } else { /* still in the middle of a string */

            str[str_index++] = c ;

            if (str_index >= STR_LEN) { /* string is too long */

                str[STR_LEN] = 0 ;

                str_index = 0 ;

                result = -1 ;

            }

        }     

    }

    return( result ) ;

}

int get_str(void)

{

    int result = 0 ;

    while(result == 0) {

        result = check_str() ;

    }

    return( result ) ;

}

void str2upper(char *str)

{

    while(str && *str) {

        if (('a' <= *str) && (*str <= 'z')) {

            *str -= ('a' - 'A') ;

        }

        str++ ;

    }

}

void do_led(void)

{

    while(get_str() == 0) ;

    str2upper(str) ;

    if (strcmp(str, "ON") == 0) {

        LED_Write(1) ;

        print("LED is ON\n") ;

    } else {

        LED_Write(0) ;

        print("LED is OFF\n") ;

    }

}

void do_sum(void)

{

    uint8_t delimiter = 0 ;

    int sum = 0 ;

    int num ;

   

    while((delimiter != CR) && (delimiter != LF)) {

        delimiter = get_str() ;

        if (delimiter) {

            sscanf(str, "%d", &num) ;

            sum += num ;

        }

    }

    sprintf(str, "sum = %d\n", sum) ;

    print(str) ;

}

void do_ave(void)

{

    uint8_t delimiter = 0 ;

    int sum = 0 ;

    int count = 0 ;

    int num ;

   

    while((delimiter != CR) && (delimiter != LF)) {

        delimiter = get_str() ;

        if (delimiter) {

            sscanf(str, "%d", &num) ;

            sum += num ;

            count++ ;

        }

    }

    if (count == 0) {

        sprintf(str, "ave = 0\n") ;

    } else {

        sprintf(str, "ave = %d\n", sum/count) ;

    }

    print(str) ;   

}

void do_command(char *str)

{

    str2upper(str) ;

    if (strcmp(str, "LED") == 0) {

        do_led() ;

    } else if (strcmp(str, "SUM") == 0) {

        do_sum() ;

    } else if (strcmp(str, "AVE") == 0) {

        do_ave() ;

    } else {

        help() ;

    }

}

int main(void)

{

    init_hardware() ;

   

    splash() ;

    prompt() ;

    for(;;)

    {

        if (check_str()) { /* a string was recived in str[] */

            do_command(str) ;

            prompt() ;

        }

    }

}

====================

Anyway, there is a lot to learn, and that's fun 😉

Best Regards,

17-Apr-2019

Motoo Tanaka

0 Likes