4
\$\begingroup\$

I am receiving some strings from UART in AVR. Strings are chaotic, not deterministic. It also includes new line \n and carriage return \r characters that's why I couldn't find a solution including checking bytes if they are \n or \r.

So is there a way to determine the end of the data?

EDIT: For more details about the data I receive. I am acquiring some strings from my web server and they are commands to be used such as "weather+check\r\n". Another one is, for example, "time\r\nNew York+Check\r\n\r\". I simply want to get these strings and assign to a char array. But to do this I need to know when data ends so that I can go out of the While loop that I use to fill the array.

\$\endgroup\$
  • \$\begingroup\$ we cannot help you unless you describe what sort of data is being sent, at what rate, if it's a stream or a "packet"/burst, etc. And do you know if it's valid/correct data at all? \$\endgroup\$ – KyranF May 13 '15 at 20:30
  • \$\begingroup\$ Its not clear what you are asking: Is the output of your data source random? Then there is no point in looking for some end marker. Or have you control over the avr? Then make sure that it does not send gibberish after it has sent the data. \$\endgroup\$ – 0x6d64 May 13 '15 at 20:30
  • \$\begingroup\$ @KyranF I am editing my question for details. \$\endgroup\$ – Zgrkpnr May 13 '15 at 20:32
  • 1
    \$\begingroup\$ @0x6d64 edited my question. \$\endgroup\$ – Zgrkpnr May 13 '15 at 20:38
  • 1
    \$\begingroup\$ If you control the output of your web server then you need to use or invent some kind of protocol. Do you control the data or not? \$\endgroup\$ – David May 13 '15 at 21:17
2
\$\begingroup\$

Without some sort of defined protocol, there is no sure way to determinate the end of a string, except for it being terminated by a carriage return ('\r') and/or linefeed ('\n') character.

You want to try something like this:

#define BUF_LEN 100
char buf [BUF_LEN];
unsigned short i;


i = 0;
while (1)
{
    char ch;
    ch = getChar();
    if (ch != '\n')     // ignore lf's
    {
        if (ch != '\r')
        {
                if (i < BUF_LEN-2)
                {
                    buf[i++] = ch;
                    buf[i] = '\0';
                }
        }
        else
        {
            break;      // string now in buf, terminated w/ '\0'
        }
    }   
}

Some strings don't have line feeds ('\n') so I just generally ignore them and treat carriage returns ('\r') as an end of string.

This code allocates a buffer buf which is 100 characters long. If that is not enough, then increase the number in the #define. Of course the buffer could have been allocated on the heap, but a lot of small microcontrollers don't have enough RAM for a useful heap.

I'm using a routine called getChar to get the character, one by one. Change that to whatever you have available.

The routine is very simple, it just gets characters and stores them in a buffer until a carriage return is found. Then it breaks out of the loop with the string in the buffer, terminated by a 0 ('\0') without any '\r' or '\n' in it.

\$\endgroup\$
  • \$\begingroup\$ You are absolutely right, Sir. This is what I would do normally, but the point is that my strings includes carriage return and line feed not only at the and but also in the middle. \$\endgroup\$ – Zgrkpnr May 13 '15 at 21:02
  • 1
    \$\begingroup\$ From your example, it looks like the final termination is '\r' '\n' '\r' which means you would get an empty string after the second '\r'. If that is always the case, then you could just gather strings together using my code, and then when you have an empty string consider that you are done. If you have no consistent structure in the data, then you will need some sort of other context to go by. Other than the above sequence, I have no more idea of "when the data ends" than you do. \$\endgroup\$ – tcrosley May 13 '15 at 21:13
  • \$\begingroup\$ Yes, Sir. Now that makes sense.Respect to experience. \$\endgroup\$ – Zgrkpnr May 13 '15 at 21:27
0
\$\begingroup\$

Let me point something out which may help: Text strings originating from Unix/Linx machines are typically end-of-line terminated ('\n') Text strings originating from Windows machines are terminated with two characters ('\r\n') In both cases, there's a \n.

Are you receving/processing text strings from both these environments and that's leading to a poorly defined end of string determination? It looks like you've got an extra \r character in one of your strings.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.