processing incomming serial data.

hi,

i am in need of some guidance when it comes to reading serial data on te arduino.
i am trying to control two LED’s via a GUI made with processing but the problem i am having is that the arduino does not read the incomming serial data the way it should be read.

Code on the arduino:

    #define redLED 6
    #define blueLED 5
    char new_buffer[2];
   
 
     void setup()
     {
      // put your setup code here, to run once:
      Serial.begin(9600);
      pinMode(redLED, OUTPUT);
      pinMode(blueLED, OUTPUT);
     
    }
     
    void loop()
    {
         char buffer[4];
     
    if(Serial.available() >0)
    {
       for (int i = 0; i<4;i++)
        {
         buffer[i] = Serial.read();
        }
    }
   
    if(buffer[0] == 253 && buffer[3] == 254)
    {
        new_buffer[0] = buffer[1];
        new_buffer[1] = buffer[2];
   }
     analogWrite(redLED, new_buffer[0]);
     analogWrite(blueLED,new_buffer[1]);
    }

the code that is used to send the serial data in processing:

char[] sliders = { 0,0};
public void draw(){

  sliders[0] =(char) redSlider.getValueI();
  sliders[1] =(char) blueSlider.getValueI();
  port.write(253);
  port.write(sliders[0]);
  port.write(sliders[1]);
  port.write(254);
}
         char buffer[4];
     
    if(Serial.available() >0)
    {
       for (int i = 0; i<4;i++)
        {
         buffer[i] = Serial.read();
        }
    }

Check if there is at least 1 character available, and then read all 4 of them. Doesn’t sound right does it? You’re assuming that Serial data arrives instanteously. It does’t. loop() can run hundreds of times in between characters being available in the buffer. Either only read 4 bytes of data when there is 4 bytes of data, or store items in the array as they come, and only process the data once you receive and end of packet marker.

Why not add a serial print that way you can actually see what the Arduino is getting from processing, instead of guessing why its not working.

HazardsMind:
Why not add a serial print that way you can actually see what the Arduino is getting from processing, instead of guessing why its not working.

done that, and i have checked it with serialmon and the data send from processing is correct.

the data send from processing is correct.

So the Arduino does see the correct data from processing but yet it still wont work.

So on the Arduino side you should be seeing,
253
XXX
YYY
254
but the way you have it coded, it can see the XXX value first and the YYY,254,and rollover back to 253. That’s not the sequence you want, so maybe you should do as Arrch suggested and use opening and closing markers.

This is the proper packet you should be sending out.
<253,XXX,YYY,254>

And in your code you should be looking for

if( Serial.read() == ‘<’ )
{
buffer[counter] = Serial.read();

if(Serial.read() != ‘>’ ) counter++;
else counter = 0;
}

And in your code you should be looking for

if( Serial.read() == ‘<’ )
{
buffer[counter] = Serial.read();

if(Serial.read() != ‘>’ ) counter++;
else counter = 0;
}

That absolutely will NOT work. You need to store each character read and do all the comparisons and storing based on that stored value, not read a new value each time.

Play computer, and see what happens if the sender sends “”. Assuming that all 5 characters are in the serial buffer, what ends up in buffer, and what value does counter have?

One simple way to capture incoming serial data and operate the board LED based on the data.

//zoomkat 3-5-12 simple delimited ',' string parse 
//from serial port input (via serial monitor)
//and print result out serial port
// CR/LF could also be a delimiter
//send on, or off, from the serial monitor

int ledPin = 13;
String readString;

void setup() {
  Serial.begin(9600);
  pinMode(ledPin, OUTPUT); 
  Serial.println("serial LED on/off test with , delimiter"); // so I can keep track
}

void loop() {

  if (Serial.available())  {
    char c = Serial.read();  //gets one byte from serial buffer
    if (c == ',') {
      Serial.println(readString); //prints string to serial port out
      //do stuff with the captured readString
      if(readString.indexOf("on") >=0)
      {
        digitalWrite(ledPin, HIGH);
        Serial.println("LED ON");
      }
      if(readString.indexOf("off") >=0)
      {
        digitalWrite(ledPin, LOW);
        Serial.println("LED OFF");
      }       
      readString=""; //clears variable for new input
    }  
    else {     
      readString += c; //makes the string readString
    }
  }
}

I learned from PaulS that using a beginning of packet character and end of packet character works best for my projects..

this way you can check when new data is being sent and when its done.. and not miss or mix up values/data..

@PaulS
Yea, I kinda rushed through it, and didn't fully think it out, but I got it now.
I'll post it if needed.

Thx for everyone helping , i have it working now.
i forgot to say at the beginning of this thread that my programming skills are just the very basic, so for me it’s a big achievement that i even managed to get this to work. :grin:

here is the code that i have used.
Arduino code:

    #define redLED 6
    #define blueLED 5
    char new_buffer[4];
   
 
     void setup()
     {
      // put your setup code here, to run once:
      Serial.begin(9600);
      pinMode(redLED, OUTPUT);
      pinMode(blueLED, OUTPUT);
     
    }
     
    void loop()
    {
         char buffer[4];
         
    if(Serial.available() > 4)
    {
      for(int i = 0; i <4 ;i++){
        buffer[i] = Serial.read();
      }
      if(buffer[0] == '<' && buffer[3] == '>'){
        for( int i = 0; i < 4; i++){
          new_buffer[i] = buffer[i];
          
        }
      }
    }
   analogWrite(redLED, new_buffer[1]);
   analogWrite(blueLED,new_buffer[2]);
    
}

Processing code:

public void draw(){
  
  background(230); 
  
  sliders[0] =(char) redSlider.getValueI();
  sliders[1] =(char) blueSlider.getValueI();
//this is were the data is send over serial com port.
  port.write('<');
  port.write(sliders[0]);
  port.write(sliders[1]);
  port.write('>');
  

}

I got this to work.
(The variables were more for me when I made them)

int buffer[8];
char buf[10];
int counter = 0, Scount=0;

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

void loop() {
  if(Serial.available() > 0){
    char temp = Serial.read(); // example incomming data <1,23,456,7890>
    if( temp == '<' ) 
    { 
      while(1){
        if(Serial.available() > 0){
          char temp = Serial.read();
          if(temp != ',' && temp != '>') {
            buf[Scount] = temp;
            buffer[counter] = atoi(buf); // converts buf into an int
            Scount++;
          }

          if(temp == ',') {
            while(Scount != 0) //clear buf for new numbers, sets Scount back to 0
            {
              buf[Scount] = 0; 
              Scount--;
            }
            counter++; 
          }

          if(temp == '>'){  
            break; // breaks out of the while loop
          }
        }
      }
    }
    /*for(int NUM=0; NUM <= counter; NUM++) //will output "1,23,456,7890"
     {
     Serial.print(buffer[NUM]);
     if(NUM != counter) Serial.print(",");
     }
     Serial.println();*/
  }

  while(counter != 0) {
    buffer[counter] = 0; 
    counter--;
  }
  while(Scount != 0) {
    buf[Scount] = 0; 
    Scount--;
  }
}