Handshaking problem

Hi everyone,

I have written a simple code that sends some information to the arduino and I have added some handshaking. The problem is that it works 80% of the time. The arduino send the character "/" and the (lets say another arduino for simplicity) send throttle roll pitch yaw.

Like so:

Arduino 1

if (input == '/')
ons.write(THROTTLE);
      ons.write(ROLL);
      ons.write(PITCH);
      ons.write(YAW);
      ons.write(AUX1);

Arduino 2

Serial.write('/')
Throttle = Serial.read(THROTTLE);
Roll = Serial.read(ROLL);
Pitch = Serial.read(PITCH);
Yaw = Serial.read(YAW);
Aux1 = Serial.read(AUX1);

I know this code isnt gonna compile but you get the idea. The problem is that sometimes the channels get mixed up (like throttle reads roll). Oh and I should add there is a delay of 100 milliseconds between sending data.

So my question is what would be a better handshaking method?

So my question is what would be a better handshaking method?

The problem isn't with handshaking. The problem is with your assumption that serial data delivery is guaranteed. It is not.

There may be further problems if the values you are sending are not byte sized. The snippets you posted leave a lot to be desired.

By the way, there is a convention that all capital letter names are constants. In your snippets, it hardly makes sense for THROTTLE, etc. to be constants.

Serial is not as easy as just sending strings over. The strings you send get converted to ASCII and thus it is possible that you have error.

This is a common issue and there is code on this site below that addresses these issues:

http://www.inventige.com/arduino-reading-serial-input-with-commands-and-numbers/

Hi,

I have had some success with the "Serial.find()" function, it works a treat for me when trying to pick up a character or a string and then act upon that when you get it!

Serial is not as easy as just sending strings over. The strings you send get converted to ASCII and thus it is possible that you have error.

There are no strings involved in OP's case. OP is using Serial.write() to send binary data.

The problem isn't with handshaking. The problem is with your assumption that serial data delivery is guaranteed. It is not.

Ah huh! So thats the problem :slight_smile:

By the way, there is a convention that all capital letter names are constants. In your snippets, it hardly makes sense for THROTTLE, etc. to be constants.

I didnt know that. I just wrote it with capitals to make it clearer to me.

Gammon Forum : Electronics : Microprocessors : How to process incoming serial data without blocking

Thank you Thank you Thank you

Also thanks to all the other responses

Ok I ran onto another problem. If I lose the connection, the arduino doesnt know it and it continues to send the previous values stored. Now I want to keep these vlues and not set them all to zero at each loop. I thought that simply writing this would work:

