View previous topic :: View next topic |
Author |
Message |
Gerhard
Joined: 30 Aug 2007 Posts: 144 Location: South Africa
|
Ensuring correct data send over RF. |
Posted: Sat Oct 20, 2007 3:41 am |
|
|
I need to send data over a RF using a CC1000 and at the moment I am sending a preamble before i sent the actual data. The code for sending is as follows
Code: | if(weapon > 230){
output_high(pin_B4);
PutCC1000(PREAMBLE);
PutCC1000(0X0A);
} |
And the recieving side is as follows.
Code: | if (temp == PREAMBLE) { // as preamble ontvang is
temp = GetCC1000();
output_high(pin_b3);
////////////////weapon///////////////////////////////////////////////////
if(temp == 0x0A)
{
output_high(pin_A5);
output_low(pin_b4);
output_high(pin_b5);
} |
I need to ensure that the correct data is recieved and if it is not i need to stop anything from hapening. Has anybody got some advice in this regard. |
|
![](templates/subSilver/images/spacer.gif) |
libor
Joined: 14 Dec 2004 Posts: 288 Location: Hungary
|
|
Posted: Sat Oct 20, 2007 5:19 am |
|
|
Solutions range from a simple checksum of a data packet, thru the more robust various CRC algorythms (8, 16, 32 bits) with or without error correcting option.
I simple ckecksum with resending (as the error correction) would be the right method for you I think. |
|
![](templates/subSilver/images/spacer.gif) |
Gerhard
Joined: 30 Aug 2007 Posts: 144 Location: South Africa
|
|
Posted: Sat Oct 20, 2007 5:42 am |
|
|
Thanks.
Can you please give me some guidance as to do this. A reference to an example or some starting point program would be nice. |
|
![](templates/subSilver/images/spacer.gif) |
libor
Joined: 14 Dec 2004 Posts: 288 Location: Hungary
|
|
Posted: Sat Oct 20, 2007 6:03 am |
|
|
First, you need to design your own standard packet structure. I see you're sending just one byte as the payload to one recipient (no addressing is needed)
So something like [preamble, data, crc] will do. For more data bytes I would have suggested a CRC-8 solution applied on your datat packet like this one here CRC-8.
But for just one byte of payload this would be an overkill, I think You can simply send you byte 3 times. [peramble, data1, data2, data3] and compare the 3 bytes upon arrival. If they match, use the data as valid.
I suggested 3 times repeating and not 2. because you can also make you error-correcting solution in the receiver if you wish. If all three bytes do not match, but any two are the same (majority-voting) you can discard the minority (presumably wrong byte) and use the majority value as valid (in the wireless RF world we need to adapt to the errors, and not trying to eliminate them) |
|
![](templates/subSilver/images/spacer.gif) |
Gerhard
Joined: 30 Aug 2007 Posts: 144 Location: South Africa
|
|
Posted: Sat Oct 20, 2007 7:57 am |
|
|
At the moment I sent a preamble which = 1byte then my data package which is also 1 byte. On the recieving side i start reading the byte as the CRX_BUFFCOUNT is bigger than 1. After that value is set to temp, i compare it to the preamble then I save the next value, in a if loop to temp aswell. How would i be able to adress say 4 data packages(preamble,data1,data2,data3) if on every set of datapackages that is sent if im am doing it with just preamble and data1 as follows?
Code: | if (CCRX_BUFFCOUNT >= 2) {
if (temp == PREAMBLE) {
temp = GetCC1000();
output_high(pin_b3);
////////////////weapon///////////////////////////////////////////////////
if(temp == 0x0A) |
|
|
![](templates/subSilver/images/spacer.gif) |
libor
Joined: 14 Dec 2004 Posts: 288 Location: Hungary
|
|
Posted: Sat Oct 20, 2007 8:13 am |
|
|
Lets send the data byte 3 times:
Code: | if(weapon > 230){
output_high(pin_B4);
PutCC1000(PREAMBLE);
PutCC1000(0X0A);
PutCC1000(0X0A);
PutCC1000(0X0A);
}
|
in the reciever lets check if you have received all four bytes and all three payload bytes are the same (for making it less likely you are getting some noise interpreted as a command)
Code: |
if (CCRX_BUFFCOUNT >= 4) {
if (temp == PREAMBLE) {
temp1 = GetCC1000();
temp2 = GetCC1000();
temp3 = GetCC1000();
output_high(pin_b3);
if ((temp1 == temp2) && (temp2 == temp3)) {
if (temp1 == 0x0A) {
...
}
if (temp1 == some other command value ....etc
|
|
|
![](templates/subSilver/images/spacer.gif) |
newguy
Joined: 24 Jun 2004 Posts: 1903
|
|
![](templates/subSilver/images/spacer.gif) |
Gerhard
Joined: 30 Aug 2007 Posts: 144 Location: South Africa
|
|
Posted: Sun Oct 21, 2007 12:41 pm |
|
|
Thanks you.
Does the comand get_CC1000 only reads the 8 bits that are in the buffer before it actually copys that value into temp 1 and then reads the next 8 bits and copy's that bit in the next temp2 or does the buffer set itself to 0 and then redo the whole reading setup. How does the pic know that 8bits have been read and it should copy the next 8 bits into the next varable?? |
|
![](templates/subSilver/images/spacer.gif) |
Gerhard
Joined: 30 Aug 2007 Posts: 144 Location: South Africa
|
|
Posted: Tue Oct 23, 2007 10:00 am |
|
|
I Can't seem to find the correct solution.
How is the adressing done in the getCC1000 comand. If the preamble is read the first data package gets read and after that the second but how does the pic know that it is in fact reading the complete 8bits of data1 then of data 2 and not some mix between the first data package and the last?? |
|
![](templates/subSilver/images/spacer.gif) |
libor
Joined: 14 Dec 2004 Posts: 288 Location: Hungary
|
|
Posted: Tue Oct 23, 2007 12:00 pm |
|
|
Quote: | how does the pic know that it is in fact reading the complete 8bits of data1 then of data 2 and not some mix between the first data package and the last?? |
Good question. It does not know. You have to synchronize to the byte boundaries in your receiving software.
You should send one or more know values (synch bytes) after the preamble so your receiving software will know how many bits you are shifted away from the true byte boundary. Knowing this you then have two choices either you skip the partial byte and go on receiving full bytes after it from the CC1000. Or you can shift bitwise all your buffer's content to the right byte boundaries in the PIC.
You can chose 2 byte of sync bytes to be such values that you will know how many bits you are shifted (and in what direction) after receiving it.
e.g. you send 11010011 10100011
you can then receive 11010011 when not shifted
10100111 when shifted by 1 bit
01001110 when shifted by 2 bits
...
etc.
So you can get back to sync depending on the value you received as the first byte.
You should use more than one byte as a preamble btw, I think these RF chips need atleast 16 or 24 bits to lock onto. So send 2 or 3 preamble bytes. |
|
![](templates/subSilver/images/spacer.gif) |
Gerhard
Joined: 30 Aug 2007 Posts: 144 Location: South Africa
|
|
Posted: Tue Oct 23, 2007 12:27 pm |
|
|
Thanks.
If i sent 4 bytes of data [preamble,data1,data2,data3] and i then recieve them with
temp = getcc1000 //preamble
temp1 = getcc1000//data1
temp2=getcc1000//data2
temp3=getcc1000//data3
wil the pic then insert preamble into temp,data1 into temp1,data2 into temp3 or will the bits become mixed up between the bytes.
How do i implement the sync into the recieving side. I think my problem is that i don't understand how each byte is entered and read from the buffer and how the pic treats the buffer if different bytes are recieved into the buffer? |
|
![](templates/subSilver/images/spacer.gif) |
libor
Joined: 14 Dec 2004 Posts: 288 Location: Hungary
|
|
Posted: Tue Oct 23, 2007 12:54 pm |
|
|
They will be mixed up. The beginning of the preamble is usually get lost in the air. (and you can't tell how much of it, maybe just 2 bits, maybe 6. this can vary with each packet) This is what the preamble meant for. (to allow the receiver - hardware in case of CC1000 - synchronize to the bit's boundaries)
Regarding the byte boundaries one approach is: You can read all bytes into a buffer. And shift them (with rotating bits) untill they are aligned to the true byte boundaries. How many bits of shifting you need depends on how many bits are lost in the air from the very beginning of the packet (preamble)
You can insert a known combination of bits (eg. two sync bytes) into the stream, so you will know how many bits of shifting you'll need to restore the original packet. |
|
![](templates/subSilver/images/spacer.gif) |
newguy
Joined: 24 Jun 2004 Posts: 1903
|
|
![](templates/subSilver/images/spacer.gif) |
libor
Joined: 14 Dec 2004 Posts: 288 Location: Hungary
|
|
Posted: Tue Oct 23, 2007 1:41 pm |
|
|
newguy, the ER400TRS module (used in the example that you refer to) has its own onboard microcontroller (maybe a PIC, or some other) that runs a firmware doing the packet construction, decoding, byte boundary synchronizing, addressing, maybe also the checksum error detecting/correction, resending etc. Using this module you are only talking to this microcontroller and not to the RF IC itself.
Gerhard is trying to interface directly to a CC1000 RF IC with no other microcontroller (with some company's firmware in it) doing these things for him.
(you might what's the reason, an RF module with a microcontroller+firmware in it costs in the range of $40-50, a CC1000 (we use the CC1100) RF chip costs $1-2, on the difference (actually the firmware's royalty) you can make a living on if you use/sell hundreds of these devices and write your own software) |
|
![](templates/subSilver/images/spacer.gif) |
newguy
Joined: 24 Jun 2004 Posts: 1903
|
|
Posted: Tue Oct 23, 2007 2:17 pm |
|
|
I appreciate the difference, but the underlying principle should still work. The only thing that the approach given in the links assumes is that the tx & rx are matched - that is a 1 sent by the transmitter means a 1 comes out of the receiver - and that both the transmitter & receiver each have a PIC (or any microcontroller really - one to pump data into the tx and other to catch data coming from the rx). Things become easier if each microcontroller has a UART.
To transmit:
a) send a 3 or 4 byte LAM (look at me)/preamble.
b) send a unique product/tx - rx pair "address".
c) send your data.
d) (optional) send a CRC.
To receive:
a) implement a state machine rx routine - look for the unique product/tx - rx pair "address" used in the transmitter's step b) above. DON'T look for the LAM signal in step a).
b) once the correct "address" unlocks the rx state machine, accept the next byte(s) as data/CRC.
c) (optional) perform a sanity check on the received data.
d) act on the received data. |
|
![](templates/subSilver/images/spacer.gif) |
|