How to separate incoming data from SerialPort

Hi to everyone!

I have an aplication that sending characters from a few TextBoxes and I want next thing:

When I click on 'send' button,I need to get that characters separate from all textboxes and forward it to corresponding functions.
Char from TextBox1 will be X argument for 'function1',char from TextBox2 will be Y argument for 'function1' etc.

Can I do this with SerialEvent and how? For now,I know only to catch data from one TextBox and use it,but I need more than that...

Thanks in advance! :slight_smile:

You have to have something unique in each text box or add some unique identifier in the code that transfers the text box to the serial port.
Then you identify that unique component when you receive it on the arduino and send the data to the appropriate function.

Well...it's very complicated. With SerialEvent I can catch just one by one character (if I send 'abcdef' i will get only 'ab' in most of cases). Than,I need to send 2 characters for identification and put 2 if loops for that (again one by one) and than another one or two for important bits...that's a bit impractical and complicated...I wonder if there is any easier way?

Then you identify that unique component when you receive it on the arduino and send the data to the appropriate function.

This is the answer.
Maybe use an *,%,> etc. character that won't part of the message you want to detect.

Yes,I'm doing that,but I have about 10-15 TextBoxes and than it's not enough just one character,i need two. 15x2 if loops + something to arrange characters after identification for all of them...that's very ugly and error-prone code.

but I have about 10-15 TextBoxes

So, send the contents of the text box with an identifier and start and end of packet delimiters. For instance, if you have a text box named X, containing BuffaloWingsAreGreat, send “<X:BuffaloWingsAreGreat>”. Then, use some code like this:

#define SOP '<'
#define EOP '>'

bool started = false;
bool ended = false;

char inData[80];
byte index;

void setup()
{
   Serial.begin(57600);
   // Other stuff...
}

void loop()
{
  // Read all serial data available, as fast as possible
  while(Serial.available() > 0)
  {
    char inChar = Serial.read();
    if(inChar == SOP)
    {
       index = 0;
       inData[index] = '\0';
       started = true;
       ended = false;
    }
    else if(inChar == EOP)
    {
       ended = true;
       break;
    }
    else
    {
      if(index < 79)
      {
        inData[index] = inChar;
        index++;
        inData[index] = '\0';
      }
    }
  }

  // We are here either because all pending serial
  // data has been read OR because an end of
  // packet marker arrived. Which is it?
  if(started && ended)
  {
    // The end of packet marker arrived. Process the packet

    // Reset for the next packet
    started = false;
    ended = false;
    index = 0;
    inData[index] = '\0';
  }
}

Where it says “Process the packet”, inData will contain “X:BuffaloWingsAreGreat”. The strtok() function can separate that into two tokens “X” and “BuffaloWingsAreGreat”. Then, you can do what you want with those two tokens.

Simple code that uses a comma , as a packet delimiter, and each packet has a unique identifier (CD, CM, CT, CS, BR) that is looked for.

//zoomkat 3-5-12 simple delimited ',' string  
//from serial port input (via serial monitor)
//and print result out serial port

String readString, data;
int CD, CM, CT, CS, BR; 

void setup() {
  Serial.begin(9600);
  Serial.println("serial delimit test 1.0"); // so I can keep track of what is loaded
}

void loop() {

  //expect a string like CD01,CM01,CT01,CS03,BR255,

  if (Serial.available())  {
    char c = Serial.read();  //gets one byte from serial buffer
    
    if (c == ',') {
      Serial.println(readString); //prints string to serial port out
      
      if(readString.indexOf("CD") >=0) {
        data=readString.substring(2);
        Serial.print("CD is: ");
        Serial.println(data);
        CD = data.toInt();
        Serial.println(CD);
        Serial.println();
      }
      if(readString.indexOf("CM") >=0) {
        readString=readString.substring(2);
        Serial.print("CM is: ");
        Serial.println(readString);
        CM = readString.toInt();
        Serial.println(CM);
        Serial.println();
      }
      if(readString.indexOf("CT") >=0) {
        readString=readString.substring(2);
        Serial.print("CT is: ");
        Serial.println(readString);
        CT = readString.toInt();
        Serial.println(CT);
        Serial.println();
      }
       if(readString.indexOf("CS") >=0) {
        readString=readString.substring(2);
        Serial.print("CS is: ");
        Serial.println(readString);
        CS = readString.toInt();
        Serial.println(CS);
        Serial.println();
      }
       if(readString.indexOf("BR") >=0) {
        readString=readString.substring(2);
        Serial.print("BR is: ");
        Serial.println(readString);
        BR = readString.toInt();
        Serial.println(BR);
        Serial.println();
      }
      
      //do some stuff

      readString=""; //clears variable for new input
      data=""; 

    }  
    else {     
      readString += c; //makes the string readString
    }
  }
}

Ok,I did what PaulS said and I have another problem now.

From aplication,I’m sending e.g.:

TextBox1: 1
TextBox2: 22
TextBox3: 333
TextBox4: 4444

When i click on Send button,c# aplication sending all 4 textboxes like this: <1223334444*>

Than,in arduino I get inData (char) and convert it to string: String str(inData);

After that,I print that string with for loop:

for (i=0;i<str.length();i++)
MyFunction.print(str*);[/quote]*
And I have this:
_ 1223334444*_
I use function string.indexOf() to get positions of every * in string (pos1,pos2,pos3,pos4,pos5).
For this example,i have following values: 0,2,5,9,14 and tha’s great. And what to do now? How to get 4 new strings from this one? I want to extract characters between 0 and 2, 2 and 5, 5 and 9, 9 and 14. But,this numbers (0,2,5,9,14) are variables,and I can’t use function string.substring(pos1,pos2),it’s working good only with numbers. Also,I tried with this:
> String string1; //first string,which should contain ‘1’
> for (i=pos+1;i<pos2;i++){
> string1=string1+str*; //str is the main string*
> }
> *int FirstValue=string1.toInt(); *
> MyFunction.print(FirstValue); // I don’t need print,i just checking,this int (and 3 others) i must send to some function
> [/quote]
> And with both methods I get poorly results. 2 good values + one zero,or 1 good + 1 wrong,or 4 zeroes…

Than,in arduino I get inData (char) and convert it to string: String str(inData);

Why? Don’t do that. First, get rid of the first and last '*'s, They make parsing harder, not easier. The < and > delimit the packet.

Use strtok() to get each token from inData, and use atoi() to convert each token to an int.

I can't remove first '*' because i need it for identification. For last one,it's ok to remove if i would use strtok().

Ok,i will try strtok() today :slight_smile:

Btw,i think that the problem with my two previous attempts is non-static string,i must use static string i think...But first I'm going to try what you said.

I can't remove first '*' because i need it for identification.

For identification of what?

Trust me. You can remove it. The sender does not need it. The receiver doesn't need it.

It works! :slight_smile:
Thanks mate! you helped me a lot!

strtok() and atoi() works exelent!