views:

154

answers:

2

I have a java program that continually listens for messages of a certain format on a serial port. When the sender application is not sending messages, it sends heartbeat messages in the following format:

byte 1: 1 byte 2: 0xFE byte 3: 0xED bytes 4-255: 0

If the receiver application is started before the sender, everything functions correctly, however, if the sender has been throwing down heartbeats, it's almost certain that the receiver, when started, will begin listening in the middle of a heartbeat message (which is a problem because I read in chunks of 255 bytes as each message is Reed-Solomon encoded). I wrote a synchronizing function that's a simple state machine. It reads 1 byte at a time with the following conditions:

If I just read a 1: switch to the NEW_MESSAGE state.

If I just read a 0xFE: switch to the POTENTIAL_HEARTBEAT state.

If I just read a 0xED: switch to the HEARTBEAT state

Relevant checks are in place to ensure that these states cannot be arrived upon out of order, and once I've reached the HEARTBEAT state, I read the remaining 252 0's and assume the receiver has been synchronized. In testing so far, this synchronizer has not worked correctly despite the correct bytes being sent down to effectively trigger a synchronization. My question is this: is there a better way to synchronize serial communications, because I really don't like my method at all.

Thanks in advance for any help.

A: 

Extend your state machine and check for the last 3 received bytes. Comapre them to the first 3 bytes of your heartbeat message. As the first 3 bytes seems to be always the same, you can use this to detect the beginning of the heartbeat message and do your sync.

Alex
I have to read 1 byte at a time as there is no way of knowing where within a particular heartbeat message I start reading. For example, say I start reading the following bytes:0 0 0 0 0 1 FE ED 0 0 0If I read 3 bytes at a time, I'll get [0,0,0] [0,0,1] [FE,ED,0] ... and miss the heartbeat entirely.
JDS
@Alex, his FSM is already checking the last 3 received bytes, by virtue of having three distinct states (which I assume are in addition to the IDLE state).
Jim Garrison
A: 

The problem was actually just me forgetting the importance of bit ordering. The byte channel I was reading from was little endian so the 16 bit integer 0xFEED was coming to me as 0xED 0xFE instead of 0xFE oxED. With a simple switch in the state checking, everything works peachy king.

Sincere thanks to all that commented.

JDS