Unable to Split Serial Data to Character Arrays - Please help

Hi,

I am trying to Split Serial Data into different character arrays and print, but no success.

Following is the serial Data:

@$25.99*$9.99*Omega T-Shirt (XXL)*OMEGA101*#

Character ‘@’ is the starting character.
Character ‘#’ is the ending character.

Character ‘*’ is the separator. I am trying to split the above in 4 Character arrays. Following is my Program.

int SeperatorCount = 1;

char receivedData;

char R_PRICE[10];
char O_PRICE[10];
char PRODUCT_NAME[40];
char SKU[15];

void setup()

{
  Serial.begin(9600);
  delay(500);
}

void letsdisplay()
{
  Serial.println(R_PRICE);
  Serial.println(O_PRICE);
  Serial.println(PRODUCT_NAME);
  Serial.print('(');
  Serial.print(SKU);
  Serial.println(')');
}


void loop()

{

  int i,j,k,l = 0;

  while (Serial.available() > 0)
  {
    receivedData = Serial.read();
    if (receivedData == '@')
      Serial.println("\n___________________________\n Transmission begins...");
    else if (receivedData == '#')
      letsdisplay();
    else
    {
      switch (SeperatorCount)
      {
        case 1:
          if (receivedData == '*')
            SeperatorCount = SeperatorCount + 1;
          else 
            R_PRICE[i++] = receivedData;
          break;
        case 2:
          if (receivedData == '*')
            SeperatorCount = SeperatorCount + 1;
          else
            O_PRICE[j++] = receivedData;
          break;
        case 3:
          if (receivedData == '*')
            SeperatorCount = SeperatorCount + 1;
          else
            PRODUCT_NAME[k++] = receivedData;
          break;
        case 4:
          if (receivedData == '*')
            SeperatorCount = 1;
          else
            SKU[l++] = receivedData;
          break;
      }
    }


  }

}

The above Program prints:

    ( <--Empty Character )
9
)
(1)

My requirements is:

$25.99
$9.99
Omega T-Shirt (XXL)
OMEGA101

So, my curiosity is:

  • Why is it printing only last charter for O_PRICE, PRODUCT_NAME and SKU and, empty character for R_PRICE.
  • And why is it not printing Full string.

I tried to end the Character arrays by assigning ‘\0’ character, if I do so, everything is printed as empty.

But if I am printing it serially without splitting like below, it works:

void loop()

{
  while (Serial.available() > 0)
    {
    receivedData = Serial.read();
    if((receivedData == '@') || (receivedData == '*') || (receivedData == '#'))
      Serial.print("\n");
    else
     Serial.print(receivedData);
    }
}

Please help me on this.

Thanks.

In 'loop()', change this:-

int i,j,k,l = 0;

to this:-

static int i=0, j=0, k=0, l = 0;

When I do that, I get this output in the serial monitor:-

___________________________
 Transmission begins...
$25.99
$9.99
Omega T-Shirt (XXL)
(OMEGA101)

Would be so much easier to use strtok.

@OldSteve:

I am getting the following, if I make the changes you suggested:

___________________________
 Transmission begins...
$25.99   <-- Got this one finally!
             <-- Empty
             <-- Empty
()          < -- Empty

What did i miss ?

gauman1981:
@OldSteve:

I am getting the following, if I make the changes you suggested:

___________________________

Transmission begins…
$25.99  ← Got this one finally!
            ← Empty
            ← Empty
()          < – Empty


What did i miss ?

This is the exact code I ran:-

int SeperatorCount = 1;
char receivedData;
char R_PRICE[10];
char O_PRICE[10];
char PRODUCT_NAME[40];
char SKU[15];

void setup()
{
    Serial.begin(9600);
    delay(500);
}

void letsdisplay()
{
    Serial.println(R_PRICE);
    Serial.println(O_PRICE);
    Serial.println(PRODUCT_NAME);
    Serial.print('(');
    Serial.print(SKU);
    Serial.println(')');
}


void loop()

{

    static int i=0, j=0, k=0, l = 0;

    while (Serial.available() > 0)
    {
        receivedData = Serial.read();
        if (receivedData == '@')
            Serial.println("\n___________________________\n Transmission begins...");
        else if (receivedData == '#')
            letsdisplay();
        else
        {
            switch (SeperatorCount)
            {
                case 1:
                    if (receivedData == '*')
                        SeperatorCount = SeperatorCount + 1;
                    else
                        R_PRICE[i++] = receivedData;
                    break;
                case 2:
                    if (receivedData == '*')
                        SeperatorCount = SeperatorCount + 1;
                    else
                        O_PRICE[j++] = receivedData;
                    break;
                case 3:
                    if (receivedData == '*')
                        SeperatorCount = SeperatorCount + 1;
                    else
                        PRODUCT_NAME[k++] = receivedData;
                    break;
                case 4:
                    if (receivedData == '*')
                        SeperatorCount = 1;
                    else
                        SKU[l++] = receivedData;
                    break;
            }
        }
    }
}

