PDA

View Full Version : RF Module Qualifier, CRC?



tazntex
- 16th March 2010, 17:53
Hello to all,
I am using the Linx RXM & TXM LR (long range) modules. I was sending my data successfully until I change my qualifier to anything but 254. It operated very reliably with only an occasional hiccup (probably due to multipath around the metal buildings) at several hundred feet. I am sending an address (word) broken up into four pieces which is in bytes because I am using Manchester Encoding, then reconstructing and comparing the address in the receiver (constant) and also doing the same with the actual button pressed on the transmitter (key). I am not using USART because I still don't understand it after reading countless post on this forum and reading the datasheet.
So I am doing this on the transmitter:
serout2 serpin,16468,[$AA,$AA,$AA,$AA,$AA,synch,addA,addB,addC,addD,addA ,_
addB,addC,addD,key,key,key,key,key]

And this of course on the receiver:
SERIN2 serpin,16468,500,loop1,[wait(254),address1,address2,address3,address4,_
address5,address6,address7,address8,mydata1,mydata 2,mydata3,mydata4,mydata5]


Then I am decoding the address (manchester) then summing those up, ADD1=ADDA+ADDB<<4+ADDC<<8+ADDD<<12
comparing my address (constant) in the receiver to ADD1
then I check:
IF (address = add1) && (mydata1 == mydata2) && (mydata1 == mydata3) &&_
(mydata1 == mydata4) && (mydata1 == mydata5) && _
(MYDATA1 > 0) && (MYDATA2 > 0) && (MYDATA3 > 0) && (MYDATA4 > 0)&& _
(MYDATA5 > 0) THEN
Index2 = 1
For Index = 0 to 3
mydata.0[Index] = mydata1.0[Index2]
Index2 = Index2 + 2
Next Index
chksum2 = chksum2 + 1
chksum3 = 0
high rf
else
chksum2 = 0
chksum3 = chksum3 + 1
low rf
endif
if chksum2 >=3 then start
until chksum3 >= 1
ADD1=0
chksum2 = 0
chksum3 = 0
mydata = 0
I decode the mydata
then i repeat this three times by going back up to the SERIN2
using that if statement ,if chksum2 >=3 then start
then I assume all of mydata and the address match is good so I continue on to the output I want on.

Life seems good because each output is actually staying on as long as I am pressing the button on the transmitter and the output immediately goes off as soon as I release the button.

