+ Reply to Thread
Results 1 to 24 of 24
  1. #1
    Join Date
    Sep 2003
    Location
    INDIA
    Posts
    161

    Question Manchester Coding / Decodeing for RF Modules

    Hello all,

    I was looking for some example on Manchester Coding and Decoding for use with RF Modules.

    Want to elimate the Holtek ICs

    Any help

    Thank you.

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

    Default

    Here is the secret of Manchester encoding/decoding in all it's simplicity... (in case any other reader wants to know why - it's to balance the data slicer in the receiver and help cancel out noise).

    Encoding: 8 bit byte becomes 16 bits to transmit... zero's become "01" and ones become "10".

    Decoding: 16 bits get deconstructed back to 8 bit byte... "01" gets turned back into a zero and "10" gets turned back into a one.

    Example... you are sending byte $00 which is equal to %00000000... this get's turned into %0101010101010101.

    Melanie

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

    Default Thank you Melanie

    Thank you for the information on Manchester.

    But could you please explain me with a small example how this word is constructed for sending and how it is decoded when received.

    Basically I am looking at hooking a PIC12C508 to the RF modules and trying to send and receive Mancheseter codes over RF.

    Thank you.

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

    Default

    Very quick example (Caveat Emptor) since it's two-thirty in the morning and time I was getting my beauty sleep... there's probably better ways of doing this, but with matchsticks propping up my eyelids this is the best you're going to get out of me tonight...

    CounterA var Byte
    ErrorFlag var Bit
    MyData var Byte
    ManchesterWord var Word

    ' 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
    Return

    Melanie

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

    Default Sending Out and Receiving

    Thank you very much for the same.

    Last but not the least. How do I send it and Rx the same.

    Thank for all that help.

    I am sure this code and your inputs have helped a lot out there, especially me.

    I shall try it and get back to you when I rx this information

    regards

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

    Default Another way to encode

    Hello all / Melanie

    I found this on the internet hope this also helps all.

    Manchester encoding can be done in PBP nice and easy:
    From: Ioannis Kyriakidis (I presume)

    For d=0 TO 7
    IF v.0[d]=0 Then
    encoded.0[d*2]=0
    encoded.0[d*2+1]=1
    Else
    encoded.0[d*2]=1
    encoded.0[d*2+1]=0
    EndIF
    Next

    d: number of bits to encode (8 bits)
    v: byte to BE encoded
    encoded: WORD sized variable holding the encoded
    byte v.

    Note that the encoded value is double size always.

    Use the above lines as subroutine to encode a byte before transmission

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

    Angry

    Mel,
    Loooking at your code I'm a bit stumped.

    How is each BIT in the MyData referenced to CounterA?

    Also.... It looks like you are shifting through each BIT on Mydata on the last line:
    MyData=MyData>1

    But shouldn't it be: MyData=MyData>>1

    I have read your FAQ on Bits, bytes and Words, but I can't relate your code here to the examples given in the FAQ.

    But otherwise, the code looks like it should work.

    Cheers
    J

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

    Default

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

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

    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

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

    Thumbs up

    Thank you for your contribution ,Squibcakes.

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

    regards

  11. #11
    a_critchlow's Avatar
    a_critchlow Guest

    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.

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

    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

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

    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

  14. #14
    a_critchlow's Avatar
    a_critchlow Guest

    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

  15. #15
    a_critchlow's Avatar
    a_critchlow Guest

    Post ByteOut.0[Index] = ~Manch.0[Index<<1]

    hi again, i have figured out how the encode part of the code works, i still cant get the last bit into my head though. The decodeing.

    ByteOut.0[Index] = ~Manch.0[Index<<1]



    After the equal sign it says to me when counter at 0, NOT Manch.0[Index<<1]. does this mean index(0) left one equaling 0? or shift left on Manch?





    thanks.

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

    Default

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

    If Index = 1 this would be Manch.bit2 = NOT ByteIn.bit1
    Regards,

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

  17. #17
    a_critchlow's Avatar
    a_critchlow Guest

    Post [Index<<1]

    what about ByteOut.0[Index] = ~Manch.0[Index<<1]


    i dont get the [Index<<1] part?









    thanks again

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

    Default

    ByteOut.0[Index] = ~Manch.0[Index<<1]

    This just shifts the bit index pointer left by 1. If you run this with a serial connection, MCS ICD, or through MPLAB sim you can see how everything is working.
    Regards,

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

  19. #19
    a_critchlow's Avatar
    a_critchlow Guest

    Post hmmm

    to if index starts off and is equal to 0, this is shifted left to 1 and invert the value at 1 to give you the value for 0? this done each time to make up the 8bits.

    If you take the encoded bit stream(example): 100110 and run it through the code it will come out like this: 100 (this is wrong as it should be 101)?



    many thanks

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

    Default

    How did you get 100 from %00100110?

    The routines I posted take an 8-bit number as the input, and return a 16-bit encoded result.

    ASCII characters A to F
    ..................... input............encoded output..........
    Encoded A = %01000001 = %01 10 01 01 01 01 01 10
    Encoded B = %01000010 = %01 10 01 01 01 01 10 01
    Encoded C = %01000011 = %01 10 01 01 01 01 10 10
    Encoded D = %01000100 = %01 10 01 01 01 10 01 01
    Encoded E = %01000101 = %01 10 01 01 01 10 01 10
    Encoded F = %01000110 = %01 10 01 01 01 10 10 01

    If I feed in your value %00100110. I get %0101100101101001
    Regards,

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

  21. #21
    a_critchlow's Avatar
    a_critchlow Guest

    Post <<1

    i going from encoded to decoding..

    the code says at counter 0 put into byteout.0 = invert of index pointer left 1.

    this inverts a 1 to give you 0 when it should be 1.

    it seems that you need to invert the first bit of the encoded data before you start moving through the rest of the code with <<1






    regards
    andrew

  22. #22
    kireytir's Avatar
    kireytir Guest

    Unhappy

    Encode:
    For d = 0 to 3 ' 4 bit
    if v.0[d]=0 Then
    encoded.0[d*2]=0
    encoded.0[d*2+1]=1
    else
    encoded.0[d*2]=1
    encoded.0[d*2+1]=0
    endif
    next
    serout2 portb.0,396,[%1000,encoded]
    goto basla
    'd: number of bits to encode (8 bits)
    'v: byte to BE encoded
    'encoded: WORD sized variable holding the encoded
    'byte v.


    im using this manchester encoding but i didnt decode this pls help..

  23. #23
    Join Date
    Nov 2003
    Location
    Greece
    Posts
    2,914

    Default

    Here are the two subroutines to encode and decode the bi-phase or manchester scheme.

    It works for sure.

    Ioannis
    Attached Files Attached Files

  24. #24
    Skyjumper's Avatar
    Skyjumper Guest

    Default

    Even after years still usefull... I was reading this topic, cause I am searching for a true solution. In this topic I miss the 90 degrees phase shifting, I think only bytesize is doubled here. I read somewhere else that Manchester code is a bi-phase code with not only transitions on the beginning of a bit, but at the center of a bit as well. It is defined as a transition orientated code, not a bit orientated. But maybe I am wrong here, cause I am quite new to this, so can anyone explain me please ?

Similar Threads

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

Members who have read this thread : 10

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