And this is the exact line I entered into the serial monitor, (copied, then pasted into the serial monitor input text box using Ctrl-V):-@$25.99*$9.99*Omega T-Shirt (XXL)*OMEGA101*#

And this is the exact result, selected, then copied from the serial monitor output window using Ctrl-C:-

___________________________
 Transmission begins...
$25.99
$9.99
Omega T-Shirt (XXL)
(OMEGA101)

I get that result regardless of whether or not I use a line-ending in the serial monitor, by the way.

You’ve done something wrong, so try copying and pasting my code and testing it.

Delta_G:
Would be so much easier to use strtok.

Yep, but still, his code should work fine as long as the vars are declared as 'static' and initialised to 0.

OP: you'd do well to keep it to one statement per line. How much have you saved by cramming all those variable definitions on one line and then having to spend all this time to try to get it right? Does the static stick to all of them? Don't know. But if you write one per line you can be sure each one gets a static.

FYI… I am transmitting serial data wirelessly using XBEEs.

Now, I am getting the following(both your and my code):

___________________________
 Transmission begins...
$25.99
           <-- Empty
           <-- Empty
()        <-- Empty

___________________________
 Transmission begins...
$25.99            <-- Got it
                      <-- Empty
                      <-- Empty
(OMEGA101)   <-- Got it.

___________________________

But If I print without splitting using below it still works, which is strange:

void loop()

{
  while (Serial.available() > 0)
    {
    receivedData = Serial.read();
    if((receivedData == '@') || (receivedData == '*') || (receivedData == '#'))
      Serial.print("\n");
    else
     Serial.print(receivedData);
    } 
}

@Delta_G,

I tried the following:

    static int i=0;
    static int j=0;
    static int k=0;
    static int l = 0;

But same results.

Delta_G:
OP: you'd do well to keep it to one statement per line. How much have you saved by cramming all those variable definitions on one line and then having to spend all this time to try to get it right? Does the static stick to all of them? Don't know. But if you write one per line you can be sure each one gets a static.

It does 'stick', because the code works for me. Still, I agree with you about keeping each declaration on a separate line, for clarity.

gauman1981:
FYI… I am transmitting serial data wirelessly using XBEEs.

Now, I am getting the following(both your and my code):

___________________________

Transmission begins…
$25.99
          ← Empty
          ← Empty
()       ← Empty


Transmission begins…
$25.99           ← Got it
                    ← Empty
                    ← Empty
(OMEGA101)   ← Got it.





But If I print without splitting using below it still works, which is strange: 



void loop()

