Serial and mixed up characters

Status
Not open for further replies.

nlecaude

Well-known member
Hello,

I'm working on a system where I have some stations that are a couple meters apart. I'm using Teensys and Xbee 802.15.4 for communication.
I have a master xbee that sends broadcast to the other xbees that are receivers (and never send anything back)
At the moment I'm sending an array of bytes using Serial1.write(buffer, length) and on the receiving side I'm using Serial.readBytes(buffer, length)
The problem I have is that if I power the sender first and the receivers last, the byte order seems to get mixed. Same happens if I shut down one of the receivers briefly and power it back on, it seems to loose track of the correct order.
Is there a way around this ? More specific code here:

That's my send code (I currently send a 2 byte array)
Code:
Serial1.write(frame, 2);

And this is on the receiving side:
Code:
  byte frame[2];
  
  if (Serial1.available() == 2)
  {
    Serial1.readBytes(frame, 2);
  }
 
You are sending bytes in pairs, but if the receiver misses the 1st byte, it'll just combine #2 & #3 etc -- this looking like it is offsetting them.

When you start a serial link like this, it's best to have the receiver send out "I'm here" messages until it gets an "I see you" message or the start of data from the transmitter. The transmitter should not start sending data until it sees the "I'm here" message. If your data can be arbitrary, if may be difficult for the receiver to distinguish and "I see you" message from the start of data.

The "I'm here" can just be 0xAA bytes.

So the transmitter code is like this:
while (didn't get a AA) ; // do nothing
...
now send the 'good' data....

The receiver is:
while(nothing received) send AA;
wait for "I see you"
...
read 'good' data
 
Thanks. That could be a good thing to implement indeed. My concern however is that if the receiver looses power or contact for a short period then it stops working. I would need to find a way to have the receiver catch up in those situations.
 
You probably need to add a little more handshaking. Many ways to do it. Here are a couple that I use...

Arbotix Commander(Trossen Robotics): The remote sends out a fixed length packet: The first byte is an 0xff, the next four bytes is the joystick data, that they restrict such that they can not have a value of 0xff, a byte of buttons and an extra byte (0), followed by a checksum byte. The receiving side reads until it gets an 0xff, then reads in the packet data with a short timeout and then check your data that the checksum is correct. Note: depending on what your code is doing there is a potential to overrun hardware buffers, so need to check that as well.

DIY Remote control: Similar types of data sent, except my remote currently has joysticks with 3 analog inputs, plus sliders, plus more button data... With these I put the XBees into Packet mode, so the XBees themselves verify the data is sent... On receiving side however you still have to do some verification. In particular keep reading until you get an 0x7e (packet start), need to then read in next two bytes which is a length, and make sure they look reasonable... A lot of this checking does not need to happen if your code is fast enough to keep up with the transmitter, but ran into issues where I was sending something like 40 packets per second, to one of my hexapods, who are walking through a gait engine...

Kurt
 
Code:
  if (Serial1.available() == 2)
This is not a good idea. what if you have received 4 bytes? You'd never read any more chars.
Use this:
Code:
  if (Serial1.available() >= 2)

Pete
 
Code:
  if (Serial1.available() == 2)
This is not a good idea. what if you have received 4 bytes? You'd never read any more chars.
Use this:
Code:
  if (Serial1.available() >= 2)

Pete

Thanks, yes I changed that. I think I might go the OSC route instead as I assume it will take care of the kind of issue for me...
 
Status
Not open for further replies.
Back
Top