Comm Protocol

Go To Last Post
4 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

This is for a atmega168 at various baudrates(38400, right now)

I have a spec for a Comm protocol.
It is an STX char, 32 bytes then a CR character. With various fields in the 32 characters.

Right now I am just running a loop that checks for the STX char then saves the next 32 chars to an array as the data comes in. I skip the CR and look for the next STX char.

It works ok but I run into issues where it get out of sync and that messes everything up.

Any one have a more proven Comm protocol that I would help with reliability.

Thanks

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yeah, I avoid using all characters in my protocols. Usually I make stuff that has to be used by people, so my protocols are like:

!nCDDDDDDDDcc\n

where
! is the start sig.
n is the name of the device ('a' - 'z', '0' - '9', 'A' - 'Z', '*' for all.
C is the packet type (for instance Move forward has an F in this place)
DDDDDD... are the data bytes in hex. While not very efficient (1byte sent = 0.5byte of data), it is human readable, and avoids a lot of problems.
CC - CRC8 checksum. If the checksum is wrong, a packet with the correct one is sent back to the user.

There are pointy haired bald people.
Time flies when you have a bad prescaler selected.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I assume STX and CR can never be part of the data. Then build a small state machine.

You start with a "no sync" state. The state is only to be left on the reception of an STX. Then you transition to a "start of text" state.

Every appearance of an STX returns you to the "start of text" state. On entry into that state the current received buffer is thrown away. If it wasn't empty you probably send an error message.

There are at least the following ways to leave the "start of text" state:

(a) A CR is received. You go into an "end of text" state. See further down

(b) A normal character is received. On reception of a normal character you leave the "start of text" state and go into a "message incomming" state. The character is put into the received buffer, and the character counter is increased. Following normal characters are added to the buffer and the counter is further increased. There are (at least) three ways to leave the "message incomming" state:

(1) An STX is received. You got back to the "start of text" state. Probably also sending an error message.

(2) A CR is received. You go into an "end of text" state. See further down.

(3) If the buffer exceeds 32 characters you transition to the "no sync" state.

On entry from (a) or (2) into the "end of text" state, you check is the character count in the buffer is exactly 32. If not, you immediately transition to the "no sync" state, probably with an error message "data to short". If you have exactly 32 characters then you forward the buffer to the message parser. Once the message is parsed you also transition to the "no sync" state.

Stealing Proteus doesn't make you an engineer.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

My 2 pence:

I prefer to search for the Stop character instead of the Start character. This makes a very simple re-sync mechanism possible.

Assume you have a circular receive buffer that is bigger than the longest message you can receive. Just add one byte after another to the buffer, don't care if you overwrite old bytes in the buffer.

As soon as you find the stop byte you can verify the content of the buffer:

a) from the first position in the circular buffer, discard all bytes until the buffer is empty or you have found a start byte.

b) if the buffer is non-empty verify the message.
- If the checksum is OK, you have got a good message. Act on it and delete the the message from the buffer.
- if the checksum is wrong, discard one byte from the buffer

If there are bytes left, return to point a) otherwise start again to read data into the buffer.

Thomas

pycrc -- a free CRC calculator and C source code generator