- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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 ?
Solved! Go to Solution.
- Labels:
-
PSoC 5 Device Programming
-
PSoC 5LP
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
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
I hope this can be a little hint for you.
moto
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
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
I hope this can be a little hint for you.
moto
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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)
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)
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