RF Encoding - Decoding

  • Upload
    ozmeen

  • View
    223

  • Download
    0

Embed Size (px)

Citation preview

  • 8/8/2019 RF Encoding - Decoding

    1/4

    1

    A laymans guide to RF transmission encoding-decoding using PbPro

    As promised a while ago, I finally got the OK from our client to release part of the code that was used in

    their RF data link project. The project, which will become a commercial instrument at the end of the next

    quarter, consisted of 16 remote logging stations with RF data links into a main controller located in the

    main building. We ended up utilizing Radiotronix module OOK transmitter and receiver modules because

    of their specs (109dbm sensitivity on the receiver, 75 kHz accuracy around the center frequency of 433.92

    MHz on the transmitter and 4800-baud rate speed on both) and low cost. By the end of the project we were

    able to achieve 99.9% link reliability and 100% data integrity reliability, measured over a period o 35 days,

    and operating 24-7 at distances in excess of 70 meters inside buildings of various types. After each remote

    is polled, it is given 5 opportunities to come back. Should transmission fail after the 5th

    attempt (data

    integrity, no answer etc.), then that link is assigned a fail code until the next time. For our purposes, at 4800

    baud, using CRC and Manchester encoding and based on the number bytes that we are dealing with, each

    transmission is well under 1 second ( more like 400 msec)

    As RF was new to us, it took a while to learn (the hard way I might add) that you cannot treat RF serial

    communications as you would ,say, a hard-wired system. We got bit by most, if not all, of the alligators

    which normally attack such a project, that is, PC board layout, choice and positioning of the antenna,

    propagation interference, signal absorption, reflection, multipath interference and radio interference inside

    the buildings, nulls, deep nulls etc. After solving the usual hardware problems, it was then that we found

    out the hard way that RF serial transmission has to be treated quite a bit differently than hard-wired serialcomms.

    Given the nature of the OOK type receivers all of which contain data slicers, the transmitted bit pattern has

    to be able to:

    1. Provide some sort of synching for the receiver2. Provide a pattern which will keep the receivers data slicer at mid point (DC balanced) when using

    NRZ type data -(Manchester encoding)

    3. Provide some sort of control for its integrity at the receive end -(16 bit CRC check).4. Provide some sort of unique identifier (if you have more than one remote working)Our transmission sequence and format looked like the following:

    Gosub Manchester_Encode

    Gosub Calc_CRCTransmit_Data:

    Serout2 RFSerOut,RfBaudRate,WaitDelay,[Preamble,Preamble,Preamble,Preamble,_

    Preamble,XmtSynch,EncodedWord.LowByte,EncodedWord.HighByte]

    At the receiver end our receive proc looked like the following:

    Receive_Results:

    TempVar = SerialNum[z]

    gosub Manchester_Encode ' Encode byte

    RFSerout = 1 ' prepare xmitter

    pause 15 ' time to settle

    Serout2 RFSerOut , RfBaudRate , 15 , [Preamble,Preamble,Preamble,Preamble, Preamble, Synch ,

    EncodedWord.Lowbyte,EncodedWord.Highbyte] ' wake up remote

    gosub Xmit_OFF ' xmitter is OFFGosub Rcv_ON ' receiver is ON

    CRC = 0

    ChannErr = 1 ' If fail code 1 then time out

    goto Get_Rx_Data ' get the data

    Continue1:

    If TempVar = SerialNum[z] then ' Is the remaote answering the correct one?

    ChannErr = 2 ' If fail code 2 then SerNum ;Timeout 2

    goto Get_Rx_Data ' get the data

    Continue2:

  • 8/8/2019 RF Encoding - Decoding

    2/4

    2

    x = TempVar ' Remote S/N

    gosub Calc_CRC ' calculate CRC for byte

    ChannErr = 3 ' Type comparison error code

    goto Get_Rx_Data ' get the data

    Continue3:

    ChannErr = 4 ' Type comparison error code

    If SensorType[z] (TempVar) then Finish_Receive ' Type error;remote type base type

    SensorType = TempVar

    x = SensorType

    gosub Calc_CRC ' calculate CRC for byte

    goto Get_Rx_Data ' get the data

    Continue4:

    ResultSign = TempVar

    x = ResultSign ' Result sign

    gosub Calc_CRC ' calculate CRC for byte

    ChannErr = 5

    goto Get_Rx_Data ' get the data

    Continue5:

    Result.LowByte = TempVar

    x = Result.LowByte ' result low byte

    gosub Calc_CRC ' calculate CRC for byteChannErr = 6 ' Result High Byte error code

    goto Get_Rx_Data ' get the data

    Continue6:

    Result.HighByte = TempVar

    x = Result.HighByte ' Result high byte

    gosub Calc_CRC ' calculate CRC for byte

    ChannErr = 7 ' result low byte error code

    goto Get_Rx_Data ' get the data

    Continue7:

    Result2.HighByte = TempVar

    x = Result2.Highbyte ' must do CRC with Hi CRC byte first

    gosub Calc_CRC ' otherwise CRC 0 on good xmission

    ChannErr = 8goto Get_Rx_Data ' get the data

    Continue8:

    Result2.LowByte = TempVar

    x = result2.Lowbyte

    gosub Calc_CRC

    If CRC 0 then ' Calculated CRC must = 0 ;else crc error

    ChannErr = 9 ' CRC Error

    goto Finish_Receive ' end reception with error

    endif

    ChannErr = 0 ' Reset error var; receive OK

    gosub Rcv_OFF ' Evereything OK; Receiver is OFF

    Goto Finish_Receive

    endifGet_Rx_Data:

    Serin2 RFSerIn,RfBaudRate,RxTimeOut,Finish_Receive,[Wait(Synch), Encoded Word.Lowbyte ,

    EncodedWord.Highbyte]

    gosub Manchester_Decode ' decode the variable back to a byte

    The above procedure, which was a subroutine in our program, basically:

  • 8/8/2019 RF Encoding - Decoding

    3/4

    3

    1. Wakes up each of remotes based on the serial number of the remote station. Note that we send out 5preambles. If you have the time and speed, the more the merrier since the preambles purpose is to helpDC balance the reeivers bit slicer.

    2. Receives each byte of data from the remote3. Does a CRC (integrity check) calculation on the received data (less the preambles, and the CRC byte)4. Manchester decodes the received data5. Note that ChannErrs were inserted in there so that we would know exactly where the transmission

    failed (if it failed).Some of the constant and variable definitions for the above procedures to work were:' CONSTANTS Here:Preamble con $55 ' preamble data byte forxmiter synching;%101010Synch con "j" ' synchronization byteCRCPolynomial con $1021 ' CRC-CCIT

    Notes:1. We chose $55 as the preamble because of its inherently balanced nature of equal number of 0s and

    1s. If one looks at the binary equivalent of 55h is 01010101b. Note that 1s and zeros equal eachother and the bit run length (how many 1s and 0s are next to each other- also important to keep thebit slicer DC balanced) ) is 1.

    2. The j was chosen as the Synch byte for the same reason3. The CRC polynomial is a standard. Much information available on the net about CCIT CRC

    polynomials.

    Manchester encoding and decoding the data:

    Manchester_Encode:For y = 0 to 7

    If TempVar.0[y] = 0 then ' Bit = 0EncodedWord.0[y * 2] = 0EncodedWord.0[(y*2)+1] = 1

    elseEncodedWord.0[y * 2] = 1 ' Bit = 1EncodedWord.0[(y*2)+1] = 0

    endifnext

    Return

    Note that:1. TempVar is the byte we want to encode2. We will encode it into a 16 bit word, the low byte will contain the lower nibble of the encoded

    variable; ' the high byte will contain the upper nibble of the encoded variable3. A 0 will be equated to a 0-1 transition4. A 1 will be equated to 1-0 transition5. I used a little touted, extremely useful, undocumented feature of PbPro- the ability to access each bit of

    a byte or word using Word.0[y] feature. This saves on LOADS of IF-ANDs as well as codereadability and size. I suspect that the CASE statement in 2.34 may be usable instead of this feature.

    6.

    The above procedure will encode each 8-bit byte to a 16-bit word with an equal number of 1s and 0s.Run length is 1. The upside is that this is perfect for DC balancing the receivers bit slicer. Thedownside is that this results in doubling bandwidth.

    Since the data is encoded at the transmitter, it must be decoded at the receiver. The procedure I used forthat was:

    Manchester_Decode:For y = 0 to 7

    If EncodedWord.0[y*2] = 0 then ' if bit =0

  • 8/8/2019 RF Encoding - Decoding

    4/4

    4

    If EncodedWord.0[(y*2)+1] = 1 then

    TempVar.0[y] = 0

    Endif

    Else

    TempVar.0[y] = 1 'then bit =1

    Endif

    Next

    Return

    Note that:

    1. We will decode EncodedWord (lower byte) as the lower nibble of tempVar2. EncodedWord ( high byte) as the upper nibble of TempVar3. Basically, again using the Word.0[y] feature of PbPro, we are able to access each bit of the encoded

    word and decode it (strip it) back to the original 1 or 0 that was transmitted.

    For data integrity at the receive end,(that is to make certain that what you receive is exactly what you send)

    we used a CRC check. We found this to be much safer and reproducible than the simpler checksum. The

    CRC routine was:

    Calc_CRC: 'calculate byte CRC; 16 bit crc based on CCIT polynomial

    CRC = (x * 256) ^ CRCFor y = 0 to 7

    If CRC.15 = 0 then Multiply

    CRC = (CRC