Problem with Arduino Serial Communication

Austin Clark

Joined Dec 28, 2011
412
Try keeping the connection alive from beginning to end. You don't have to physically disconnect them to trigger the Arduino reset. I'm not great at C and I can't really tell if your PC-side code does this. If you're only receiving part of the response you're expecting, perhaps you're reconnecting after sending "Hello?" instead of staying connected throughout, causing the Arduino to reset mid-response.
You might try temporarily disabling auto reset to see if that helps: http://playground.arduino.cc/Main/DisablingAutoResetOnSerialConnection
 

THE_RB

Joined Feb 11, 2008
5,438
The only reason that I connect and reconnect is when I test after changing something in the code.
Its just a mild annoyance to have to mess with starting both ends at the same time.
It's asynchronous serial. You should never have to "start both ends at the same time".

How do you handle timeouts, and periods between data packets?

And framing error means when the receive starts at the wrong time compared to the transmit, so it thinks one of the data 0 bits is the start bit.

That's why it needs to resync using pauses between data packets, and why it reall yhelps to use 8N2 for the TX because the two stop bits allow it to resync on the fly (and tolerate a larger baudrate mismatch by re-syncing on each new byte).
 

djsfantasi

Joined Apr 11, 2010
9,163
Something bothers me about your programs. It looks as if they assume that all six bytes are available almost simultaneously. If there is a slight pause between characters, serial.available() will return false and you will fall out if your read loop with a partial result.

I'd code it so that it loops until a termination character is received. Your defined protocol has ! or ? as an end of input character. I'd loop until this character is received, reading characters when available and waiting for characters to become available when there is nothing to read. (If you need to, you can perform other work while waiting for characters.) This is a simple explanation; a robust solution would also have to allow for a timeout period.

As is, you assume all six characters are available when the first one is. If this is the case, it has nothing to do with latency, framing, resetting communication or starting one program before another.
 

Thread Starter

kurtruk

Joined Aug 26, 2012
140
Try keeping the connection alive from beginning to end. You don't have to physically disconnect them to trigger the Arduino reset. I'm not great at C and I can't really tell if your PC-side code does this. If you're only receiving part of the response you're expecting, perhaps you're reconnecting after sending "Hello?" instead of staying connected throughout, causing the Arduino to reset mid-response.
You might try temporarily disabling auto reset to see if that helps: http://playground.arduino.cc/Main/Di...rialConnection
I tried this however I only had a 110 ohm resistor not 120. But it did not cause any difference.

How do you handle timeouts, and periods between data packets?
I use stuff such as while(!Serial.Available());

And framing error means when the receive starts at the wrong time compared to the transmit, so it thinks one of the data 0 bits is the start bit.
Could be that; when it doesn't work I receive something that isn't quite a byte or an int.

That's why it needs to resync using pauses between data packets, and why it reall yhelps to use 8N2 for the TX because the two stop bits allow it to resync on the fly (and tolerate a larger baudrate mismatch by re-syncing on each new byte).
I am using 2 stop bits; doesn't help any.

Something bothers me about your programs. It looks as if they assume that all six bytes are available almost simultaneously. If there is a slight pause between characters, serial.available() will return false and you will fall out if your read loop with a partial result.
Currently I'm using this code:
Rich (BB code):
while(!Serial.available());   //wait for input
  delay(1);
  char incomingString[6] = {0,0,0,0,0,0};
  while (Serial.available()==6)    //wait for buffer to recieve all of incoming string
    for(int i=0;i<6;i++){
      incomingString = Serial.read();
    } 

This waits for all 6 bytes to be in the buffer before reading them.
I'd code it so that it loops until a termination character is received. Your defined protocol has ! or ? as an end of input character. I'd loop until this character is received, reading characters when available and waiting for characters to become available when there is nothing to read. (If you need to, you can perform other work while waiting for characters.) This is a simple explanation; a robust solution would also have to allow for a timeout period.

As is, you assume all six characters are available when the first one is. If this is the case, it has nothing to do with latency, framing, resetting communication or starting one program before another.
I'm working on something like this however I doubt it will make a differance.
 

kubeek

Joined Sep 20, 2005
5,795
...Currently I'm using this code:
Rich (BB code):
while(!Serial.available());   //wait for input
  delay(1);
  char incomingString[6] = {0,0,0,0,0,0};
  while (Serial.available()==6)    //wait for buffer to recieve all of incoming string
    for(int i=0;i<6;i++){
      incomingString = Serial.read();
    } 
This waits for all 6 bytes to be in the buffer before reading them.
Nope, it doesnt quite do that. It checks whether the Serial.available() function has anything that you could read. But what if it has obtained more than 6 bytes to read before the code could check it? Then you would be waiting forever before the nuber was 6 again.
 

djsfantasi

Joined Apr 11, 2010
9,163
Rich (BB code):
while(!Serial.available());   //wait for input
  delay(1);
  char incomingString[6] = {0,0,0,0,0,0};
  while (Serial.available()==6)    //wait for buffer to recieve all of incoming string
    for(int i=0;i<6;i++){
      incomingString = Serial.read();
    }



I don't think this will wait as your comment seems to indicate. When execution reaches your while statement, it will wait only when six characters are available. If there are less than six characters available, execution falls through and you read six characters. But, there is a good possibility that less than six characters are there! I think you mean to wait in the while loop, when less than six characters are available or when the number of characters is not equal to six.

Update: I may have missed a semicolon, but the logical execution that results still does not wait until six characters are available.
 

Thread Starter

kurtruk

Joined Aug 26, 2012
140
i should be while(!Serial.available()==6);

but knowing that still might give problems I changed code once again.

Rich (BB code):
void DisplayArduinoClass::confirmSerialConnection(){
  char incomingString[6] = {0,0,0,0,0,0};
  int i=0;
  while(!Serial.available());   //wait for input
  delay(1);
  while (Serial.peek()!= 'e'){   //read until termination character
    incomingString[i++] = Serial.read();
  }
  Serial.read();  //read off termination character

  if (incomingString [0] == 'H' && incomingString [1] == 'o' && incomingString [2] == 'l' && incomingString [3] == 'a' && incomingString [4] == '?'){
    Serial.write("Hola!"); 
  }
}
I am using the char e as a termination character since "Hello" has and e in it My process now goes like this:
Computer: Hola?e
Arduino: receive until 'e'
Arduino: did I receive Hola?
Arduino if so send Hola!
Computer: did I receive Hola!
if so connection successful.

this works, but both ends "need to be started at the same time".
 

djsfantasi

Joined Apr 11, 2010
9,163
The dreaded "need to be started at the same time". I agree with THE_RB in post #22, it asynchronous communications. "Starting at the same time" should not be the case. Something else is up.
 

THE_RB

Joined Feb 11, 2008
5,438
Something bothers me about your programs. It looks as if they assume that all six bytes are available almost simultaneously. If there is a slight pause between characters, serial.available() will return false and you will fall out if your read loop with a partial result.
...
Agreed, there seems to be something funky about the way packets of 6 bytes are synchronised.

If the 6 byte packets are separated by time (and not some special character or other condition), then you need to detect a timeout period of >X mS where there are no received bytes, then reset the variables ready to receive a packet, then get the 6 bytes.
 
Top