Manchester Coding / Decodeing for RF Modules


Closed Thread
Results 1 to 24 of 24

Hybrid View

  1. #1
    Join Date
    Jul 2003
    Posts
    2,358


    Did you find this post helpful? Yes | No

    Default

    Thanks for letting me know. Code has been up for eons and nobody spotted the typo before now!

  2. #2
    Join Date
    Oct 2003
    Location
    Australia
    Posts
    257


    Did you find this post helpful? Yes | No

    Talking

    Hi Mel,

    Yep I thought it had a bug, actually there is another ...(I swear I am not picking on you.... ) the NEXT counterA is missing in the EncodeManchester routine.

    For a while I had a problem understanding how the shift right >> instruction ran. (Not using this before)

    Also I assumed that the MyData BITS are stored in the registers as [0,1,2,3,4,5,6,7], but actually they are the other way around (same goes for the ManchesterWord bits).

    Watching the code run through ICD makes a lot of sense. I have attached the code for anyone interested. It is fully working on a 16F628 chip and great to pause the code and swap a few bits in the manchesterword to trigger the ErrorFlag Bit.

    Thanks again Melanie

    Now then, where did I put those RF modules?.....

    ' ==========================
    ' DEVICE PROGRAMMING OPTIONS
    ' ==========================

    ' PRESET FUSES
    @ DEVICE PIC16F628, WDT_ON
    @ DEVICE PIC16F628, INTRC_OSC_NOCLKOUT
    @ DEVICE PIC16F628, BOD_ON
    @ DEVICE PIC16F628, PROTECT_OFF
    @ DEVICE PIC16F628, MCLR_ON

    ' =============
    ' USER DEFINES
    ' =============
    DEFINE OSC 4

    ' =================
    ' SET USART PARAMS
    ' =================

    DEFINE HSER_RCSTA 90h ' Set receive register to receiver enabled
    DEFINE HSER_TXSTA 24h
    DEFINE HSER_BAUD 4800 ' Set baud rate
    DEFINE HSER_SPBRG 51 ' Set SPBRG directly (normally set by HSER_BAUD)

    ' ===========================
    ' CONFIGURE COMPARATOR MODULE
    ' ===========================
    CMCON = 7 ' TURN ANALOG COMPARATOR MODE OFF

    ' ==============
    ' PROGRAM VARS
    ' ==============
    COUNTERA var Byte
    ERRORFLAG var Bit
    MYDATA var Byte
    MANCHESTERWORD var Word

    ' ===================
    ' START
    ' ===================
    START:
    HSERIN [MYDATA]
    HSEROUT ["ENTERED VALUE: ",MYDATA,13,10]
    HSEROUT ["ENCODING TO MANCHESTER NOW",13,10]
    GOSUB EncodeManchester
    HSEROUT ["ENCODING COMPLETED",13,10]

    PAUSE 1000

    HSEROUT ["DECODING MANCHESTER NOW",13,10]
    GOSUB DECODEMANCHESTER
    HSEROUT ["DECODING COMPLETED",13,10]
    IF ERRORFLAG THEN
    HSEROUT ["VALUE CORRUPTED!: ",MYDATA,13,10,13,10]
    ELSE
    HSEROUT ["FINAL VALUE: ",MYDATA,13,10,13,10]
    ENDIF
    GOTO START:

    ' Subroutine Encodes Manchester Word
    ' Enter subroutine with data in MyData
    ' Exit Subroutine with encoded ManchesterWord
    ' MyData contents are destroyed on exit
    ENCODEMANCHESTER:
    ManchesterWord=0
    For CounterA=0 to 7
    If MyData.0=0 then
    ManchesterWord.14=1
    else
    ManchesterWord.15=1
    endif
    If CounterA<7 then ManchesterWord=ManchesterWord>>2
    MyData=MyData>>1
    Next CounterA
    Return

    ' Subroutine Decodes Manchester Word
    ' Enter subroutine with encoded data in ManchesterWord
    ' Exit subroutine with decoded data in MyData
    ' ManchesterWord contents are destroyed on exit
    ' Also on exit, ErrorFlag=0 then Data is good
    ' ErrorFlag=1 then Data is suspect/corrupt
    DECODEMANCHESTER:
    ErrorFlag=0
    For CounterA=0 to 7
    If ManchesterWord.1=0 then
    MyData.7=0
    If ManchesterWord.0=0 then ErrorFlag=1
    else
    MyData.7=1
    If ManchesterWord.0=1 then ErrorFlag=1
    endif
    ManchesterWord=ManchesterWord>>2
    If CounterA<7 then MyData=MyData>>1
    NEXT COUNTERA
    Return

  3. #3
    Join Date
    Sep 2003
    Location
    INDIA
    Posts
    161


    Did you find this post helpful? Yes | No

    Thumbs up

    Thank you for your contribution ,Squibcakes.

    Your code can be an excellent example for someone wanting RC5 over RF.

    regards

  4. #4
    a_critchlow's Avatar
    a_critchlow Guest


    Did you find this post helpful? Yes | No

    Exclamation wah waaaa

    hi all, i don't believe the decoding part of that code works! if you received an encoded stream of 0110100110011010 for example, this would raise the erro flag?

    If ManchesterWord.1=0 then
    MyData.7=0
    If ManchesterWord.0=0 then ErrorFlag=1
    else
    MyData.7=1
    If ManchesterWord.0=1 then ErrorFlag=1
    endif



    any help?





    thanks.

  5. #5
    Join Date
    Oct 2003
    Location
    Australia
    Posts
    257


    Did you find this post helpful? Yes | No

    Arrow Critchlow -> Wah waa yourself!

    Have you run the program and seen it work?

    I just did and it works fine! Lets see, was the letter you typed in the letter "k"?

    It decoded no problems for me.

    The best way to inderstand this program is to step through it using ICD mode... its hard to explain without viewing the registers at work.

    Good luck, and may the force be with you.

    Cheers
    J

  6. #6
    Join Date
    Jul 2003
    Posts
    2,405


    Did you find this post helpful? Yes | No

    Smile

    There are probably a few hundred ways to do this, but here's a few that I've used with decent results.

    The 1st version uses PBP's bit twiddling ability. Version 2 is a modified version of one originally done
    by Les Johnson.

    The .asm routine is considerably faster & smaller (knocks off 300 words) compared to the BASIC
    bit-twiddling approach.
    Code:
    DEFINE LOADER_USED 1
    DEFINE OSC 20
    
    ; compiled for an 18F2525. 882 words with MPASMWIN 5.01
    X           VAR BYTE
    Y           VAR BYTE    ' Array index pointer for primary functions
    Index       VAR BYTE    ' Array index pointer for encode/decode routines
    BitCount    VAR BYTE    ' Bit counter
    ByteIn      VAR BYTE    ' Byte to encode
    ByteOut     VAR BYTE    ' Decoded byte
    Manch       VAR WORD    ' Encoded manchester word
    Enc_Dat     VAR WORD[6] ' Word array for 6 manchester encoded words
        
        GOTO Main  ' Jump over encode/decode routines
        
    Encode:
        For Index = 0 to 7		' loop 8-bits
            Manch.0[(Index*2)] = ~ByteIn.0[Index] ' Encode bits 0,2,4,6,8,10,12,14 in Manch
    	Manch.0[(Index*2)+1] = ByteIn.0[Index]' Encode bits 1,3,5,7,9,11,13,15 in Manch
        Next Index
        Return
    
    Decode::
        For Index = 0 to 7		' loop for 8 bits
            ByteOut.0[Index] = ~Manch.0[Index<<1] ' ByteOut bits 0-7 = Manch bits 0,2,4,6,8,10,12,14
        Next Index  
        Return
    
    Main:
        CLEAR       ' Used for demo to start with all RAM clear
        ' Encode ASCII characters "A" to "F"
        Y = 0       ' Start array index pointer at 0
        FOR X = "A" to "F"
         ByteIn = X
         GOSUB Encode
         Enc_Dat[Y] = Manch
         HSEROUT ["Encoded ",ByteIn," = ",IBIN16 Enc_Dat[Y],13,10]
         Y = Y + 1  ' Increment array index pointer
        NEXT X
        
        ' Decode & print results
        FOR Y = 0 to 5
         Manch = Enc_Dat[Y]
         GOSUB Decode
         HSEROUT ["Decoded ",IBIN16 Manch," = ",ByteOut,13,10]
        NEXT Y
        PAUSE 10000
        GOTO Main
    
        END
    And here's a much smaller version. A nice choice; especially for smaller PIC's, but it's somewhat harder
    to understand at first glance if you're not familiar with .asm
    Code:
    DEFINE LOADER_USED 1
    DEFINE OSC 20
    
    ; compiled for an 18F2525. 582 words with MPASMWIN 5.01
    X           VAR BYTE
    Y           VAR BYTE
    BitCount    VAR BYTE bank0 system ' Bank0 system so we don't need an underscore
    ByteIn      VAR BYTE bank0 system ' to access BASIC variables from assembler
    ByteOut     VAR BYTE bank0 system
    Manch       VAR WORD bank0 system ' Holds manchester encoded word
    Temp        VAR WORD bank0 system ' Temp var
    Enc_Dat     VAR WORD[6]           ' Holds 6 manchester encoded words
        
        GOTO Main   ' Jump over encode/decode routines
        
    ASM  ; Note: For 14-bit core just change Rlcf to Rlf
         ; Manchester encode routine
    _Encode
    	Movlw   8
    	Movwf   BitCount
    E_Repeat
    	Rlcf    ByteIn,F   ; Rotate MSB on ByteIn into carry & test for 1
    	Btfss   STATUS,C   ; If bit = 1 then skip to BitSet
    	Goto    BitClr     ; If bit = 0 then goto to BitClr
    BitSet                 ; Bit was set, so encode 1 as 10
    	Rlcf    Manch,F
    	Rlcf    Manch+1,F
    	bcf     STATUS,C
    	Rlcf    Manch,F
    	Rlcf    Manch+1,F
    	Goto    E_Loop
    BitClr                 ; Bit was clear, so encode 0 as 01
    	Rlcf    Manch,F
    	Rlcf    Manch+1,F
    	bsf     STATUS,C
    	Rlcf    Manch,F
    	Rlcf    Manch+1,F
    E_Loop
    	Decfsz  BitCount,F
    	Goto    E_Repeat
    	Return
    ENDASM
    
    ASM
        ; Manchester decode routine.
    _Decode
    	Movf    Manch+1,W
    	Movwf   Temp+1
    	Movf    Manch,W
    	Movwf   Temp
    	Movlw   8
    	Movwf   BitCount
    Repeat
    	Rlcf    Temp,F       
    	Rlcf    Temp+1,F    
    	Rlcf    ByteOut,F    
    	Rlcf    Temp,F      
    	Rlcf    Temp+1,F    
    	Decfsz  BitCount,F
    	Goto    Repeat
    	Return
    ENDASM
    
    Main:
        CLEAR       ' Used for demo to start with all RAM clear
        ' Manchester encode ASCII characters "A" to "F"
        Y = 0       ' Start array index pointer at 0
        FOR X = "A" to "F"
         ByteIn = X
         CALL Encode
         Enc_Dat[Y] = Manch
         HSEROUT ["Encoded ",X," = ",IBIN16 Enc_Dat[Y],13,10]
         Y = Y + 1  ' Increment array index pointer
        NEXT X
        
        ' Decode & print results
        FOR Y = 0 to 5
         Manch = Enc_Dat[Y]
         CALL Decode
         HSEROUT ["Decoded ",IBIN16 Manch," = ",ByteOut,13,10]
        NEXT Y
        PAUSE 10000
        GOTO Main
        
        END
    Toss in a few bytes for preamble & synch consisting of an equal 1's & 0's before the encoded data packet,
    and you're off to the races....;}
    Regards,

    -Bruce
    tech at rentron.com
    http://www.rentron.com

  7. #7
    a_critchlow's Avatar
    a_critchlow Guest


    Did you find this post helpful? Yes | No

    Question Manch.0[(Index*2)] = ~ByteIn.0[Index]

    Thanks for that bruce, would you be able to explain the line:

    Manch.0[(Index*2)] = ~ByteIn.0[Index]

    for me please? what are the parts in [] doing?





    thanks

Similar Threads

  1. Reading in Manchester code
    By brid0030 in forum Code Examples
    Replies: 0
    Last Post: - 10th March 2009, 22:55
  2. Manchester coding question
    By oneohthree in forum mel PIC BASIC Pro
    Replies: 9
    Last Post: - 5th May 2007, 18:35
  3. 433MHz RF PIC2PIC connection
    By NavMicroSystems in forum mel PIC BASIC Pro
    Replies: 21
    Last Post: - 5th February 2006, 16:44
  4. Manchester coding
    By micro in forum General
    Replies: 1
    Last Post: - 13th January 2006, 04:40

Members who have read this thread : 1

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts