parsing serial only receiving part of the string

Hi i am sending the following over serial from pi to arduino: (not exact numbers but same layout and characters)

a123:b233:c142:d142:e124:f124:g123:h123:i124:j127:k128:l125:m127:n125:o124:p126:q136:r125:s152:t124:u124:v123:w123:x124:

how ever i only receieve part of this, this is shown in the arduino serial window:

Data entered: a212:b126:c000:d255:e129:f212:g126:h000:i255:j129:k212:l126:m23

as you can see it only reads up to the first 2 characters after m and i haven’t a clue why? i have increased my buffer size and increased the delay but still nothing. I understand its not the most efficient way to parse a string but it would appear the problem is on the receiving side of things. Can anyone help? Thanks

char buffer[400];
int c1,c2,c3,c4,c6,c7,c8,c9,c10,c11,c12,c13,c14,c15,c16,c17,c18,c19,c20,c21,c22,c23,c24;
int RedPin = 11;
int GreenPin = 10;
int BluePin = 9;

void setup()
{
      Serial.begin(9600);
      while(Serial.available())
      Serial.read();
}

void loop() {
        if (Serial.available() > 0) {
                int index=0;
                delay(300); // let the buffer fill up
                int numChar = Serial.available();
                if (numChar>180) {
                        numChar=180;
                }
                while (numChar--) {
                buffer[index++] = Serial.read();
                }
                splitString(buffer);
        }
}

void splitString(char* data) {

Serial.print("Data entered: ");
Serial.println(data);
char* parameter;
parameter = strtok (data, ":"); // Note that this is a space before the comma in " , "
while (parameter != NULL) {
 setLED(parameter); 
 parameter = strtok (NULL, ":"); // space before the comma in " , "
}


// Clear the text and serial buffers
for (int x=0; x<180; x++) {
        buffer[x]='\0';
}
while(Serial.available())
        Serial.read();}
void setLED(char* data) {
        if ((data[0] == 'a') || (data[0] == 'A')) {
                int Ans = strtol(data+1, NULL, 10);
                Ans = constrain(Ans,0,255);
                analogWrite(GreenPin, Ans);
                Serial.print("C1 = ");
                Serial.println(Ans);
        }
        if ((data[0] == 'b') || (data[0] == 'B')) {
                int Ans = strtol(data+1, NULL, 10);
                Ans = constrain(Ans,0,255);
                analogWrite(GreenPin, Ans);
                Serial.print("C2 = ");
                Serial.println(Ans);
        }
        if ((data[0] == 'c') || (data[0] == 'C')) {
                int Ans = strtol(data+1, NULL, 10);
                Ans = constrain(Ans,0,255);
                analogWrite(BluePin, Ans);
                Serial.print("C3 = ");
                Serial.println(Ans);
}
        if ((data[0] == 'd') || (data[0] == 'D')) {
                int Ans = strtol(data+1, NULL, 10);
                Ans = constrain(Ans,0,255);
                analogWrite(GreenPin, Ans);
                Serial.print("C4 = ");
                Serial.println(Ans);
        }
        if ((data[0] == 'e') || (data[0] == 'E')) {
                int Ans = strtol(data+1, NULL, 10);
                Ans = constrain(Ans,0,255);
                analogWrite(GreenPin, Ans);
                Serial.print("C5 = ");
                Serial.println(Ans);
        }
        if ((data[0] == 'f') || (data[0] == 'F')) {
                int Ans = strtol(data+1, NULL, 10);
                Ans = constrain(Ans,0,255);
                analogWrite(BluePin, Ans);
                Serial.print("C6 = ");
                Serial.println(Ans);
}         if ((data[0] == 'g') || (data[0] == 'G')) {
                int Ans = strtol(data+1, NULL, 10);
                Ans = constrain(Ans,0,255);
                analogWrite(GreenPin, Ans);
                Serial.print("C7 = ");
                Serial.println(Ans);
        }
        if ((data[0] == 'h') || (data[0] == 'H')) {
                int Ans = strtol(data+1, NULL, 10);
                Ans = constrain(Ans,0,255);
                analogWrite(GreenPin, Ans);
                Serial.print("C8 = ");
                Serial.println(Ans);
        }
        if ((data[0] == 'i') || (data[0] == 'I')) {
                int Ans = strtol(data+1, NULL, 10);
                Ans = constrain(Ans,0,255);
                analogWrite(BluePin, Ans);
                Serial.print("C9 = ");
                Serial.println(Ans);
}         
if ((data[0] == 'j') || (data[0] == 'J')) {
                int Ans = strtol(data+1, NULL, 10);
                Ans = constrain(Ans,0,255);
                analogWrite(GreenPin, Ans);
                Serial.print("C10 = ");
                Serial.println(Ans);
        }
        if ((data[0] == 'k') || (data[0] == 'K')) {
                int Ans = strtol(data+1, NULL, 10);
                Ans = constrain(Ans,0,255);
                analogWrite(GreenPin, Ans);
                Serial.print("C11 = ");
                Serial.println(Ans);
        }
        if ((data[0] == 'l') || (data[0] == 'L')) {
                int Ans = strtol(data+1, NULL, 10);
                Ans = constrain(Ans,0,255);
                analogWrite(BluePin, Ans);
                Serial.print("C12 = ");
                Serial.println(Ans);
}         if ((data[0] == 'm') || (data[0] == 'M')) {
                int Ans = strtol(data+1, NULL, 10);
                Ans = constrain(Ans,0,255);
                analogWrite(GreenPin, Ans);
                Serial.print("C13 = ");
                Serial.println(Ans);
        }
        if ((data[0] == 'n') || (data[0] == 'N')) {
                int Ans = strtol(data+1, NULL, 10);
                Ans = constrain(Ans,0,255);
                analogWrite(GreenPin, Ans);
                Serial.print("C14 = ");
                Serial.println(Ans);
        }
        if ((data[0] == 'o') || (data[0] == 'O')) {
                int Ans = strtol(data+1, NULL, 10);
                Ans = constrain(Ans,0,255);
                analogWrite(BluePin, Ans);
                Serial.print("C15 = ");
                Serial.println(Ans);
}         if ((data[0] == 'p') || (data[0] == 'P')) {
                int Ans = strtol(data+1, NULL, 10);
                Ans = constrain(Ans,0,255);
                analogWrite(GreenPin, Ans);
                Serial.print("C16 = ");
                Serial.println(Ans);
        }
        if ((data[0] == 'q') || (data[0] == 'Q')) {
                int Ans = strtol(data+1, NULL, 10);
                Ans = constrain(Ans,0,255);
                analogWrite(GreenPin, Ans);
                Serial.print("C17 = ");
                Serial.println(Ans);
        }
        if ((data[0] == 'r') || (data[0] == 'R')) {
                int Ans = strtol(data+1, NULL, 10);
                Ans = constrain(Ans,0,255);
                analogWrite(BluePin, Ans);
                Serial.print("C18 = ");
                Serial.println(Ans);
}         if ((data[0] == 's') || (data[0] == 'S')) {
                int Ans = strtol(data+1, NULL, 10);
                Ans = constrain(Ans,0,255);
                analogWrite(GreenPin, Ans);
                Serial.print("C19 = ");
                Serial.println(Ans);
        }
        if ((data[0] == 't') || (data[0] == 'T')) {
                int Ans = strtol(data+1, NULL, 10);
                Ans = constrain(Ans,0,255);
                analogWrite(GreenPin, Ans);
                Serial.print("C20 = ");
                Serial.println(Ans);
        }
        if ((data[0] == 'u') || (data[0] == 'U')) {
                int Ans = strtol(data+1, NULL, 10);
                Ans = constrain(Ans,0,255);
                analogWrite(BluePin, Ans);
                Serial.print("C21 = ");
                Serial.println(Ans);
}         if ((data[0] == 'v') || (data[0] == 'V')) {
                int Ans = strtol(data+1, NULL, 10);
                Ans = constrain(Ans,0,255);
                analogWrite(GreenPin, Ans);
                Serial.print("C22 = ");
                Serial.println(Ans);
        }
        if ((data[0] == 'w') || (data[0] == 'W')) {
                int Ans = strtol(data+1, NULL, 10);
                Ans = constrain(Ans,0,255);
                analogWrite(GreenPin, Ans);
                Serial.print("C23 = ");
                Serial.println(Ans);
        }
        if ((data[0] == 'x') || (data[0] == 'X')) {
                int Ans = strtol(data+1, NULL, 10);
                Ans = constrain(Ans,0,255);
                analogWrite(BluePin, Ans);
                Serial.print("C24 = ");
                Serial.println(Ans);
} 
}

