Go Down

Topic: Having problems with Serial Communication on FIO (Read 1 time) previous topic - next topic

PaulS

Quote
So in the processing code, I am sending the values in an array (19 of them) as bytes. All of them are less than 255, does this mean that I will be sending 19 bytes

Just because the values fit in a byte does not mean that only one byte will be sent. The number of bytes actually sent depends on the data type in Processing. Need to see some code...

Quote
I tried the code below, and when it printed the data, it was not the data I expected.

Then, it is likely that Processing is not sending just 19 bytes. See above.

Quote
Also, probably a silly question, but if I Serial.print, will it mess up the data in the Serial buffer?

Not silly at all. Still, the answer is no. The send functions (print, println, and write) have no affect on the input functions or the buffer used to hold unread data.

Quote
I flushed the Serial buffer at the end.

So, you discarded random amounts of unread data. Was this really what you wanted to do?

Quote
Should I write back to Processing with a known value and then when received send a new stream of data?

Maybe, maybe not. It depends on when/why Processing is sending data, and whether the Arduino can keep up with the data at the rate Processing is sending it. If it can't, then handshaking (which is what your proposal is called) will be useful/necessary.

Code: [Select]
if (Serial.available() >= 19) {
   
    buff[1] = Serial.read();
    buff[2] = Serial.read();
    for (int i=0; i<buff[2]; i++) {
      buff[i+3]=Serial.read();     
    }     

This code could read more than 19 bytes or less than 19 bytes. You should be waiting for/reading the number of bytes defined by buff[2].

Why are you starting to store data in buff[1] instead of buff[0]?

I think we need to see the Processing code and all of the Arduino code.

mattschoenholz

#6
Aug 06, 2011, 06:54 pm Last Edit: Aug 06, 2011, 07:16 pm by mattschoenholz Reason: 1
Thanks, I appreciate the guidance (and not providing the answer but pointing me in the right direction. After looking at the approach here, I realized I needed to simplify the start and end bits to a single character and then check for each of these. I am now sending a '[' and ']' for the start and end string and then a 'L' or 'M' for the LED or Motor Control.

PaulS I also saw a recent post on Serial communication using the 'started && ended' approach with a while statement. This was super helpful for guidance as well.

Here is the code that is working right now! Yay!
Code: [Select]

void loop() {
 while(Serial.available() > 0)
 {
   char inChar = Serial.read();
   if(inChar == '[') // check for the opening character
   {
     started = true;
     index = 0;
     inData[index] = '\0';
   }
   else if(inChar == ']') // check for the end character
   {
     ended = true;
     break;
   }
   else
   {
     if(started && index < 19) // process all the bits in between
     {
       inData[index++] = inChar;
       inData[index] = '\0';
     }
   }
 }

 if(started && ended)
 {
   if (inData[0] == 'L'){ // process all the data for the LED control. Use the 15 bits 3-17 for the 5 RGB LEDs.
       if(debug) Serial.println("LED");
       Tlc.set(0, inData[3]);
       Tlc.set(1, inData[4]);
       Tlc.set(2, inData[5]);
       Tlc.set(3, inData[6]);
       Tlc.set(4, inData[7]);
       Tlc.set(5, inData[8]);
       Tlc.set(6, inData[9]);
       Tlc.set(7, inData[10]);
       Tlc.set(8, inData[11]);
       Tlc.set(9, inData[12]);
       Tlc.set(10, inData[13]);
       Tlc.set(11, inData[14]);
       Tlc.set(12, inData[15]);
       Tlc.set(13, inData[16]);
       Tlc.set(14, inData[17]);
   }
   else if(inData[0] == 'M'){
         if(debug) Serial.println("Motor");
         analogWrite(MOTOR_ENCODER, inData[2]);
         digitalWrite(L_MOTOR_DIR, inData[3]);
         digitalWrite(L_MOTOR_PWM, inData[4]);
         digitalWrite(R_MOTOR_DIR, inData[5]);
         digitalWrite(R_MOTOR_PWM, inData[6]);
         digitalWrite(V_MOTOR_DIR, inData[7]);
         digitalWrite(V_MOTOR_PWM, inData[8]);
       
   }
   if(debug){
     for(int i=1; i<17; i++) { // print the data bits (excluding the '[' and ']'
       Serial.println(inData[i]);
     }
   }

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

 Tlc.update(); // send all data to the TLC through the update function
 delay(100);  
}

And here is the processing code:
Code: [Select]

void sendCommand(int ardCtrl){
// this function will take supplied variables and package and send to arduino
 mySerial.clear(); //clear the serial buffer at the start of the function
 if(debug) println("send command function called");
 byte[] pass2ard = new byte [19];
 if(ardCtrl == 1){  
   pass2ard[0] = byte('['); //start
   pass2ard[1] = byte('L'); //led control
   pass2ard[2] = byte(15);
    for(int l=0; l<=colorLED.length-1; l++){
      color currColor = color(unhex(colorLED[l]));
      println(currColor);
      int cPos = (l*3)+3;
      int r = (currColor >> 16) & 0xFF;  // Faster way of getting red
      int g = (currColor >> 8)& 0xFF;   // Faster way of getting green
      int b = currColor & 0xFF;          // Faster way of getting blue
      pass2ard[cPos] = byte(r);
      pass2ard[cPos +1] = byte(g);
      pass2ard[cPos +2] = byte(b);
      }
   pass2ard[18] = byte(']'); //end string
   //the array that is sent to arduino should look like this "[, L, 15, X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, ]" - where X is a value

 } else if (ardCtrl == 2){
     pass2ard[0] = byte('['); //start
     pass2ard[1] = byte('M'); //motor control
     pass2ard[2] = byte(7);
     for(int l=0; l<=6; l++){
       pass2ard[l+3] = byte(motors[l]);
     }
     pass2ard[10] = byte(']'); //end string
     //the array that is sent to arduino should look like this "[, M, 6, X, X, X, X, X, X, ]" - where X is a value
 }

  mySerial.write(byte(pass2ard[0])); //the second byte is the command.
  delay(40); // send the start string byte to arduino and wait until response come

  for (int i=1;i<pass2ard.length;i++){
      mySerial.write(byte(pass2ard[i]));
      println(i + ": " + pass2ard[i]);
      delay(40);
 }
  sendComd = 0; // set the trigger to zero if successful
  println("end of function");
}


Thanks again! Now on to debugging the hardware!

PaulS

Quote
Thanks, I appreciate the guidance (and not providing the answer but pointing me in the right direction.

I think that if put some effort into finding the answer, you will better understand the answer, as well as why it is the answer, than if you are just given an answer.

When you know why something works, you have another tool that you can adapt. If you know something works, but not why, you have no idea whether that thing can be adapted for another purpose.

So, I prefer to provide some clues, rather than complete code. If you get stuck, or need a bigger clue by four, I'm happy to provide code, and explanations.

In your case, though, you probably won't make any more mistakes in reading and using serial data, now that you understand the hows and whys and limitations. Not everyone else is there, yet.

Quote
Now on to debugging the hardware!

And learning to post code properly... See the # button?

AWOL

Quote
I think that if put some effort into finding the answer, you will better understand the answer, as well as why it is the answer, than if you are just given an answer.

I think that should be framed - thanks Paul
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

PaulS

Quote
I think that should be framed

Well, maybe if I'd proofread it first... There is a missing "you" in the first sentence.


Go Up