UART Input String Parsing

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

cross mob
lock attach
Attachments are accessible only for community members.
Anonymous
Not applicable

I want to be able to interupt my main code when data is recieved via UART. The recieved data string will contain ASCII parameters and parameter values that will need to be parsed and saved into a structure. For example: "rate,10000,gain,4" would be saved as data.rate=10000 and data.gain=4. The incoming string will be less than 256 bytes.

   

I was able to setup an ISR to set a flag and interupt the main code using the "RX - On Byte Received" interupt on the UART. I however don't know how to handle the incoming string. Can someone help me with getting the data from UART to a structure?

   
0 Likes
1 Solution
Anonymous
Not applicable

Hi jram,

   

 

   

This project can be implemented in the following manner:

   

1) Declare a structure with the elements whose values will be received via UART.

   

2) The UART Rx interrupt must be used to get the ASCII characters. There should be two arrays, one to store the element name like "rate", "gain" etc and another to store the corresponding numerical values in ASCII such as "10000", "4", etc

   

3) If the ASCII character received is not a numerical number (between 0x30 and 0x39), then store it in the NAME array. If the received ASCII character represents a number, that is, between 0x30 and 0x39, then store it in the NUMBER array.

   

4) Once a pair of NAME and NUMBER array is received, then the number received is mapped to the element of the structure to which it belongs.

   

For this two operations is to be done in the main. The NAME array should be checked if it is equal to "rate" or "gain". When one of them matches, the corresponding number should be assigned to the element of the structure.

   

The received numerals in ASCII format should be converted to a number. Example, "10000" will be stored as {0x31, 0x30, 0x30, 0x30, 0x30}. A function should be written to convert it to hexadecimal format. This number should be assigned to the element of the structure, like example.rate = 10000, example.gain = 4.

   

 

   

How many elements are there in the structure? And what is the baud rate of the UART used?

   

All the conversion and assignment operations should be done in the main before the next pair of data is received.

View solution in original post

0 Likes
13 Replies
Anonymous
Not applicable

Hi jram,

   

 

   

This project can be implemented in the following manner:

   

1) Declare a structure with the elements whose values will be received via UART.

   

2) The UART Rx interrupt must be used to get the ASCII characters. There should be two arrays, one to store the element name like "rate", "gain" etc and another to store the corresponding numerical values in ASCII such as "10000", "4", etc

   

3) If the ASCII character received is not a numerical number (between 0x30 and 0x39), then store it in the NAME array. If the received ASCII character represents a number, that is, between 0x30 and 0x39, then store it in the NUMBER array.

   

4) Once a pair of NAME and NUMBER array is received, then the number received is mapped to the element of the structure to which it belongs.

   

For this two operations is to be done in the main. The NAME array should be checked if it is equal to "rate" or "gain". When one of them matches, the corresponding number should be assigned to the element of the structure.

   

The received numerals in ASCII format should be converted to a number. Example, "10000" will be stored as {0x31, 0x30, 0x30, 0x30, 0x30}. A function should be written to convert it to hexadecimal format. This number should be assigned to the element of the structure, like example.rate = 10000, example.gain = 4.

   

 

   

How many elements are there in the structure? And what is the baud rate of the UART used?

   

All the conversion and assignment operations should be done in the main before the next pair of data is received.

0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

Problems like yours are traditionally solved with a program named "Parser". It reads an input-stream and divides ti into "Tokens". To do that there must be a (or more) "Delimiter" between the tokens for instance a comma, Cr, and so on.

   

Data received from UART are put into a buffer until a delimiter is found and it is signaled (setting a flag) that a token has arrived.

   

The controlling program reads and acts upon the token and resets the flag (good to double-buffer tokens so that they do not get overwritten)

   

The controlling program in your case sounds like a simple state-machine (waiting for name, process name, waiting for Value, process value,...)

   

This approach gives the most flexibiliy and can easily be re-used in other programs with similar problems, so it is worth the effort to implement it.

   

Bob

0 Likes
Anonymous
Not applicable

 If your message is of fixed format ie, the first 5 byte is rate, the next is 1 byte of gain. Then you don't need to send the 'rate' and 'gain' string. You just read the value and convert it to a long of a byte and copy it to you structure. Unless your incomming message can be of any order.

0 Likes
Anonymous
Not applicable

My biggest concern is how do I handle the incoming data stream? I understand that I need to parse the string and put it into a structure. If this was simply a C-code program I could figure it out, but the UART is causing my primary confusion. How do I properly get the data from UART into a string? I also know how to read bytes/char from the UART, but I am uncertain how to setup the memory array and transfer the data from UART to the memory. Should the memory be in Flash or SRAM, etc?

0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

Oh, that's easy! I would suggest to put the incoming data into SRAM, preferrably into an array of chars

   