to arduino

To which Arduino?

                int index=0;
                delay(300); // let the buffer fill up

Never mind which. You NEVER wait for the serial buffer to fill up. Doing so almost certainly ensures data loss.

You need to change what your pi sends, to include a packet terminator. You need to read and store data as fast as possible until that packet terminator arrives. Only then should you try to use the data in the packet.

Given that the packet consists of severl subpackets, it seems stupid to wait until all of the subpackets arrive. Read and store data until the colon arrives WITHOUT USING DELAY().

Then, process the packet. The first letter defines what the data is for.

You might try parsing your data similar to the below.

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

String readString;

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 a123:b233:c142:d142:e124:f124:g123:h123:i124:j127:
  
  if (Serial.available())  {
    char c = Serial.read();  //gets one byte from serial buffer
    if (c == ':') {
      //do stuff
      Serial.println(readString); //prints string to serial port out
      readString=""; //clears variable for new input      
     }  
    else {     
      readString += c; //makes the string readString
    }
  }
}

Any one remember if the serial buffer has 64 or 128 bytes on the input side. I know its less than 180!.

Mark

It's 64 - I just counted the number of chars in the OP's result.

M

does that mean i cant send as much data as i need? is there a way of sending the first 64 then flushing the buffer and receiving the 2nd 64?

does that mean i cant send as much data as i need?

No, it doesn't. It means that you can't dink around waiting for the buffer to get full before you start reading.

is there a way of sending the first 64 then flushing the buffer and receiving the 2nd 64?

Why would you need to flush the empty buffer after you've read all the data?

Yes, you could make the sender send 64 bytes, and then wait for the Arduino to send a "ready" message before sending more data.

Using Strings slows down handling serial data. Considerably.

i dont think im understanding what the buffer actually does and what exactly the problem i'm having is. could you explain this a little more for me? in my understanding the buffer stores the data until it is moved on to say a variable which is why i thought you would need to clear the memory (flush) to allow for more data to be received. Also how else would you send data to speed things up?
Thanks

You have a 64 byte buffer. If you send more than that before reading anything, you will lose data.

Serial data transmission is very slow compared to the arduino's clock speed so you have plenty of time to read the data as it's arriving. You can create your own larger buffer and copy the incoming data there as it arrives. Better though as suggested above to parse the data as it arrives; no need to wait for the whole string - every time you see a colon, you can parse and reset your (small) buffer.

Edit: typos

Thanks
quick solution if anyone else struggles with this is to edit the arduino source code and adjust the buffer size as shown here.

http://www.hobbytronics.co.uk/arduino-serial-buffer-size