Help with Bluetooth Data code

I am trying to control a robotic arm using the VarSpeedServo library. Im using a JY-MCU BT module with an UNO. I'm also using App Inventor to send the BT data. AI seems to be sending the data fine and motors work ok for a time. The problem Im having is sometimes when the 1st byte of data in the buffer is not that initial variable, its usually the last byte from previous packet. (Example; sometimes the Serial Monitor will show the dec value for the variable 'lastbyte' then jointservo, xval, etc down to speedval) So then I find myself in a cycle where the data the UNO is receiving according to the Serial monitor is 7,1,2,3,4,5,6 and the only way to fix is to restart the UNO. Can someone chime in what Im doing wrong?

void setup() {
 pinMode(ledpin, OUTPUT); 
 PanServo.attach(10);
 TiltServo.attach(11);
 BaseServo.attach(9);
 Serial.begin(9600);
 
}

void loop() {
    if (Serial.available() > 6) {
      if (Serial.available() == 7){
        
      jointservo=Serial.read();
      xval=Serial.read();
      delimiter1=Serial.read();
      yval=Serial.read();
      delimiter2=Serial.read();
      speedval=Serial.read();
      lastbyte=Serial.read();
      //Serial.flush(); 
      Serial.println(jointservo);
      Serial.println(xval);
      Serial.println(delimiter1);
      Serial.println(yval);
      Serial.println(delimiter2);
      Serial.println(speedval);
      Serial.println(lastbyte);
      Serial.println("\n");

      
      if (jointservo == 'W'  && lastbyte == 'E')
      PanServo.slowmove(xval, speedval);
      TiltServo.slowmove(yval, speedval);
      }
      else if (jointservo == 'B' && lastbyte == 'E') {
       BaseServo.slowmove(yval, speedval);
       digitalWrite(ledpin, HIGH);
      }
      else if (jointservo == 'C' && lastbyte == 'E'){
       PanServo.slowmove(yval, speedval);
      }
       else{
        Serial.flush();
       }
    }
      Serial.flush();
    
    }

Can someone chime in what Im doing wrong?

Many things.

    if (Serial.available() > 6) {
      if (Serial.available() == 7){

If there are more than 6 bytes to read, why is the fact that there might be part of a second packet available to read a problem? Ditch the second if statement. More than 7 characters to be read is NOT a problem.

      jointservo=Serial.read();
      xval=Serial.read();
      delimiter1=Serial.read();
      yval=Serial.read();
      delimiter2=Serial.read();
      speedval=Serial.read();
      lastbyte=Serial.read();

This looks like you are expecting to read binary data. The Serial Monitor does NOT send binary data. It sends ASCII data - characters.

It is reading the commas in your string, too.

If you send "7,1,2,3,4,5,6", and expect that to be the 7 values you want to read, you are sadly mistaken. That is 13 characters. The code will only execute when "7,1,2,3" has arrived, and you are storing '7' in jointservo (not 7). You are storing ',' in xval. I can't imagine what sending the servo to ',' will actually do.

       else{
        Serial.flush();
       }
    }
      Serial.flush();

Wait until all pending outgoing data has been sent. Since you are not sending any data, why the f**k are you calling this function?

In the old meaning of this function, "Throw away random amounts of unread data", again I have to ask why the f**k would you want to do that?

PaulS:
If there are more than 6 bytes to read, why is the fact that there might be part of a second packet available to read a problem? Ditch the second if statement. More than 7 characters to be read is NOT a problem.

      jointservo=Serial.read();

xval=Serial.read();
      delimiter1=Serial.read();
      yval=Serial.read();
      delimiter2=Serial.read();
      speedval=Serial.read();
      lastbyte=Serial.read();




Im not looking for binary data, Im assigning each of the 7 bytes received to a variable, then checking the jointservo and lastbyte variables against what AI sent to make sure the packet is complete, then parsing xval, yval and speedval. 



If you send "7,1,2,3,4,5,6", and expect that to be the 7 values you want to read, you are sadly mistaken. That is 13 characters. The code will only execute when "7,1,2,3" has arrived, and you are storing '7' in jointservo (not 7). You are storing ',' in xval. I can't imagine what sending the servo to ',' will actually do.


I'm not trying to send "7,1,2,3,4,5,6" I was saying that's the order in which the elements are showing in the SM. So the SM shows the value sent as 'lastbyte' is seen as the 1st element read in the buffer, assigned to 'jointservo' then the value for jointservo is seen as element 2, assigned to xval. xval is value 3, etc.




else{
        Serial.flush();
      }
    }
      Serial.flush();



Wait until all pending outgoing data has been sent. Since you are not sending any data, why the f**k are you calling this function?

In the old meaning of this function, "Throw away random amounts of unread data", again I have to ask why the f**k would you want to do that?

I am reading the data, collecting the 7 bytes I need and flushing out the rest in the buffer before restarting the loop. I dont see the problem. ?

Im not looking for binary data

Bummer, because that is that you are sending. You are not sending what you initially said you were sending.

I am reading the data, collecting the 7 bytes I need and flushing out the rest in the buffer before restarting the loop. I dont see the problem. ?

The flush() method affects the outgoing serial buffer, not the incoming serial buffer.

Even if it affected the incoming serial buffer, it makes no sense to dump random amounts of unread data.

One of the issues you are not dealing with is that fact that serial data delivery is NOT guaranteed. If a byte gets lost, you WILL get out of sync. Sending 0xFF is NOT a good idea, for a sync bit, because ALL of the values in a byte are valid values.

Sending ASCII data, with specific start and end markers, and the expected number of bytes, and a checksum is the only way to assure that what was sent is what was received. Parsing the ASCII data is trivial. It IS slower, but it is the only way to write robust communications code.

Of course, if speed was an issue, you wouldn't be using 9600 baud.

PaulS:

Im not looking for binary data

Bummer, because that is that you are sending. You are not sending what you initially said you were sending.

Here's is the command to home the the Pan/Tilt servos:
'W' 90 ',' 90 ',' 20 'E'
Here's what the Serial Monitor is showing:
87 90 44 90 44 20 69
At this point everything works fine. How can I change my code so I can avoid this:
69 87 90 44 90 44 20?

I am reading the data, collecting the 7 bytes I need and flushing out the rest in the buffer before restarting the loop. I dont see the problem. ?

The flush() method affects the outgoing serial buffer, not the incoming serial buffer.

I did not know that. So there is no buffer for incoming data?

Even if it affected the incoming serial buffer, it makes no sense to dump random amounts of unread data.

One of the issues you are not dealing with is that fact that serial data delivery is NOT guaranteed. If a byte gets lost, you WILL get out of sync. Sending 0xFF is NOT a good idea, for a sync bit, because ALL of the values in a byte are valid values.

Should I use a 2byte number over 255 to fix this issue?

Sending ASCII data, with specific start and end markers, and the expected number of bytes, and a checksum is the only way to assure that what was sent is what was received. Parsing the ASCII data is trivial. It IS slower, but it is the only way to write robust communications code.

Right now my start marker is the joint of the robot arm (B,E,W) and end marker is 'E' What do you mean by checksum?

Of course, if speed was an issue, you wouldn't be using 9600 baud.
This is the default speed for this BT module, I'll change it when I figure out how to change the module's speeed.