Parsing a text-string from serial and decide what to do ?

Hello!

I have looked all over the forum, but i didn't really find what i was looking for.

I need to parse a text string recieved on the serial port, and from the contents, decide what to do with it.

I send a text string on the serial port like Start1135(Cr,Lf)

Some part of the program sees the "Start" word and jumps to a sub function, where the rest of the string is examined, if it contains 4 digits (e.g. 1135) it sets these numbers into two bytes (byte1 = 11) and (byte2 = 35)

How do i write code that parses this ? It should support various messages, and not be case-sensitive...

Checking for various commands recieved (e.g. Start, Status, On, Off) etc. - do i test the messages as a single string against a list, or a single character at a time ?

Any ideas to get me further ?

// Per.

I send a text string on the serial port like

Why don’t you make the parsing easier, by delimiting the text being sent?

Start,11,35,,
would be a lot easier to parse.

PaulS:
Why don’t you make the parsing easier, by delimiting the text being sent?

Start,11,35,,
would be a lot easier to parse.

If that makes the task easier, that is OK. This just means that i need to start my messages with a “,” or, when receiving the string, truncate the first line of text

+CMGL: 1,"REC READ","+4580808080",,"11/11/12,15:48:19+04"
Start1135

Maybe, the first thing to look for is the CR+LF (before the message starts)

As you can see, i always get the CMGL: 1 etc when reading a SMS, then after a CR-LF, the contents i am interested in, starts. A new CR+LF ends the message.

As you can see, i am playing with a GSM modem, reading SMS messages :wink:

// Per.

This just means that i need to start my messages with a "," or, when receiving the string, truncate the first line of text

I don't know what you mean by truncate the first line of text. If you are only interested in the message portion, and that occurs after the first CR/LF, don't store anything until the LF is read. Then, store everything up to the next CR. When the CR is received, parse the string and use the data.

There is no reason to start the message with a comma. The strtok() function will look for the first delimiter (comma, in this case) in the string, and return a pointer to the token up to that delimiter. The next call, with NULL as the first argument will return a pointer to the next token. Do this part in a while loop, terminating when strtok() returns NULL, indicating that the end of the string was reached.

OK, i will search the forum for strtok() and see what i can find.

Still i have not a single idea of how to do this (i'm almost a complete noob at programming) but i am trying the best i can..

After all, hardware IS my stronger side...

// Per.

You may want to read this discussion as it may have some of what you need.

http://arduino.cc/forum/index.php/topic,78392.0.html

OK, i looked at it, and googled a bit, and found a site with the basics:

http://joysofprogramming.com/c-strings-library-index-locate-character-in-string/ and http://joysofprogramming.com/strtok-tokenize-strings-in-c/

Compiling the first program at the terminal works just fine like

$  gcc index.c
$  ./a.out
gramming

Putting in my own string of text "+CMGL: 1,"REC READ","+4580808080",,"11/11/12,15:48:19+04" The quick brown fox jumps over the lazy dog" (What would come from my GSM modem) and changing

int c = 'g';

to

int c = '\n';

It spits this out at the terminal:

The quick brown fox jumps over the lazy dog

Well, that is a part of the way - there is just a single "but" - i want to detect both \n and \r so the resulting string starts with "The quick...." and not "\rThe Quick...”

I tried looking at the syntax but i cannot make it work.

If i can figure out how to detect both the \r and \n and make a string with the rest, the code on the second link i mention can pick out the parts i am interested in and put them into variables.

I test this in the Terminal of my Unix console, it is way faster than programming the 'Duino all time :-)

// Per.

and changing

So, you said to split the string at the \n, and give you everything after the \n. Which it did.

Now, you want to know how to not include the \r that follows the \n in the returned string.

Seems pretty obvious, to me. Make the \r the delimiter, instead of the \n.

Once you have a token ("The quick brown fox jumps over the lazy dog" or "Start,11,35") use that as the input to strtok() to tokenize it. The delimiters can change between calls.

PaulS:
So, you said to split the string at the \n, and give you everything after the \n. Which it did.

Exactly!

PaulS:
Now, you want to know how to not include the \r that follows the \n in the returned string.
Seems pretty obvious, to me. Make the \r the delimiter, instead of the \n.

I have tried that, the terminal output is the same. It makes completely sense what you say, probably the \r comes before the \n (i cannot really check this, as my serial terminal does not show these “escape characters” or whatever they are named, sent from my GSM modem)

I figured out that the \n in printf("%s\n",return_val); makes a newline character after the program has executed, and does not make a newline character before first program output.

Anyhow, executing the program with \r as the delimiter gives the same terminal output as \n.

I tried changing the delimiter to " " (space character) instead, and first output from the program is not being started with a newline…

PaulS:
Once you have a token (“The quick brown fox jumps over the lazy dog” or “Start,11,35”) use that as the input to strtok() to tokenize it. The delimiters can change between calls.

Yep, that was what i had in mind :wink:

Sorry for being such a noob, i do the best i can :astonished:

// Per.

I figured out that the \n in printf("%s\n",return_val); makes a newline character after the program has executed,

The \n causes a carriage return to be generated as part of the string, and sent to the console output device by the printf function. This happens when the printf call is made, not "after the program has executed".

and does not make a newline character before first program output.

True. printf("\n%s",return_val); would output the carriage return first, then the string.

Anyhow, executing the program with \r as the delimiter gives the same terminal output as \n.

Printing the string inside some delimiters would be a useful exercise.

printf("[%s]\n", return_val); will print different thins, depending on whether return_val contains a \r at the beginning, or not, and depending on whether return_val contains a \n or \r at the end, or not.

Well, that is a part of the way - there is just a single "but" - i want to detect both \n and \r so the resulting string starts with "The quick...." and not "\rThe Quick...”

Look at the code in the below post (from the previous link discussion):

http://arduino.cc/forum/index.php/topic,78392.msg594928.html#msg594928