{
 while (Serial.available() > 0)
   {
   receivedData = Serial.read();
   if((receivedData == ‘@’) || (receivedData == ‘*’) || (receivedData == ‘#’))
     Serial.print("\n");
   else
    Serial.print(receivedData);
   }
}

Then obviously, something else is going on, since with a serial stream from the serial monitor it works fine, (only when the variables are declared as ‘static’, of course, otherwise it couldn’t work because the variables are re-declared on each iteration of the ‘loop()’). If I leave out the ‘static’, I get the same result as you.

You didn’t mention the fact that it was being transmitted via RF using XBee modules. I can’t duplicate that. I can only test what’s in front of me.

Your output indicates that some invalid characters are being received.
Perhaps you could add a very short delay between characters at the transmitting end, if that’s possible with the XBee modules. (Shouldn’t really be necessary though.)

@OldSteve,

Thanks for the help.

I will try to debug more and see.

gauman1981:
@OldSteve,
Thanks for the help.
I will try to debug more and see.

No worries. I hope you can get it sorted out. It should work.

Unfortunately, there’s nothing further I can do, since I can’t reproduce your exact problem without a pair of XBee modules, (and your transmitting code).
Good luck.

I changed the transmitter code a bit and reduced the delay a bit.

And In the receiver code when I use:

  static int i = 0;
  static int j = 0;
  static int k = 0;
  static int l = 0;

I get the following weird o/p. fist transmission is perfect. Then it slowly enters into an infinite loop.

Transmission begins...

$25.99
$9.99
Omega T-Shirt (XXL)
(OMEGA101)

Transmission begins...

$25.99
$28
$9.99$9.99

Omega T-Shirt (XXL)Omega T-Shirt (XXL)
(OMEGA101OMEGA101)

Transmission begins...

$25.99
$2@
$9.99$9.99(
Omega T-Shirt (XXL)Omega T-ShirtOMEGA101u
(OMEGA101OMEGA109)

Transmission begins...

a T-ShirtOMEGA101u
(OMEGA101OMEGA109)
ransmission begins...

$25.99
$2H
EGA1019.99-
Omega T-Shirt (XXL)Omega T-ShirtOMEGA101OMEGA1019.99-
(OMeGA101OMEGA10A)
rt (XXL)Omega T-ShirtOMEGA101OMEGA1019.99-
(OMeGA101OMEGA10A)
rt (XXL)Omega T-ShirtOMEGA101OMEGA1019.99-
(OMeGA101OMEGA10A)
rt (XXL)Omega T-ShirtOMEGA101OMEGA1019.99-
(OMeGA101OMEGA10A)

But if I remove the Static ints and make them like before, I get last character of the character strings.

It’s very late, and I’m not thinking too clearly, but are you resetting the variables to 0 after each complete cycle?
Edit: Maybe immediately after you call the ‘letsdisplay()’ function.
Edit2: Now I’m off to bed - it’s almost 2am here. :frowning:

Yes. I will try more.

Please carry on. Have a good night.

Thanks a ton!

No problem. I hope it helps. Good night.

gauman1981:
I get the following weird o/p. fist transmission is perfect. Then it slowly enters into an infinite loop.

When you get the terminator and you display the data, you should probably then reset i, j, k , and l back to 0.

Delta_G:
When you get the terminator and you display the data, you should probably then reset i, j, k , and l back to 0.

Exactly what I said in reply #14. :slight_smile:

Hello Good Morning!

Yes I tried the following and I am getting pretty stable o/p except one small thing.

In first transmission I get everything clean.
But, from second transmission, 2 extra blank characters are getting preceded to R_PRICE(The first variable) variable o/p. I cannot see this when I print on Serial monitor, but I can see when I display on a TFT display.

I checked the loops also. After receiving the first transmission the loop automatically increments the consecutive transmissions by 2 characters and stores in R_PRICE.

I thought this might be the problem with transmission, and checked on XCTU and other serial interfaces to XBEE, things are pretty clean. Which means , the problem might be while Splitting.

Its a small issue, but curiosity is making me restless. Below is the code:

void loop()

{

  static int i,j,k,l;

  while (Serial.available() > 0)
  {
  Serial.println("Inside While...");
    receivedData = Serial.read();
    if (receivedData == '@')
      Serial.println("\nTransmission begins...\n");
    else if (receivedData == '#')
    {
      letsdisplay();
      i=0;
      j=0;
      k=0;
      l=0;
    }  
    else
    {
      switch (SeperatorCount)
      {
        case 1:
          Serial.print("i= ");
          Serial.println(i);
          Serial.print("j= ");
          Serial.println(j);
          Serial.print("k= ");
          Serial.println(k);
          Serial.print("l= ");
          Serial.println(l);
          if (receivedData == '*')
            SeperatorCount = SeperatorCount + 1;
          else 
            R_PRICE[i++] = receivedData;
          break;
        case 2:
          Serial.print("i= ");
          Serial.println(i);
          Serial.print("j= ");
          Serial.println(j);
          Serial.print("k= ");
          Serial.println(k);
          Serial.print("l= ");
          Serial.println(l);
          if (receivedData == '*')
            SeperatorCount = SeperatorCount + 1;
          else
            O_PRICE[j++] = receivedData;
          break;
        case 3:
          Serial.print("i= ");
          Serial.println(i);
          Serial.print("j= ");
          Serial.println(j);
          Serial.print("k= ");
          Serial.println(k);
          Serial.print("l= ");
          Serial.println(l);
          if (receivedData == '*')
            SeperatorCount = SeperatorCount + 1;
          else
            PRODUCT_NAME[k++] = receivedData;
          break;
        case 4:
          Serial.print("i= ");
          Serial.println(i);
          Serial.print("j= ");
          Serial.println(j);
          Serial.print("k= ");
          Serial.println(k);
          Serial.print("l= ");
          Serial.println(l);
          if (receivedData == '*')
            SeperatorCount = 1;
          else
            SKU[l++] = receivedData;
          break;
      }
    }


  }
delay(20000);
}

I am not initializing Static variables while declaration as I read somewhere that if not explicitly initiated, the static variables will be initiated to '0'.

If you have time, please put some light on this, what can be the issue.