Shop OBEX P1 Docs P2 Docs Learn Events
Help with Manchester decoding — Parallax Forums

Help with Manchester decoding

BuildThingsBuildThings Posts: 31
edited 2010-03-08 13:20 in Propeller 1
I am looking for some help decoding a Manchester signal into binary using the prop. The signal is 64 bits with 1 start and 1 stop bit (total of 66 bits)

Signal specs are:

280uS / 3.57KHzPeriods


Thanks

Comments

  • tonyp12tonyp12 Posts: 1,951
    edited 2010-02-27 04:28
    Here is some ideas on how to decode that signal, using 3/4 bit time.

    http://www.eetasia.com/STATIC/PDF/200805/EEOL_2008MAY23_EMS_AN_03.pdf?SOURCES=DOWNLOAD
  • BuildThingsBuildThings Posts: 31
    edited 2010-03-03 00:10
    Tony,
    Thanks for the reply. I have worked with manchester decoding before, however I am a Spin virgin and this was perhaps a little much to take on as a "first" project with the prop. I have found lots of theory on these forums regarding bi-phase , but yet to discover any actual spin code.

    I have been tweaking counter code from some of the IR remote, RC receiver objects as well as any other place I could highjack some code from. My "swap and plop" method of coding in Spin is leaving me guessing at allot of things and its going to take some time.

    I have taken some of JohnyMac's code from his Pulse Measure object and manipulated it to the point where I am able to measure values that have some distant relation to the data that I see on my scope. However I know the timing is off and I am having a hard time figuring out what the first bit the Prop sees is, in relation to what the first bit sent actually was. For example I know my preamble is 16 identical bits, however I am not seeing 16 identical pulse times; only lets say 3 identical bits in a row are detected.

    My nominal data rate is 3.7 kB/s ~3.2 -> ~4.2. The data Word I am decoding is 64 bits that have a max duration of 312.5uSec. I am not sure clock wise what my freq should be .. or what I should be offloading to additional COGS.



    I will post somecode when I get home from work and see if I am even on the right track.

    Thanks,
    John
  • Bill HenningBill Henning Posts: 6,445
    edited 2010-03-03 14:18
    I am afraid that Spin is too slow to decode 64 bits in 312.5us ... you will have to write your code in pasm.
    BuildThings said...
    Tony,
    Thanks for the reply. I have worked with manchester decoding before, however I am a Spin virgin and this was perhaps a little much to take on as a "first" project with the prop. I have found lots of theory on these forums regarding bi-phase , but yet to discover any actual spin code.

    I have been tweaking counter code from some of the IR remote, RC receiver objects as well as any other place I could highjack some code from. My "swap and plop" method of coding in Spin is leaving me guessing at allot of things and its going to take some time.

    I have taken some of JohnyMac's code from his Pulse Measure object and manipulated it to the point where I am able to measure values that have some distant relation to the data that I see on my scope. However I know the timing is off and I am having a hard time figuring out what the first bit the Prop sees is, in relation to what the first bit sent actually was. For example I know my preamble is 16 identical bits, however I am not seeing 16 identical pulse times; only lets say 3 identical bits in a row are detected.

    My nominal data rate is 3.7 kB/s ~3.2 -> ~4.2. The data Word I am decoding is 64 bits that have a max duration of 312.5uSec. I am not sure clock wise what my freq should be .. or what I should be offloading to additional COGS.



    I will post somecode when I get home from work and see if I am even on the right track.

    Thanks,
    John
    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    www.mikronauts.com E-mail: mikronauts _at_ gmail _dot_ com 5.0" VGA LCD in stock!
    Morpheus dual Prop SBC w/ 512KB kit $119.95, Mem+2MB memory/IO kit $89.95, both kits $189.95 SerPlug $9.95
    Propteus and Proteus for Propeller prototyping 6.250MHz custom Crystals run Propellers at 100MHz
    Las - Large model assembler Largos - upcoming nano operating system
  • BuildThingsBuildThings Posts: 31
    edited 2010-03-03 23:29
    Bill,

    I might have not been so clear as to the speed, since I wrote that post from my Blackberry in DC traffic. The duration of each bit has a max of 312uS, making the complete packet (64 bits) ~24mS

    Not that it helps me much to understand my signals performance specification because I don't yet fully understand the Speed limitation of Spin code, nor the relationships between clocks rate (freq), counter speed, and code execution speed. Meaning that when the Prop is running at X speed, Y lines of code execute over T amount of time. Also is there a relationship between the counters speed (when used as a Pos/Neg detector) and clock speed (Spin Vs PASM)?


    I guess I was hoping for some code objects that were built for manchester... but I will continue to hunt and pec. I also am having some Forum anxiety posting the code I butchered from Sir JohnnyMac [noparse]:)[/noparse] . His pulse measuring code does use PASM, however its getting the raw measurement times from the COG running the PASM, decoded into the binary string.

    -John
  • localrogerlocalroger Posts: 3,452
    edited 2010-03-04 00:34
    Hi BuildThings -- A PASM instruction (typically a bit more powerful than most other ASM variants, as long as you can get your algorithm coded in 496 of them) takes 12.5 usec 50 ns to execute at 80 MHz. Spin is typically figured at about 50 times slower, so as a rule of thumb you can figure on a couple of microseconds this is correct per Spin operation. Obviously a complex expression can consist of a lot of "operations" but you can consider each line an operation, and then each assignment and each math operator used within an assignment as an operation. If you have a board you can write a few simple loops and run them a million times and time them.

    If you need to use PASM mixing Spin and PASM works much differently than on other platforms, since you can't call PASM code inline; you have to write a standalone PASM routine that waits for orders dropped in a chosen location in Hub RAM (sometimes called a mailbox, generally passed via the 'par' parameter when the cognew is issued) and the Spin code has to leave such requests and wait for the PASM code to answer by leaving the answer somewhere else and maybe clearing the request. It sounds awkward but it's also extremely powerful, since you can have multiple Spin cogs using a common PASM resource this way.

    edited to correct bonehead miscalculation of PASM instruction time

    Post Edited (localroger) : 3/4/2010 2:05:47 AM GMT
  • BuildThingsBuildThings Posts: 31
    edited 2010-03-04 01:34
    Thanks Localroger for the info. I can definitely see how powerful the combination of Spin and PASM can be. I am coming from a single processor background on the embedded hardware side, and I'm used to selecting 40 different kinds of ICs to get the job done, vice tinkering with stretching capabilities via software. Software wise I grew up from Visual Basic 3 all the way through to .Net so I have not had to ever really deal with clock speed calculations or LOW level code. The Prop is a challenge that I took on to refresh all that down and dirty microprocessor theory that has been wasting away in my brain. I appreciate the reply here. This forum seems to be a good group of people to learn from.

    Back to my original problem ....

    To decode the manchester signal, it sounds like I will need a COG that runs an PASM method that reads the input from a counter (or 2) and then places that raw input into a place in memory (a... hub address?..) that can be read in "near real time" by another COG..... does that sounds right ?


    --Manchester Decoding--

    COG 1 (SPIN)

    -Launch another COG that does the hard stuff
    -Gets the stuff from shared memory that COG 2 stored
    -Run a loop to parse the data stream into segments
    ---Identify preamble
    ---Identify data segment
    ---Do some CRC stuff
    -Send data to somewhere else to have something else done with it



    COG 2 (PASM)

    -Start up some counters
    -Get the data from the pins
    -Make the counter triggers into something useful
    -Put the something useful into memory
  • localrogerlocalroger Posts: 3,452
    edited 2010-03-04 02:14
    Build -- you've got the general idea. (BTW I was reminded by kuroneko privately that misstated the PASM instruction time up there; somehow I typed the processor cycle time instead of instruction time, and said usec instead of nsec. sheesh. Getting old sucks.) Let's see if I can avoid screwing something else up here...

    You will pass your stuff in Hub RAM. From Spin, you'll define one or more VARs. It's best if you need more than one to use an array of longs, as Spin creatively rearranges the order of variables in some cases. So you have a VAR segment and define PASM_PARMS[noparse][[/noparse]10] because you need 10 values, indexed from 0 to 9. Then you COGNEW(pasm_code, @pasm_parms). The @ tells Spin to return a pointer to where the array is at.

    On the PASM side you'll use the par register to locate pasm_parms; you can see examples of how to do this in just about every obex object that uses PASM. You'll probably want to RES pointers to your individual pasm_parms values and calculate them when the PASM code starts, so instead of having to access pasm_parms by adding 3<<2 to par, you can just refer to something meaningful like start_val. You will actually read and write to pasm_parms with the rdlong and wrlong commands. These move data between hub and cog RAM. They're special instructions that take longer to execute than regular cog instructions because they have to wait for the hub to sync to that cog, so you don't want to use Hub RAM more than necessary, but it's how you transfer data between Spin and PASM processes.

    There are many good examples of how to do this in the obex; check out the fullduplexserial or tv_text objects for example.
  • MarineCorpsCommMarineCorpsComm Posts: 8
    edited 2010-03-04 02:36
    Roger,

    Unfortunately; your correction was too late and mis-calculations caused my rocket full of kittens to be lost forever. I'm kidding of course, and thanks for the attention to detail from yourself as well as the secret forum auditors [noparse]:)[/noparse] .

    I will spend a few hours with this tonight to see what I can slap together.

    Thanks again


    -John
  • localrogerlocalroger Posts: 3,452
    edited 2010-03-04 02:44
    Oh no, not the rocket full of kittens 8-( Well, at least Captain Archer's beagle dog will have some company now.
  • BuildThingsBuildThings Posts: 31
    edited 2010-03-04 06:41
    I drew out a logical architecture to ensure I am tracking with the guidance provided. Any code snippets would be great in any of the areas.

    Thanks,
    John
  • MagIO2MagIO2 Posts: 2,243
    edited 2010-03-04 09:51
    I'm not sure wheather you need counters .. do you want to use the 3/4 decoding now?

    Then I'd say the way to go is:
    1. use waitpeq or waitpne to wait for the start-bit
    2. use the waitcnt to wait for the 3/4 clock cycle
    3. read a bit
    4. go back to 2 until all 64 bits have been read

    Of course there would be another way of decoding a manchester.
    Run a counter that counts high-time, run a counter that counts low-time of the signal
    On each high-low or low-high edge you verify the high/low-counter alternatingly. If it's a long signal you have to record the bit and flip the bit for the next record, if it's a short signal you'd simply record.
  • SapiehaSapieha Posts: 2,964
    edited 2010-03-04 11:33
    Hi MagIO2

    You said "I'm not sure wheather you need counters .. do you want to use the 3/4 decoding now?"

    It is not so simple tha only "want to use 3/4 decoding now" as Manchester code as I understand it correctly are variable speed code.
    That means as Clock periods betwen sepatarte pulses can vary - To have good Manchester code demodulator YOU need Syncronise reading on every Clock pulse.


    Regards
    Christoffer J

    Ps. With other words It is self contained code that need demodulate every Clock pulse and Data bit in its period.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Nothing is impossible, there are only different degrees of difficulty.
    For every stupid question there is at least one intelligent answer.
    Don't guess - ask instead.
    If you don't ask you won't know.
    If your gonna construct something, make it·as simple as·possible yet as versatile as posible.


    Sapieha

    Post Edited (Sapieha) : 3/4/2010 11:38:42 AM GMT
  • MagIO2MagIO2 Posts: 2,243
    edited 2010-03-04 13:02
    No, manchester transmits only one signal. In this signal clock and data is combined (by simple XOR). To be able to decode that it's very essential that the clock frequency does not change!

    So, it's not really variable frequency! But the result of encoding will have exactly 2 different high/low-times.
    If you send only 0s or only 1s, the resulting signal will have the same frequency as the clock.
    If you send 010101010101......., the resulting signal will have half of the clock frequency.

    PS:
    For decoding you can now use the fixed clock frequency to sample the signal (that's the 3/4 bit time method described in the document as linked in the second post)

    or

    you can decode by measuring the high and low times. Whenever the high or low time is 2 times the clocks high/low-time the bit has been flipped ... whenever the high or low-time is equal to the high/low-time of the clock then the same bit as before has been transferred again.

    Post Edited (MagIO2) : 3/4/2010 1:12:49 PM GMT
  • BuildThingsBuildThings Posts: 31
    edited 2010-03-04 14:08
    Thanks guys,

    I brainstormed together a notional list of decoding methods to keep track of them all in once place and when this is all said and done, we will have a single graphic (flow chart) that lists the methods/pros/cons/code etc.

    Sapieha, You are correct that the CLOCKING IS essential to being able to extract (decode) the stream. Depending on the bit rate in relation to the decoders time slippage or time slippage from the transmitting clock circuit, the decoder may have to adjust its clock sample routine to stay in sync. My thought was that with a 16 bit preamble at a bit rate of only ~ 3.2 kbS, that if I used a mid-bit method I would not drift clock enough to make a difference... at least within my 64 bit packet.


    MagIO2,

    Appreciate the feedback. I would be lying if I said I had not scoured over ever post in all forums on here with the words Manchester,bi-phase, and bit bang; to see your name in just about every thread. Since I am a newbie to the Spin/Prop, I look forward to forgetting I read all of your old posts and only asking questions you have answered somewhere else before. tongue.gif

    This forum is like a 12 step program. I know I could get my FIX from some dirty controller or language that I already know. However, every time I come back to this site and see what people are doing, and the level of inovation I remind myself that I must stay clean, and that I am powerless over the feeling of making things work the easy way (Without PASM).
    smile.gif
  • MagIO2MagIO2 Posts: 2,243
    edited 2010-03-04 14:25
    I would not use "mid bit" as name, as mid bit is the worst place to look for the information! Mid bit is where the high low or low high transition takes place. So you have a real good chance to get the wrong information at this time. Have a look into the PDF linked in the second post - it contains some good pictures which make things clearer.

    3/4 bit cycle method can be implemented allowing flexible clock timing as well. Your first bit will be a start bit. So you can use that start bit for measuring the clock-frequency and then wait for the 3/4 bit cycle of the first data bit. But that's only needed if you connect to a device that has a drifting clock-frequency. If you can be pretty sure that your device uses a fixed frequency which is not drifting to much, a sync to the start bit is enough.



    Table based?
    You want to record the whole signal and compare it to a list of 2 to the power of 64 entries??


    Post Edited (MagIO2) : 3/4/2010 2:30:18 PM GMT
  • BuildThingsBuildThings Posts: 31
    edited 2010-03-04 16:04
    MagIO,

    Correct, I was mixing too many thoughts at once. What I meant to describe was using the Mid-bits to extract the clock. I was not sure if I would have to use the extracted clock, perhaps even in another COG to invoke the sampling of the data in another COG.

    Center Sampling is sampling at the time furthest from the signal transition. Therefore center sampling in Manchester occurs at points 1/4 and 3/4 through the cell, since transitions occur always at mid-bit and sometimes on the cell boundary.


    Regarding the tables:

    I had seen several examples of people creating two tables with 256 entries. One table is a direct mapping of an 8-bit byte into a 16-bit Manchester encoding of the byte. The second table is a mapping of a Manchester encoded 8-bit byte to 4 decoded bits.

    Some other more protocol/implementation specific tables link a specific manchester encoded bit pattern directly to a predefined value. This in my case would actually work ok since I am only receiving packets from a sensor that has a very predefined set of values. I would much rather build an object that I can adjust and reuse though .


    I had looked through that PDF, as well as like 10 others. My problem is more learning how to do it in Spin.

    I will have it completed by tonight and will post my code for critique.

    -John
  • phishguyphishguy Posts: 36
    edited 2010-03-04 17:26
    I don't remember the exact name of the topic, but there was a simple RFID reader that did manchester decoding with the Propeller on this forum somewhere. If you look at that, it may give you some ideas.

    I would like to do something similar decoding a 134.2 kHz biphase RFID tag (FDXB).··Unfortunately, my skills are not sufficient to accomplish this task.
  • LawsonLawson Posts: 870
    edited 2010-03-04 22:57
    Imho, spin should be fast enough to decode this signal IF you use a streamlined decoding algorithm and have time between packets to finish up the decoding. I've made several spin loops that cycle at 4kHz and one stripped down loop that cycles at up to 12kHz! If you're not sure of the speed of your code, how about making a short function to run in a separate cog that outputs a slower version of your test signal on a spare pin? You can then test that your decoding algorithm works without before having to worry if the code works fast enough.

    Lawson

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Lunch cures all problems! have you had lunch?
  • BuildThingsBuildThings Posts: 31
    edited 2010-03-04 23:26
    Thanks Lawson,

    I appreciate the info. I am working with a 3.52KHz signal, so from what you have tested I should be able to make it work with Spin. If I can't I will just pull out the PASM guide and start playing with that.

    - John
  • HannoHanno Posts: 1,130
    edited 2010-03-08 06:54
    Manchester encoding is fun!
    This provides a nice demo of ViewPort's power. Here's what I came up with in half an hour:
    {***************************************************
    * (C) 2010 HannoWare.com, Inc.                     *
    * Machester Encoding Tutorial                      *
    * AppletImage=scope.gif                            *
    ****************************************************
    Generate and decode Manchester encoded signals.
    Run this with ViewPort v4.2+
    Use the dOut box to send a specified value in Manchester encoding.
    You'll see the sequence and the decoded value.}
    CON
     _clkmode     = xtal1 + pll16x
     _xinfreq        = 5_000_000         'use standard 5MHz clock
     ManPin=16
     dbgPin=17
    OBJ                                  'include 2 ViewPort objects:
     vp    : "Conduit"                   'transfers data to/from PC
     qs    : "QuickSample"               'samples INA continuously in 1 cog- up to 20Msps
    VAR
      long period                        'period of clock
      long dataOut                       '32 bits of data to write
      long dataIn                        '32 bits of read data
      long frame[noparse][[/noparse]400]                    'stores measurements of INA port
      long stack[noparse][[/noparse]100]                    'stack for decode cog
    pub generateManchester|d,tcnt
     vp.register(qs.sampleINA(@frame,1)) 'sample INA into <frame> array
     optional_configure_viewport         'optionally configure viewport's interface   
     vp.share(@dataOut,@dataIn)          'share the data variables 
     dira[noparse][[/noparse]ManPin]~~                      'output pulses on pin 16
     cognew(decodeManchester,@stack)     'start a cog decode the code
     period:=clkfreq/(3520*2)            'period is twice clkfreq/frequency
     tcnt:=cnt+period
    
     repeat
      d:=dataOut
      outa[noparse][[/noparse]ManPin]~~
      repeat 32                          'start with 1
        if d & 1                         'output lsb first
          waitcnt(tcnt+=period)          'on a 1, output rising
          outa[noparse][[/noparse]ManPin]~
          waitcnt(tcnt+=period)
          outa[noparse][[/noparse]ManPin]~~
        else                             'on a 0, output falling
          waitcnt(tcnt+=period)          
          outa[noparse][[/noparse]ManPin]~~
          waitcnt(tcnt+=period)
          outa[noparse][[/noparse]ManPin]~
        d>>=1                            'rotate right to get next highest bit    
      outa[noparse][[/noparse]ManPin]~                      'leave at 0
      waitcnt(tcnt+=period*100)
    pub decodeManchester|d,tcnt
     dira[noparse][[/noparse]dbgPin]~~ 
     repeat
      waitpeq(|<ManPin,|<ManPin,0)       'wait for begin of code
      tcnt:=cnt-period*1/2               'delay into middle of bit
      d~
      repeat 32
        waitcnt(tcnt+=period*2)
        if not ina[noparse][[/noparse]ManPin]               'input lsb first
          d+=1
        d->=1                            'rotate right to get next highest bit
      dataIn:=d
      !outa[noparse][[/noparse]dbgPin]
      waitcnt(tcnt+=period*10)           
    pub optional_configure_viewport  
     vp.config(string("var:io(bits=[noparse][[/noparse]16sig,17dbg]),dOut(base=16),dIn(base=16)"))
     'view IO pins, and dOut,dIn in hex
     vp.config(string("lsa:view=io,timescale=1ms,trigger=io[noparse][[/noparse]16]r"))
     'view with lsa- timescale set to 1ms, triggered on pin 16 rise
     vp.config(string("edit:dOut(mode=text,default=85)"))
     'edit the dOut variable with a textbox
     vp.config(string("start:lsa"))
     'start in lsa view
    
    



    It lets a user specify a 32bit value to transmit on pin 16 in Manchester encoding. It uses another cog to decode data on that cog- hopefully it arrives at the same number! (it does)
    It's all in simple spin- plenty fast for both the generation and decoding. Attached is a screenshot- notice that with a $55 pattern, the beginning sequence is as slow as possible. Later, the sequence transitions twice as fast- once for every 0. This will be in future versions of ViewPort- or paste from above and try it out!
    Hanno

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Co-author of the official Propeller Guide- available at Amazon
    Developer of ViewPort, the premier visual debugger for the Propeller (read the review here, thread here),
    12Blocks, the block-based programming environment (thread here)
    and PropScope, the multi-function USB oscilloscope/function generator/logic analyzer
    816 x 540 - 81K
  • MagIO2MagIO2 Posts: 2,243
    edited 2010-03-08 08:25
    @Hanno,

    ViewPort looks great ... guess sooner or later I have to purchase a copy.

    But somehow the attached picture looks strange. Shouldn't the pulse and pause-times for the $0000_00-part of the long be identical? It's obviously because of scaling the signal down/up to the size of the window. Is ther a mode where you only scale by non-fractional scaling factor?

    PS:
    Can you try the same with $AA? I think it would be better to send a start-bit first!
    Code of reading then could be made timing independent·by measuring the length of the first pause.


    Post Edited (MagIO2) : 3/8/2010 8:31:47 AM GMT
  • HannoHanno Posts: 1,130
    edited 2010-03-08 08:35
    Hi,
    I used the 1ms timescale to show all 32 encoded bits on one screen. Of course you can select a faster timescale to more accurately analyze the individual pulse lengths.
    I'll take more screen-shots and post a tutorial of steps I took to get to the result. I'll show different patterns- but notice that I start and stop the sequence with 1 and 0.
    Hanno

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Co-author of the official Propeller Guide- available at Amazon
    Developer of ViewPort, the premier visual debugger for the Propeller (read the review here, thread here),
    12Blocks, the block-based programming environment (thread here)
    and PropScope, the multi-function USB oscilloscope/function generator/logic analyzer
  • BuildThingsBuildThings Posts: 31
    edited 2010-03-08 13:20
    @Hanno,

    Much appreciated !

    I have been using Viewport and the Parallax USB scope. I CAN'T wait to get my USB Prop Scope in the mail tomorrow. I know you put a ton of work into the new scopes HW/SW design.

    What equivalence does the software that comes with the Prop Scope have to Viewpoint?

    -John
Sign In or Register to comment.