0

I was looking at answers in Simple serial point-to-point communication protocol and it doesn't help me enough with my issue. I am also trying to communicate data between a computer and an 8-bit microcontroller at first, then eventually I want to communicate the one microcontroller to about 40 others via wireless radio modules. Basically one is designated as a master and the rest are slaves.

speed is an issue

The issue at hand is speed. because communication of every packet needs to be done at least 4x a second back and forth between the master and each slave.

Let's assume baud rate for data is 9600bps. That's 960 bytes a second.

If I used 16-byte packets then: 40 (slaves) times 16 (bytes) times 2 (ways) = 640. Divide that into 960 and that would mean well more than 1/2 a second. Not good.

If I used 8-byte packets then: 40 (slaves) times 8 (bytes) times 2 (ways) = 320. Divide that into 960 and that would mean 1/3 second. It's so-so.

But the thing is I need to watch my baud because too high of baud might mean missed data at larger distances, but you can see the speed difference between an 8 and 16 byte packet.

packet format idea

In my design, I may have a need to transmit a number in the low millions so that will use 24-bits which fits in my idea. But here's my initial idea:

Byte 1: Recipient address 0-255
Byte 2: Sender address 0-255
Byte 3: Command
Byte 4-6: Data
Byte 7-8: 16-bit fletcher checksum of above data

I don't mind if the above format is adjusted, just as long as I have at least 6 bits to identify the sender and receiver (since I'll only deal with 40 units), and the data with command included should be at least 4 bytes total.

How should I modify my data packet idea so that even the device that just turned on in the middle of reception can be in sync with the next set of data? Is there a way without stripping a bit from each data byte?

Mike -- No longer here
  • 2,064
  • 1
  • 15
  • 37
  • Is the wireless link approximately the same bandwidth? Because if yes, then I think you have to tone down your data rate expectations even further. RF communication startup and switching can suffer from much longer delays than cable bound comms. Regarding the protocol: if it is true master-slave, you could do away with one of the address bytes as it will always be the master who is involved. Moreover maybe a CRC8 could be a replacement for the Fletcher checksum. Intra-CPU bandwidth is cheap in relation to field bus speed. – Vroomfondel Dec 07 '17 at 23:13
  • Yes, I set all baud rates the same (57.6K). I made the noise floor and deviation to the maximum settings as well. The modules I use are HM-TRP. I'm also using an 8-bit processor (AT89C4051) for the testing. – Mike -- No longer here Dec 08 '17 at 04:42

1 Answers1

2

Rely on the check sum! My packet would consists of:

  1. Recipient's address (0..40) XORed with 0x55
  2. Sender's address (0..40) XORed with 0xAA
  3. Command Byte
  4. Data Byte 0
  5. Data Byte 1
  6. Data Byte 2
  7. CRC8 sum, as suggested by Vroomfondel

Every receiver should have a sliding window of the last seven received bytes. When a byte was shifted in, that window should checked if it is valid:

  • Are the two addresses in the valid range?
  • Is it a valid command?
  • Is the CRC correct?

Especially the last one should safely reject packets on which the receiver hopped on off-sync.

If you have less than 32 command codes, you may go down to six bytes per packet: 40[Senders] times 40[Receivers] times 32[Commands] evaluates to 51200, which would fit into 16 bits instead of 24.

Don't forget to turn off the parity bit!

Update 2017-12-09: Here a receiving function:

typedef uint8_t U8;

void ByteReceived(U8 Byte)
{
   static U8 Buf[7]; //Bytes received so far
   static U8 BufBC=0;

   Buf[BufBC++] = Byte;

   if (BufBC<7) return; //Msg incomplete

   /*** Seven Byte Message received ***/

   //Check Addresses
   U8 Adr;
   Adr = Buf[0] ^ 0x55; if (Adr >= 40) goto Fail;
   Adr = Buf[1] ^ 0xAA; if (Adr >= 40) goto Fail;

   if (Buf[2] > ???) goto Fail; //Check Cmd

   if (CalcCRC8(Buf, 6) != Buf[6]) goto Fail;

   Evaluate(...);

   BufBC=0; //empty Buf[]
   return;
Fail:
   //Seven Byte Msg invalid -> chop off first byte, could use memmove()
   Buf[0] = Buf[1];
   Buf[1] = Buf[2];
   Buf[2] = Buf[3];
   Buf[3] = Buf[4];
   Buf[4] = Buf[5];
   Buf[5] = Buf[6];
   BufBC  = 6;
}
user5329483
  • 1,260
  • 7
  • 11
  • When i monitor the chunked data it seems to slide. Now i guess i'll have to look up sliding windows for the 8051 – Mike -- No longer here Dec 09 '17 at 01:07
  • Maybe I haven't searched right but looking at sliding window protocols means that the window shifts if a receiver sends an acknowledgement. But I need to optimize for a half-duplex situation because the radio modules I use are also restricted to half-duplex in which a transmission made on the micro is given priority over data reception (according to the radio module). – Mike -- No longer here Dec 09 '17 at 03:15