How to indicated the first of data in data frame

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

Hi all,
I'm trying to send 100 byte data to rs232, each byte have value from 0-255, I try to find the good way to indicated the first byte of data frame. Now I have only one idea by send 2 byte for the header, first byte for the header and second byte for header inverse.

F2 0D data1 data2.....data100

I know this way not so good, because some time data1-data100 maby can have same value as the header. Any one have a good idea ?

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

You will need form of packet protocol, this is where 9 bits comms is a winner.
The only other reliable way would be to send the data as ASCII HEX values (ie 2 bytes for each byte 0x00 would be 0x30,0x30) this way you will always be able to send control characters like STX (start of text 0x02) and ETX (end of text 0x03).

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

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

js wrote:
You will need form of packet protocol, this is where 9 bits comms is a winner.
The only other reliable way would be to send the data as ASCII HEX values (ie 2 bytes for each byte 0x00 would be 0x30,0x30) this way you will always be able to send control characters like STX (start of text 0x02) and ETX (end of text 0x03).

That mean if I need to send data 100 byte, actually sending on 200 byte :!:

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

Quote:
actually sending on 200 byte
Correct, there are other old tricks you may be able to use like sending a break signal and then start sending the first byte. Where is the data coming from/going to, a pc or another AVR?

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

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

Data coming from AVR and going to PC. I think your first trick is good idea, but many data to sending, for the old tricks could you deal ?

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

Quote:
for the old tricks could you deal
If you send a lot of zero bits longer than the formatted byte, then you will get a framing error in the UART. You can use this error as an indication that the next byte is the first of the packet. ie if you are using 8 bits, 1 start and 1 stop bit (10 bits) and you set the AVR UART to send an 9 bit data + start and 1 stop bit (11 bits) you will produce the framing error in the pc, then switch to 8 bit mode before sending data out.
But then you will need to have special code in the pc to know how to deal with this and HOPE that you don't have a real framing error.
Also is the data ALWAYS 100 bytes? If not you MUST have some form of prototcol so that the other end knows when to stop.

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

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

I get it, it seem complicated than the first tricks, but I can reduce the sending byte, maybe I need to find an event for framing error on Visual Basic (not sure it provide already ?) to indicated the next data is the first byte of the framing. Have you use this methods before ?

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

Start the packet with STX and end it with ETX. When the data contains any of these, prefix them with a DLE (0x16 iirc). Also, prefix DLE itself ;)

Source data:
0x56 0x78 0x02 0x9A 0x16 0x65 0x30

Transmitted:
0x02 0x56 0x78 0x16 0x02 0x9A 0x16 0x16 0x65 0x30 0x03

Include some checksum, the likelyhood of a good checksum in a packet which is received only partially is very slim.

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

Quote:
Include some checksum,
16 bit CRC may even be better.
Quote:
Have you use this methods before ?
May have done, but it would have been a long time ago, can't remember too clearly. For the past 16 years I have been using 9 bit comms which make life a lot easier. Unfortunately receiving 9 bit data with the pc is not that easy and I have never attempted it, sending 9 bits data is easy enough.
Using a delimiter or an escape sequence as suggested by jayjay is also a good way to solve your problem.
I would tend towards using ASCII HEX as the easiest to implement even though the time would be twice as long. How much data will be send and how often? What baud rate? 200 bytes at 115K would take less than 20ms.

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

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

How about this. I just got in from google.

Attachment(s): 

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

Good for TEXT only data I think.

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

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

Umm you lads seems to be slowly reinventing Xmodem-CRC here! ;-)

http://en.wikipedia.org/wiki/XMODEM

(actually Y-modem may be better as it includes information about the overall length too)

Last Edited: Tue. Aug 7, 2007 - 11:28 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

js wrote:
Good for TEXT only data I think.

Why you think like that ?

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

1. How much data and how often do you want to send it ?

2. How reliable is your connection ? A radio link or modem link needs to have some reliable protocol.