BUT:
It does not work if I change the qualifier to anything else, maybe this should not alarm me but I have been trying to figure out why.. call me a perfectionist,...after all I am sending a preamble to balance the data slicer,...right? And I have tried sending more $AA's and even $55's and a combination of those. I am aware of the rx module "noise" read many post on this forum,watched it on my scope and squelch is useless because of range limitations but mainly to stop the noise completey, squelch turn up full, no data is then received:(

ok, other than changing the qualifier this remote control works almost perfect, that may be an over statement . I have learned a lot from all of you out there, especially breaking down my code and understanding how it ticks.

After doing a search on checksums, found many articles about CRC and a dead link PDF about CRC but as I mentioned, it is a dead link. So any suggestions, preferably in lamen's terms how I can use CRC?

Many Thanks

languer
- 16th March 2010, 20:34
Don't know if you have looked at the following links, but they maybe useful:

http://www.picbasic.co.uk/forum/showthread.php?t=11790&highlight=CRC
http://www.ccsinfo.com/forum/viewtopic.php?t=37015&highlight=crc

What you mention truly is puzzling. Before I tried adding any "wireless" comms to my protocols, I always tested them "wired". Have you tried your code changes on a "wired" setup (i.e. TX and RX PICs connected through a wire).

tazntex
- 16th March 2010, 21:20
Thanks Languer, I have tried everything wired before I went to RF, but, I did not make any changes to the qualifier. I was bored last Friday so reading over my code i realized that obviously the qualifier is not Manchester Encoded so I was thinking if I am sending a preamble of %10101010 preceding the qualifier 254,%11111110,what happens to the data slicer so curiosity got the better of me. I then thought that I could keep the data slicer balance by sending 170, %10101010. Thats when I found that I had a problem. when I changed it to 170 or whatever it became intermittent. By keeping it 254 I could operate this way over a couple of hundred feet with only a rare hiccup, stutter or whatever its called, but that is only when I was going close around my metal shop and vehicle. I've been trying to figure out some of the examples I have found on the CRC though. Instead of cut, copy and pasting them to my code I am trying to understand how each line works before I tailor it to my need.

Again, many thanks

mackrackit
- 16th March 2010, 22:52
This might give you some ideas. Not exactly what you are asking for, but it is very reliable.
http://www.picbasic.co.uk/forum/showthread.php?t=12554

Bruce
- 17th March 2010, 04:16
Have a look at this article. The PIC controls a Linx LR transmitter with data received from the PC serial port. It simulates the Holtek 8-bit encoder, and can control a Linx FCTN-RLY4-xxx receiver/relay, or a Linx KH2 receiver module. Both use the Holtek 8-bit decoder IC.

http://www.myamicus.co.uk/content.php?259-PC-Remote-Control

And this thread: http://www.picbasic.co.uk/forum/showthread.php?t=6581 has PBP code for decoding a Holtek 8-bit encoder.

languer
- 17th March 2010, 19:04
Those post from Bruce are very valuable. They show very simple methods to make you comms more robust.

Dhouston also has some very good information on similar subject: http://www.picbasic.co.uk/forum/showthread.php?t=6261


in lamen's terms how I can use CRC?
This is my best attempt to address this in particular (full disclosure - I am no expert). CRC is used in many places when you want to validate the contents of a packet (i.e. detect the packet to be error free). A packet can be anything: wireless data, ethernet data, bootloader data, archive data (read WinZIP). It is a very simple way of coming up with a somewhat unique identifier that tells you the packet you have has not been compromised (i.e. corrupted, changed, etc).

How effective is it? - It depends. There are as many algorithms (polynomials) as days of the year (and then some). It all depends on how "unique" you want to define your packet and how much math (read - computer resources) you want to use to come up with the CRC.

How simple is it? - Again, it depends.

Why use it? - It is pretty standard method of validating packetized data; as long as you have the computing power to do it, and select an algorithm/polynomial and stick with it.

What it does? - It gives you confidence on the validity of your packet (i.e. error detection).

What it does not do? - If your data packet is corrupted, it does not tell you how to correct it (i.e. it does not have error correction).

How you could use it? - On the transmit side, you calculate the CRC of your data packet (after selecting the algorithm you want/need) and send it along with your data packet (usually at the end). On the receive side, you receive the data packet and the CRC. Calculate a new CRC value form the data packet (not including the received CRC) and compare it to the received CRC. If they match you have a higher degree of certainty the packet is free from errors.

Good reads:
http://en.wikipedia.org/wiki/Cyclic_redundancy_check
http://www.hackersdelight.org/crc.pdf
http://www.repairfaq.org/filipg/LINK/F_crc_v3.html

rmteo
- 17th March 2010, 20:22
How effective is it? - It depends. There are as many algorithms (polynomials) as days of the year (and then some). It all depends on how "unique" you want to define your packet and how much math (read - computer resources) you want to use to come up with the CRC.

How simple is it? - Again, it depends.

Why use it? - It is pretty standard method of validating packetized data; as long as you have the computing power to do it, and select an algorithm/polynomial and stick with it.
Many higher-end devices (such as PIC24) implement it in hardware for the reasons you mention.

Bruce
- 18th March 2010, 03:06
Many higher-end devices (such as PIC24) implement it in hardware for the reasons you mention.
Yep. Unfortunately PBP just doesn't support the PIC24, PIC32, or dual-core pentiums..;o) And, for this particular application, that would be like hunting rabbits with a Sherman TANK. Honestly.

You just-do-not-need-to get-that-complex for such simple wireless communications, and it really does NOT require any PIC type beyond what PBP supports.

rmteo
- 18th March 2010, 13:53
I am aware of the limitations and shortcomings of PBP. I was agreeing with languer that implementing CRC in software is resource intensive and may not be the best solution for the OP. That is why it is implemented in hardware - for those that feel they have a need for it. But hey, rabbit hunting with a Sherman tank does sound like fun. :D:D:D

ScaleRobotics
- 18th March 2010, 15:07
implementing CRC in software is resource intensive and may not be the best solution for the OP.

Rmteo, is running CRC so intensive that it will not keep up with the lightning speed of 9600 baud? He will need to move up to a 16 bit chip for and new compiler for that?

I don't think so.

I heard this asked before, but do you use PBP?

tazntex
- 19th March 2010, 19:23
Thanks for all the help but I was looking at Bruce's remote example,
http://www.picbasic.co.uk/forum/showthread.php?t=12554

I thought I could also use the timer portion that could be helpful to jump out of the SERIN2 if no data is received, But ASM??? This is why I bought PicBasic Pro...

From what I understand, very little, I need to add this to my code:

DEFINE NO_CLRWDT 1 ' Watchdog timer is disabled, so we don't need to reset it
DEFINE INTHAND RESET_VT ' Interrrupt on Timer1 overflow to reset outputs in 65.5mS
' if no serial data received in this time period
SYMBOL TMR1IF = PIR1.0 ' Timer1 overflow interrupt flag (reset in int handler)
SYMBOL TMR1IE = PIE1.0 ' Timer1 interrupt enable bit

' Setup Timer1 for resets after ~65.5mS
T1CON = %00000000 ' Internal clock, 1:1 prescale, Timer1 off for now
TMR1L = 0
TMR1H = 0 ' Timer1 low & high bytes cleared
TMR1IF = 0 ' Clear Timer1 overflow flag before enabling interrupt
TMR1IE = 1 ' Enable Timer1 overflow interrupt
INTCON = %11000000 ' Global & peripheral ints enabled
chksum2 = 0 ' Clear match count
GOTO initialize ' Jump over int handler

ASM
RESET_VT
; Do interrupt stuff here
bcf T1CON,TMR1ON ; Stop Timer1
clrf TMR1L ; Clear low byte
clrf TMR1H ; Clear high byte
bcf PIR1,TMR1IF ; Clear Timer1 interrupt flag bit

DON'T KNOW ABOUT THE NEXT TWO LINES, SO I COMMENTED THOSE OUT. I BEEN READY THE DATASHEET FOR THE 16F628A, AND AT BEST GUESS TO CLEAR A SINGLE BIT ON PORTA, WHAT I SEEN IN THE DATASHEET REFERENCING WOULD BE PORTA, 1 OR PORT??1. DOESN'T COMPILE, HOW COULD I CLEAR PARTICULAR BITS HERE FOR PORTA AND PORTB?

;clrf portb ; Clear outputs on button release (or timeout)
;clrf porta ; Clear outputs on button release (or timeout)
bsf T1CON,TMR1ON ; Re-enable Timer1 before exiting interrupt handler
retfie ; Return from the interrupt
ENDASM

And then here is my serial in:

' Fire up Timer1 before entry to serial input routine
T1CON.0 = 1

' at 4MHz Timer1 overflows in 65536 * 1uS (~65.5mS) if no Synch byte
' and serial data arrive on time. SERIN2 timeout & label options
' are useless with a noisy RF receiver output - as noise continually
' resets the timeout period causing it to hang forever.

' Wait for Synch byte, then get new inbound data & checksum

SERIN2 serpin,16468,[wait(254),address1,address2,address3,address4,_
mydata1,mydata2,mydata3,mydata4,mydata5,mydata6]

T1CON.0 = 0 ' Stop Timer1 once we've received data
TMR1L = 0 ' Clear low byte
TMR1H = 0 ' Clear high byte

I compiled this with the rest of my code and it seems to be working fine, but am waiting for the gremlins to pop out.

Thanks a million for all the recommendations already.

mtripoli
- 19th March 2010, 22:14
I've been following this to see where it ended up... If you don't mind me asking; what kind of data are you transmitting? What speed?

I'm using the same modules for RF control of hardware.

tazntex
- 22nd March 2010, 13:44
Thanks for all the Help everyone,
Mtripoli, I am just sending the value of the button being pressed and have the modules set up for 9600. I don't know for sure if they're running at that speed but it is working great.

What has me fascinated, is the piece of code, I mentioned in my last response, the timeout for the receiver. I am not familiar with asm and have done some research on the datasheet for the 16f628a where it goes in to the instruction set. Instead of "clrf PORTA", I would just like to clear certain bits on PORTA and PORTB instead of clearing them all. At this moment I have not found anything on that but am about to use google to try to find that answer. Right now I am using the timeout feature of serin2, but I have taken a recommendation from a previous post on using:

while flag < 1 '1*100ms =.001

serin2, and so forth
flag = flag + 1
wend

I don't see any problems yet using this, but I guess time will tell. Would like to understand how the timer portion actually works in PICBASIC PRO but it must be one of those ASM things.

Thanks again

Bruce
- 22nd March 2010, 14:39
The Timer1 interrupt is just to exit the SERIN2 line and clear the decoder output pins if
no data has been received before Timer1 times-out.

Without the interrupt, it would just sit & spin on the SERIN2 line due to noise on the RF
receivers data output pin.

If data IS received, it drops to the next line after the SERIN2 and disables the timer until
it's needed again.

If you need to put certain values on PORTB or PORTA just use something like;

movlw b'11000010' ; <-- value to place on port
movwf PORTB ; <-- put it on the port

Not much tougher than PORTB = %11000010 in PBP...;o)

tazntex
- 22nd March 2010, 16:15
Thanks Bruce,
What I have is two outputs on PORTA, and eight outputs on PORTB, so if no data is received, or shall I say no valid data is received, then all of my outputs would then clear.


Again, Thank you all for your help and support, especially for the education that I have received from you all.