char CharBuffer[20];

   

uint8 ii = 0;

   

if(UART_ReadRxStatus() & UART_RX_STS_FIFO_NOTEMPTY) CharBuffer[ii++] = UART_ReadRxData();

   

 

   

Have a look at the APIs in the datasheet.

   

Flash-memory is something that must be "programmed" and it will keep its contents even when the power to the chip is turned off.

   

If you are getting a bit more experienced I would suggest you to write a "Circular Buffer" and feed it interrupt driven with the incoming UART-Data.

   

 

   

Happy coding

   

Bob

0 Likes
ShVy_264716
Level 4
Level 4
50 replies posted 25 replies posted 10 replies posted

Bob, can you please elaborate how I can create a circular buffer and feed it interrupt driven with the incoming UART data?

   

Thanks in advance.

   

Regards

   

Shaunak

0 Likes
ShVy_264716
Level 4
Level 4
50 replies posted 25 replies posted 10 replies posted

Can anyone please elaborate with some example how I can create a circular buffer and feed it interrupt driven with the incoming UART data?

   

Thanks in advance.

   

Regards

   

Shaunak

0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

For a circular buffer you need

   

A buffer, preferrably an array of chars or uint8s

   

A writepoiner that points into the buffer to the place where the next character received will be stored

   

A readpointer that points into the buffer to the place where the current character will be red from.

   

You may maintain a count of characters that reflects the actual count of characters in the buffer

   

 

   

In your interrupt handler you just write

   

*writepoiner++ = received character;

   

if(writepointer > end of buffer) writepointer = begin of buffer;

   

charactercount++;

   

 

   

to read a character works similar.

   

Additionally you may define some more functions as

   

boolean IsBufferEmpty(void) which compares for the character count.

   

You may write a read function that checks for an empty buffer and waits until a character has been saved (blocking)

   

 

   

Happy coding

   

Bob

0 Likes
lock attach
Attachments are accessible only for community members.
odissey1
Level 9
Level 9
First comment on KBA 1000 replies posted 750 replies posted

@jram,

   

To summarize all ideas from <Bob Marlowe> I am attaching an example project of UART Rx with parsing. You may need to adjust UART speed, circular buffer length, command string length and buffer structure (if command identifier is longer than 1 byte). Finally, it is better to send short commands, separated by terminator, instead of complex statement, e.g:

   

send this:

   

'R128\r'

   

'G255\r'

   

'B0\r'

   

 

   

not this:

   

'R128 G255 B0\r'

   

 

   

regards,

   

odissey1

0 Likes
ETRO_SSN583
Level 9
Level 9
250 likes received 100 sign-ins 5 likes given

In your interrupt handler you just write

   

*writepoiner++ = received character;

   

if(writepointer > end of buffer) writepointer = begin of buffer;

   

charactercount++;

   

 

   

Should the charactercount++ and received char be conditional on receipt of a legit char (not NULL)

   

and ptr not at end of buffer ?

   

 

   

writepointer++;

   

tempchar = received character;

   

if( ( writepointer <= end of buffer ) && ( tempchar != NULL ) ) {

   

     *writetpointer = tempchar;

   

     charactercount++;

   

} else {

   

     writepointer = begin of buffer;

   

}

   

 

   

Regards, Dana.

0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

I assumed a NULL character to be legal, but in case you are transmitting ASCIIs you can mask out NULL or even non-printables.

   

ptr not at end of buffer ?

   

I was a bit tricky with defining my prerequisites, I wrote "A writepoiner that points into the buffer to the place where the next character received will be stored"

   

So at entry of the handler writepointer is already correct and when leaving the handler it is valid again.

   

 

   

Bob

0 Likes
Anonymous
Not applicable

Hi Clever people,

   

Is there any way to make UART Parser on UART (SCB mode) component. I have tried project posted by Odissey1 and it works fine. But UART(v2.50) occupies 24 Marcocells and I can't use it as I have only 22 left after all other components takes they functions. Right now I am using Cy8CKIT-049-4200, based on CY8C4245AXI-483 and I know that I can chose another processor (like CY8C4247AZI-L423)) and looks like it builds my project without any problem, but it's bit complicated to order it as well as to test (I need to make PCB for that and so on). My general task is to be able to understand commands I get thru UART and manipulate with values. I am expecting commands in format like M1(123), N2(9999), but I will also get some free format text, which one I should just ignore (UART is connected to ESP8266, running nodemcu and at startup it just prints to UART some text). 

   

Thank you in advance for any comment or reference,

   

Aidas

0 Likes
odissey1
Level 9
Level 9
First comment on KBA 1000 replies posted 750 replies posted
        PSoC 4200 example for Fixed Function UART can be found in post #35 http://www.cypress.com/comment/389231#comment-389231   
0 Likes