if((!Serial.available() >  0)  && delaytime > 500){
do something

However, that never happens. Before you ask, yes I have verified that delaytime is incremented. What would be the approach to knowing when the connection is lost and doing this without adding extra code on the sending arduino side?

However, that never happens.

What never happens? Serial.available() never returns 0? Never returns non-zero? millis() never exceeds delaytime?

Before you ask, yes I have verified that delaytime is incremented.

Great. Show us where, though.

What would be the approach to knowing when the connection is lost and doing this without adding extra code on the sending arduino side?

If there is no data coming in, for some period of time, you can assume that the connection was lost.

What I mean is the if is never true. I have set it to a led and it never turns on. Curious thing is that if i put only the serial.available an not the delay, the led turns on. Also if I set the delay in the same sceth to blink the led, it does it properly. So my question is why don't they work together(like in the code suggested before)?

Theelectronicguy:
I thought that simply writing this would work:

if((!Serial.available() >  0)  && delaytime > 500){

do something

I find that code mildly disconcerting. Could you post your actual code, not some sort of "this is sort-of what it does" code? Like, "do something" is not valid C.

Ok well basically I would appreciate an example of what kind of code should be written because I have no idea :P. Lets say I want the arduino to turn the led ON when the serial connection has failed for more than 1 second(aand off when the connection has been established). This is my current code:

#include <Servo.h> 
 
Servo Throttle;  // create servo object to control a servo 
Servo Roll;
Servo Pitch;
Servo Yaw;
Servo Aux1;

int throttle;
int roll;
int pitch;
int yaw;
int aux1;


long previousMillis = 0;


void setup() 
{
  Throttle.attach(2);  // attaches the servo on pin 9 to the servo object 
  Roll.attach(3);
  Pitch.attach(4);
  Yaw.attach(5);
  Aux1.attach(6);
  Serial.begin(115200);
  throttle = 0;
  roll = 90;
  pitch =90;
  yaw = 90;
  aux1 = 0;
} 
 
void loop() 
{
  switch(GetFromSerial()){
    
    case 'T':
    throttle = (GetFromSerial() + 45);
    break;
    case 'R':
    roll = (GetFromSerial() + 45);
    break;
    case 'P':
    pitch = (GetFromSerial() + 45);
    break;
    case 'Y':
    yaw = (GetFromSerial() + 45);
    break;
    case 'A':
    aux1 = (GetFromSerial() + 45);
    break;
    
  }
  long currentMillis = millis();
  if(currentMillis - previousMillis > 50) {
  Throttle.write(throttle);
  Roll.write(roll);
  Pitch.write(pitch);
  Yaw.write(yaw);
  Aux1.write(aux1);
  
  previousMillis = currentMillis;
}
}
int GetFromSerial() {
  while (Serial.available()<=0) {
  }
  return Serial.read();
}

Thank you

Something like this?

#include <Servo.h> 

Servo Throttle;  // create servo object to control a servo 
Servo Roll;
Servo Pitch;
Servo Yaw;
Servo Aux1;

int throttle;
int roll;
int pitch;
int yaw;
int aux1;

const byte errorLED = 13;
unsigned long lastSerialData = 0;

long previousMillis = 0;


void setup() 
{
  Throttle.attach(2);  // attaches the servo on pin 9 to the servo object 
  Roll.attach(3);
  Pitch.attach(4);
  Yaw.attach(5);
  Aux1.attach(6);
  Serial.begin(115200);
  throttle = 0;
  roll = 90;
  pitch =90;
  yaw = 90;
  aux1 = 0;

  pinMode (errorLED, OUTPUT);
} 

void loop() 
{

 switch(GetFromSerial ())
   {
  
    case 'T':
      throttle = (GetFromSerial() + 45);
      break;
    case 'R':
      roll = (GetFromSerial() + 45);
      break;
    case 'P':
      pitch = (GetFromSerial() + 45);
      break;
    case 'Y':
      yaw = (GetFromSerial() + 45);
      break;
    case 'A':
      aux1 = (GetFromSerial() + 45);
      break;
  
    }  // end of switch
  
  long currentMillis = millis();
  
  if(currentMillis - previousMillis > 50)
    {
    Throttle.write(throttle);
    Roll.write(roll);
    Pitch.write(pitch);
    Yaw.write(yaw);
    Aux1.write(aux1);
    previousMillis = currentMillis;
    }
}

int GetFromSerial() 
  {
  // wait until we have some serial data
  while (Serial.available() == 0) 
    {
    // turn LED on if 1 second has elapsed
    if (millis () - lastSerialData > 1000)
      digitalWrite (errorLED, HIGH);
    }

  lastSerialData = millis ();
  digitalWrite (errorLED, LOW);

  return Serial.read();
  }
      throttle = (GetFromSerial() + 45);

45? What does adding a '-' or 45 to the serial byte accomplish?

Something like this?

Yes thank you I just couldnt get my head around how (and where) to put the lastreceiveserial. Thank you for the example, Ill try it now.

45? What does adding a '-' or 45 to the serial byte accomplish?

Well, to control the quadcopter, I had to send servo values between 45 and 141 so 141 was over the 128 byte value limit(and I can't send unsigned bytes from android processing i think). This also prevents negative values. I guess I could of put it like this instead:

return (Serial.read() + 45);

I hope I can get this quad in the air soon. :slight_smile: