Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Minimizing errors and capturing valid data in wireless internet

Status
Not open for further replies.

mik3ca

Member
I'm planning to make a wireless network of my own with microcontrollers. It may sound like I'm trying to reinvent the wheel, but later on I will be using the network for other purposes besides exchanging bytes over the air.

The problem I have is that nearly all data streams being sent over end up at the other end incorrect.

This is the data format I use to send over the air with. Each entry below uses one byte:

  1. Sender's address from 0 - 255
  2. Receipient's address from 0 - 255
  3. Command
  4. Data
  5. Data
  6. Data
  7. Checksum High byte
  8. Checksum Low byte
The checksum bytes put together form a 16-bit checksum of the remaining 6 bytes in the entire packet.

What I have attempted is to transmit the same packet 4 times in a row in hopes the receiver gets it. Sometimes the receiver gets it but not always in the right order. sometimes bytes are missed.

This is what I have done when trying to receive data:

Code:
Buffer pointer is zero - start at 1st byte.
Receiver first checks to see that the first byte isn't their ID. If it is, start read all over.
Receiver then checks to see that the second byte IS their ID. If it isn't, start read all over.
Receiver then reads all remaining 6 bytes.
Receiver checks checksum. If it doesn't match, start read all over.
When everything is valid, data is copied to userspace for application processing.

Sometimes when I try to read data from the transmitter that continuously transmits the same packet endlessly, the ID matches up but the checksum is incorrect, yet I use the same equation on both transmitter and receiver to generate the checksum.

Is there any other way I can do this without extending my packet size or reducing the number of bits available for generic data?

I heard someone mention the use of sliding windows but I'm not sure how that would improve the situation.
 
I usually implement a 2-BYTE SYNC header in my data packet that never changes.... i.e $FF and $AD .... The receiver looks for $FF and doesn't process any other bytes until $FF is received. I also implement a SEED that can be random but a simple incremental rollover byte is sufficient. So my packet may look something like this ...

Simple 6-BYTE data packet...
$FF : $AD : SEED : ADDRESS : DATA : CRC

CRC(calculated) = $FF ^ $AD ^ SEED ^ ADDRESS ^ DATA + CRC (received)

Note1: Notice the '+' at the end for the CRC rather than an XOR '^' ... I like to do this for a slightly added amount of robustness. With a straight forward XOR, two bits in the same binary position can be in error and the CRC result reports valid. By adding, two bits would have to be in error and a bit shift would have to take place in order for the CRC to report valid.

Note2: Since Valid data could also produce $FF SYNC, if the following SYNC byte is not $AD the packet index pointer should be reset so that the packet framing aligns properly.

Note3: You can implement a Command or Function without having to send it every time by allocating an Address and/or Data value to be written to a specific address on the receiver within the capabilities of the 6-BYTE example data packet mentioned here. Of course you can expand the framework any way you wish.

If you have bidirectional capabilities, then proper handshaking would send a re-transmit request if the received CRC did not match the calculated CRC value. Otherwise you just have to send the data multiple times hoping that the receiver got the data intact.

If the CRC matches, then and only then the DATA is written to the ADDRESS .... <-- This simple approach works best if both sides have the same structure of scratchpad memory to work with
 
I usually implement a 2-BYTE SYNC header in my data packet that never changes.... i.e $FF and $AD .... The receiver looks for $FF and doesn't process any other bytes until $FF is received.
I was thinking of reserving two bits from the addresses (since I'll be using less than 64) as the sync bytes, but I suppose two full bytes are more robust? Ok. I'll now say my first 2 bytes are FF and AD then. I might decide later to do AA and 55 since that means alternating 1's and 0's in binary.

I also implement a SEED that can be random but a simple incremental rollover byte is sufficient.
Hmm... I thought it'd be more economical to store such seed in all devices in the same network rather than transmitting it. With the fletcher checksum I used before, I could start the number with any common seed (typically 0). If it is more economical transmitting the seed every time, I'm curious to know why.

So my packet may look something like this ...

Simple 6-BYTE data packet...
$FF : $AD : SEED : ADDRESS : DATA : CRC

Well Ideally I'd like 3 bytes for raw data and 1 for command because I could be passing a number that's in the million range, and that would require 24 bits.

So If I use 1 byte CRC then I'm thinking:

FFh ADh Address Address/Command Data Data Data CRC

where the 4th byte is split between address and command. Then in total I'd have 6 bits for sender, 6 bits for receiver, and 4 bits for command. Could I still get decent data integrity if I used only halves of the first two bytes for syncing and the remaining halves for command so format will be:

Byte 1:
Bits 1-4: sync nibble 1
Bits 5-8: command nibble 1
Bits 9-12: sync nibble 2
Bits 13-16: command nibble 2
Byte 2: Sender
Byte 3: Receiver
Bytes 4 to 7: Data
Byte 8: CRC

CRC(calculated) = $FF ^ $AD ^ SEED ^ ADDRESS ^ DATA + CRC (received)
For this math, you xor'ed every byte but the CRC byte and then you added the CRC byte again to get the CRC to transmit?

If you have bidirectional capabilities, then proper handshaking would send a re-transmit request if the received CRC did not match the calculated CRC value. Otherwise you just have to send the data multiple times hoping that the receiver got the data intact.
I do but I don't have full-duplex capabilities.

If the CRC matches, then and only then the DATA is written to the ADDRESS
Ok, this part I got figured out. Its just the rest of it as explained above I need more elaboration on because I want to be able to send at least 3 bytes of raw parametric data and 1 byte of command to any address (from 0 to 63).
 
HM-TRP series with 1cm helical antennas attached. my channel is 915Mhz In all tests, the modules are 1 feet apart and I use the highest settings for receive bandwidth and modulation index. I chose 57600 baud for air speed and uart speed. Other settings I did not play with.
 
the modules are 1 feet apart and I use the highest settings for receive bandwidth and modulation index
May well be your problem.. The signal may be saturating.... I have to have mine at least 1 metre apart!! But then again, I have whip antenna's..
 
Is there a way I can do the tests with the units closer together? I mean I can reduce transmitter power, but to what?
 
I would consider doing a simple link budget, with a goal of hitting your received at its nominal level by reducing tx power or increasing distance
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top