3. If you need to send lots of data down bad lines then use an existing method like zmodem. It is not worth your time and effort to re-invent the wheel. I have never seen your googled protocol before. I definitely would NOT risk such a method with a bad line.

4. If you have a hard-wired connection between an AVR and a PC, then the simple binary to hex method is easy to implement. Or use simple escape sequences as suggested earlier. i.e. if SOH or EOT occur within your data, then escape them.

David.

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

Another way is like Modbus RTU - use time to frame the packet. Modbus RTU declares a pause of no transmission for 3 char times (variable) as the end of packet. Therefore, the first char you send must be the first char in the packet. It also uses a CRC to check the packet.

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

The protocol I came up with to send data via SPI uses a stack at the receiving end, sends 1-7 byte chunks in 2-9 byte chunks, and sets the 7th bit to indicate the end of a chunk.

You'd send bytes in the following format:

0AAAAAAA 1000001a

0AAAAAAA 0BBBBBBB 100001ab

0AAAAAAA 0BBBBBBB 0CCCCCCC 10001abc

0AAAAAAA ... 0DDDDDDD 1001abcd

0AAAAAAA ... 0EEEEEEE 101abcde

0AAAAAAA ... 0FFFFFFF 11abcdef

0AAAAAAA ... 0GGGGGGG 0abcdefg 1000000 (if more bytes follow)

0AAAAAAA ... 0GGGGGGG 0abcdefg 1000001 (if this is it)

unpacking them in assembly is easy... all you do is put the byte with the zero-bits in one register, and iterate through the stack one byte at a time. Rotate the zero-bit register right (shifting the rightmost bit into the Carry), then rotate the iterated byte left (shifting that bit into the byte and restoring it). Since the bytes are unpacked into another stack, figuring out how many args follow the opcode (the last byte) is easy, because you just follow the trail all the way down until the stack is empty.

There's no place like ~/

Last Edited: Wed. Aug 8, 2007 - 05:27 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
Why you think like that ?
Because if your data contains character below 0x20 (space character) like 0x01 or 0x03, you may get false starts.

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

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

For return bytes sent by the slave, I got even fancier so I could distinguish between real bytes and junk bytes. For the trip from slave to master, each byte gets split into two nybbles, and encoded as follows:

RNSPxxxx

where "xxxx" is the upper or lower nybble

'P' is the lower nybble's parity

'R' is 0 to indicate that it's a 'R'esponse, and 1 to indicate that it's an alert or unsolicited message

'N' is 1 to indicate that it's the upper nybble, and 0 to indicate that it's the lower nybble

'S' is the 'S'anity bit... if R == N, S = !P. If R != N, S = P

Then, on the receiving end, I buffer the two most recently-received valid bytes.

If a byte fails the parity or sanity bit test, it's discarded.

An upper & lower nybble may be separated by junk bytes, but NOT by a valid upper or lower nybble of the other Type. In other words, if an upper response nybble, an upper message nybble, and a lower response nybble gets received, the upper response nybble would be purged the moment the upper message nybble were received, because nothing that follows can then make the upper response nybble valid & it's presumed to be a junkbyte that merely looked valid.

I'm sure someone else has thought of the idea before, but I'm pretty proud of it because I came up with it entirely on my own :-)

Incidentally, the byte-per-nybble encoding is actually the "Data Link" layer. Responses are first encoded the same way as master->slave data (1..6 to 2..7 and 7 to 9), then split and sent as 01SPxxxx and 00SPxxxx pairs.

Messages are 1, 2, or 3 bytes encoded as:

100xxxxx -- 32 possible messages that by their existence convey some signal, like "button 0 depressed" or "button 1 released"

0AAAAAAA 101axxx -- single-byte message, with one of 16 possible signal ids.

0AAAAAAA 0BBBBBBB 11abxxxx -- double-byte message, with one of 16 possible signal IDs.

Like responses, the 1, 2, or 3-byte encoded message then gets split into nybbles and sent as 11SPxxxx and 10SPxxxx.

There's no place like ~/