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

Manchester decoding

tukituki Posts: 10
edited 2009-05-19 23:39 in Propeller 1
I was wondering if there was anyone than can help me out with a problem I am having. I built an RFID reader and now I have to decode the data from the tag. Attached is the data sheet for the tags I am using. From what I understand, the tag sends back it's information encoded in Manchester. Basically a transition from logic low to logic high is considered a binary 1 and a transition from logic high to logic low is considered a 0. The data sheet explains this in greater detail but that's the idea. I am going to be honest and admit that I am not very good at programming and I have never used the Propeller before.

I know what I have to do I just do not know how to translate it in code and since I have never used Spin my problem becomes that much worse. This is how my reader works:

When there is no tag near the antenna, the output is always high (between 5 and 6 volts). When the tag gets in the readers range, the output sends back 9 1's (so low to high nine times) and then the data, 64 bits in total including the initial ones, and it keeps resending the data as long as it is in the range. What I have to do is, once the data starts transmitting, read what state the output is in, either low or high (logic 0 or logic 1), whenever there is a rising edge on the clock.

Pretty simple I know but I don't know spin and I have to finish this project by next week or else i will not graduate. What I want for the program to do is wait until there is a falling edge in the input data and branch to a subroutine where every time there is a rising edge in the external clock the program saves the data, either logic low or high, 64 times since there are 64 bits of data being sent from the tag. After all 64 bits have been saved I would have to wait until the tag leaves the range at which point the input data goes back to high. If there's any way of checking for a pulse in one of the pins of the micro would be perfect for that.

If someone could help me out with this i would greatly appreciate it since i do not know any of the commands for the propeller or its capabilities. Thank you in advance.

Victor


Victor

Comments

  • tonyp12tonyp12 Posts: 1,951
    edited 2009-05-16 13:52
    A manchester byte is only 4 bits of real data.

    As·a 8bit data-byte is manchester-encoded to 16bits to make sure there are no 1 or 0 twice in a row.

    A 256 entry lookup table would be fast, anyone have a source for such a table?


    http://www.quickbuilder.co.uk/qb/articles/index.htm

    Post Edited (tonyp12) : 5/16/2009 2:13:09 PM GMT
  • MagIO2MagIO2 Posts: 2,243
    edited 2009-05-16 22:17
    Hi tuki!

    So you want to tell us that they only gave you one week for this project including learning a programming language? Hmmm ... not sure if I'll believe you. My guess is that you were to lazy to start earlier and now you want us to do your work.

    I'd say ctra and ctrb are your friends for this task, together with waitpeq/waitpne. If you have a look at the signal, you can see that you simply have to detect the long pulse or the long pause for·switching from reading 1 to reading 0 (or from 0 to 1). If the pulse or the pause is short you simply repeat shifting in the same bit as before.

    In the beginning we expect nine 1 bits to be send. So with each low edge, we·received an additional·1. We only measure the time that the signal is high, because if we find a longer high-time·we know that we received a 0 bit. Now with each low-high edge we received an additional 0. We masure the low-time and if it is longer we received a 1.

    This pretty much looks like a·perfect usecase for a state machine.

    Counter A would be setup as a POS detector, counter B as a NEG detector. This way, the hardware is taking care of measuring the time. You can find a nice Application note for Counters in the download-section called "AN001 - Propeller Counters". There you can also find code examples on how to setup the counters.


    ·
  • tukituki Posts: 10
    edited 2009-05-17 02:05
    Hey MagI02,

    I honestly haven't been lazy. I tried to use another micro for my project but i could not get it to work. I think the micro was just to slow for what i wanted to do. A friend of mine recently lent me his propeller because he said it would be fast enough but he didn't show me how to use it and he left back home tongue.gif. I am honestly trying my best to do it by myself. Here's what I have so far but when I open the terminal, I am supposed to get the same data when the tag is in the readers range but when I pass the tag more than once I don't get the same data. Here's what I have so far:

    
    CON
    _clkmode = xtal1 + pll16x
    _xinfreq = 5_000_000
    
    CLOCK_PIN = 2
    DATA_PIN = 0
    X = 1
    VAR
    byte STR[noparse][[/noparse]64]
    
    OBJ
    ser: "FullDuplexSerial"
    
    PUB start
    DIRA[noparse][[/noparse]CLOCK_PIN]~
    DIRA[noparse][[/noparse]DATA_PIN]~
    ser.start(31, 30, 1, 9600)
    repeat
      waitpeq(%0000, |< DATA_PIN, 0) 'Wait for DATA_PIN  to go low
        repeat X
          waitpeq (%100, |< CLOCK_PIN, 0) 'Wait for Clock to go high
          STR[noparse][[/noparse]0] := INA[noparse][[/noparse]DATA_PIN]  
          waitpne (%000, |< CLOCK_PIN, 0) 'Wait for Clock to go low
          waitpeq (%100, |< CLOCK_PIN, 0) 'Wait for Clock to go high
          STR := INA[noparse][[/noparse]DATA_PIN]  
          waitpne (%000, |< CLOCK_PIN, 0) 'Wait for Clock to go low
          waitpeq (%100, |< CLOCK_PIN, 0) 'Wait for Clock to go high
          STR := INA[noparse][[/noparse]DATA_PIN]  
          waitpne (%000, |< CLOCK_PIN, 0) 'Wait for Clock to go low
          waitpeq (%100, |< CLOCK_PIN, 0) 'Wait for Clock to go high
          STR := INA[noparse][[/noparse]DATA_PIN]  
          waitpne (%000, |< CLOCK_PIN, 0) 'Wait for Clock to go low
          waitpeq (%100, |< CLOCK_PIN, 0) 'Wait for Clock to go high
          STR := INA[noparse][[/noparse]DATA_PIN]  
          waitpne (%000, |< CLOCK_PIN, 0) 'Wait for Clock to go low
          waitpeq (%100, |< CLOCK_PIN, 0) 'Wait for Clock to go high
          STR := INA[noparse][[/noparse]DATA_PIN]  
          waitpne (%000, |< CLOCK_PIN, 0) 'Wait for Clock to go low
          waitpeq (%100, |< CLOCK_PIN, 0) 'Wait for Clock to go high
          STR[noparse][[/noparse]6] := INA[noparse][[/noparse]DATA_PIN]  
          waitpne (%000, |< CLOCK_PIN, 0) 'Wait for Clock to go low
          waitpeq (%100, |< CLOCK_PIN, 0) 'Wait for Clock to go high
          STR[noparse][[/noparse]7] := INA[noparse][[/noparse]DATA_PIN]  
          waitpne (%000, |< CLOCK_PIN, 0) 'Wait for Clock to go low
          waitpeq (%100, |< CLOCK_PIN, 0) 'Wait for Clock to go high
          STR[noparse][[/noparse]8] := INA[noparse][[/noparse]DATA_PIN]  
          waitpne (%000, |< CLOCK_PIN, 0) 'Wait for Clock to go lo
          waitpeq (%100, |< CLOCK_PIN, 0) 'Wait for Clock to go high
          STR[noparse][[/noparse]9] := INA[noparse][[/noparse]DATA_PIN]  
          waitpne (%000, |< CLOCK_PIN, 0) 'Wait for Clock to go low
          waitpeq (%100, |< CLOCK_PIN, 0) 'Wait for Clock to go high
          STR[noparse][[/noparse]10] := INA[noparse][[/noparse]DATA_PIN]  
          waitpne (%000, |< CLOCK_PIN, 0) 'Wait for Clock to go low
          waitpeq (%100, |< CLOCK_PIN, 0) 'Wait for Clock to go high
          STR[noparse][[/noparse]11] := INA[noparse][[/noparse]DATA_PIN]  
          waitpne (%000, |< CLOCK_PIN, 0) 'Wait for Clock to go low
          waitpeq (%100, |< CLOCK_PIN, 0) 'Wait for Clock to go high
          STR[noparse][[/noparse]12] := INA[noparse][[/noparse]DATA_PIN]  
          waitpne (%000, |< CLOCK_PIN, 0) 'Wait for Clock to go low
          waitpeq (%100, |< CLOCK_PIN, 0) 'Wait for Clock to go high
          STR[noparse][[/noparse]13] := INA[noparse][[/noparse]DATA_PIN]  
          waitpne (%000, |< CLOCK_PIN, 0) 'Wait for Clock to go low
          waitpeq (%100, |< CLOCK_PIN, 0) 'Wait for Clock to go high
          STR[noparse][[/noparse]14] := INA[noparse][[/noparse]DATA_PIN]  
          waitpne (%000, |< CLOCK_PIN, 0) 'Wait for Clock to go low
          waitpeq (%100, |< CLOCK_PIN, 0) 'Wait for Clock to go high
          STR[noparse][[/noparse]15] := INA[noparse][[/noparse]DATA_PIN]  
          waitpne (%000, |< CLOCK_PIN, 0) 'Wait for Clock to go low
          waitpeq (%100, |< CLOCK_PIN, 0) 'Wait for Clock to go high
          STR[noparse][[/noparse]16] := INA[noparse][[/noparse]DATA_PIN]  
          waitpne (%000, |< CLOCK_PIN, 0) 'Wait for Clock to go low
          waitpeq (%100, |< CLOCK_PIN, 0) 'Wait for Clock to go high
          STR[noparse][[/noparse]17] := INA[noparse][[/noparse]DATA_PIN]  
          waitpne (%000, |< CLOCK_PIN, 0) 'Wait for Clock to go low
          waitpeq (%100, |< CLOCK_PIN, 0) 'Wait for Clock to go high
          STR[noparse][[/noparse]18] := INA[noparse][[/noparse]DATA_PIN]  
          waitpne (%000, |< CLOCK_PIN, 0) 'Wait for Clock to go lo
          waitpeq (%100, |< CLOCK_PIN, 0) 'Wait for Clock to go high
          STR[noparse][[/noparse]19] := INA[noparse][[/noparse]DATA_PIN]  
          waitpne (%000, |< CLOCK_PIN, 0) 'Wait for Clock to go low
          waitpeq (%100, |< CLOCK_PIN, 0) 'Wait for Clock to go high
          STR[noparse][[/noparse]20] := INA[noparse][[/noparse]DATA_PIN]  
          waitpne (%000, |< CLOCK_PIN, 0) 'Wait for Clock to go low
          waitpeq (%100, |< CLOCK_PIN, 0) 'Wait for Clock to go high
          STR[noparse][[/noparse]21] := INA[noparse][[/noparse]DATA_PIN]  
          waitpne (%000, |< CLOCK_PIN, 0) 'Wait for Clock to go low
          waitpeq (%100, |< CLOCK_PIN, 0) 'Wait for Clock to go high
          STR[noparse][[/noparse]22] := INA[noparse][[/noparse]DATA_PIN]  
          waitpne (%000, |< CLOCK_PIN, 0) 'Wait for Clock to go low
          waitpeq (%100, |< CLOCK_PIN, 0) 'Wait for Clock to go high
          STR[noparse][[/noparse]23] := INA[noparse][[/noparse]DATA_PIN]  
          waitpne (%000, |< CLOCK_PIN, 0) 'Wait for Clock to go low
          waitpeq (%100, |< CLOCK_PIN, 0) 'Wait for Clock to go high
          STR[noparse][[/noparse]24] := INA[noparse][[/noparse]DATA_PIN]  
          waitpne (%000, |< CLOCK_PIN, 0) 'Wait for Clock to go low
          waitpeq (%100, |< CLOCK_PIN, 0) 'Wait for Clock to go high
          STR[noparse][[/noparse]25] := INA[noparse][[/noparse]DATA_PIN]  
          waitpne (%000, |< CLOCK_PIN, 0) 'Wait for Clock to go low
          waitpeq (%100, |< CLOCK_PIN, 0) 'Wait for Clock to go high
          STR[noparse][[/noparse]26] := INA[noparse][[/noparse]DATA_PIN]  
          waitpne (%000, |< CLOCK_PIN, 0) 'Wait for Clock to go low
          waitpeq (%100, |< CLOCK_PIN, 0) 'Wait for Clock to go high
          STR[noparse][[/noparse]27] := INA[noparse][[/noparse]DATA_PIN]  
          waitpne (%000, |< CLOCK_PIN, 0) 'Wait for Clock to go low
          waitpeq (%100, |< CLOCK_PIN, 0) 'Wait for Clock to go high
          STR[noparse][[/noparse]28] := INA[noparse][[/noparse]DATA_PIN]  
          waitpne (%000, |< CLOCK_PIN, 0) 'Wait for Clock to go lo
          waitpeq (%100, |< CLOCK_PIN, 0) 'Wait for Clock to go high
          STR[noparse][[/noparse]29] := INA[noparse][[/noparse]DATA_PIN]  
          waitpne (%000, |< CLOCK_PIN, 0) 'Wait for Clock to go low
          waitpeq (%100, |< CLOCK_PIN, 0) 'Wait for Clock to go high
          STR[noparse][[/noparse]30] := INA[noparse][[/noparse]DATA_PIN]  
          waitpne (%000, |< CLOCK_PIN, 0) 'Wait for Clock to go low
          waitpeq (%100, |< CLOCK_PIN, 0) 'Wait for Clock to go high
          STR[noparse][[/noparse]31] := INA[noparse][[/noparse]DATA_PIN]  
          waitpne (%000, |< CLOCK_PIN, 0) 'Wait for Clock to go low
          waitpeq (%100, |< CLOCK_PIN, 0) 'Wait for Clock to go high
          STR[noparse][[/noparse]32] := INA[noparse][[/noparse]DATA_PIN]  
          waitpne (%000, |< CLOCK_PIN, 0) 'Wait for Clock to go low
          waitpeq (%100, |< CLOCK_PIN, 0) 'Wait for Clock to go high
          STR[noparse][[/noparse]33] := INA[noparse][[/noparse]DATA_PIN]  
          waitpne (%000, |< CLOCK_PIN, 0) 'Wait for Clock to go low
          waitpeq (%100, |< CLOCK_PIN, 0) 'Wait for Clock to go high
          STR[noparse][[/noparse]34] := INA[noparse][[/noparse]DATA_PIN]  
          waitpne (%000, |< CLOCK_PIN, 0) 'Wait for Clock to go low
          waitpeq (%100, |< CLOCK_PIN, 0) 'Wait for Clock to go high
          STR[noparse][[/noparse]35] := INA[noparse][[/noparse]DATA_PIN]  
          waitpne (%000, |< CLOCK_PIN, 0) 'Wait for Clock to go low
          waitpeq (%100, |< CLOCK_PIN, 0) 'Wait for Clock to go high
          STR[noparse][[/noparse]36] := INA[noparse][[/noparse]DATA_PIN]  
          waitpne (%000, |< CLOCK_PIN, 0) 'Wait for Clock to go low
          waitpeq (%100, |< CLOCK_PIN, 0) 'Wait for Clock to go high
          STR[noparse][[/noparse]37] := INA[noparse][[/noparse]DATA_PIN]  
          waitpne (%000, |< CLOCK_PIN, 0) 'Wait for Clock to go low
          waitpeq (%100, |< CLOCK_PIN, 0) 'Wait for Clock to go high
          STR[noparse][[/noparse]38] := INA[noparse][[/noparse]DATA_PIN]  
          waitpne (%000, |< CLOCK_PIN, 0) 'Wait for Clock to go lo
          waitpeq (%100, |< CLOCK_PIN, 0) 'Wait for Clock to go high
          STR[noparse][[/noparse]39] := INA[noparse][[/noparse]DATA_PIN]  
          waitpne (%000, |< CLOCK_PIN, 0) 'Wait for Clock to go low
          waitpeq (%100, |< CLOCK_PIN, 0) 'Wait for Clock to go high
          STR[noparse][[/noparse]40] := INA[noparse][[/noparse]DATA_PIN]  
          waitpne (%000, |< CLOCK_PIN, 0) 'Wait for Clock to go low
          waitpeq (%100, |< CLOCK_PIN, 0) 'Wait for Clock to go high
          STR[noparse][[/noparse]41] := INA[noparse][[/noparse]DATA_PIN]  
          waitpne (%000, |< CLOCK_PIN, 0) 'Wait for Clock to go low
          waitpeq (%100, |< CLOCK_PIN, 0) 'Wait for Clock to go high
          STR[noparse][[/noparse]42] := INA[noparse][[/noparse]DATA_PIN]  
          waitpne (%000, |< CLOCK_PIN, 0) 'Wait for Clock to go low
          waitpeq (%100, |< CLOCK_PIN, 0) 'Wait for Clock to go high
          STR[noparse][[/noparse]43] := INA[noparse][[/noparse]DATA_PIN]  
          waitpne (%000, |< CLOCK_PIN, 0) 'Wait for Clock to go low
          waitpeq (%100, |< CLOCK_PIN, 0) 'Wait for Clock to go high
          STR[noparse][[/noparse]44] := INA[noparse][[/noparse]DATA_PIN]  
          waitpne (%000, |< CLOCK_PIN, 0) 'Wait for Clock to go low
          waitpeq (%100, |< CLOCK_PIN, 0) 'Wait for Clock to go high
          STR[noparse][[/noparse]45] := INA[noparse][[/noparse]DATA_PIN]  
          waitpne (%000, |< CLOCK_PIN, 0) 'Wait for Clock to go low
          waitpeq (%100, |< CLOCK_PIN, 0) 'Wait for Clock to go high
          STR[noparse][[/noparse]46] := INA[noparse][[/noparse]DATA_PIN]  
          waitpne (%000, |< CLOCK_PIN, 0) 'Wait for Clock to go low
          waitpeq (%100, |< CLOCK_PIN, 0) 'Wait for Clock to go high
          STR[noparse][[/noparse]47] := INA[noparse][[/noparse]DATA_PIN]  
          waitpne (%000, |< CLOCK_PIN, 0) 'Wait for Clock to go low
          waitpeq (%100, |< CLOCK_PIN, 0) 'Wait for Clock to go high
          STR[noparse][[/noparse]48] := INA[noparse][[/noparse]DATA_PIN]  
          waitpne (%000, |< CLOCK_PIN, 0) 'Wait for Clock to go lo
          waitpeq (%100, |< CLOCK_PIN, 0) 'Wait for Clock to go high
          STR[noparse][[/noparse]49] := INA[noparse][[/noparse]DATA_PIN]  
          waitpne (%000, |< CLOCK_PIN, 0) 'Wait for Clock to go low
          waitpeq (%100, |< CLOCK_PIN, 0) 'Wait for Clock to go high
          STR[noparse][[/noparse]50] := INA[noparse][[/noparse]DATA_PIN]  
          waitpne (%000, |< CLOCK_PIN, 0) 'Wait for Clock to go low
          waitpeq (%100, |< CLOCK_PIN, 0) 'Wait for Clock to go high
          STR[noparse][[/noparse]51] := INA[noparse][[/noparse]DATA_PIN]  
          waitpne (%000, |< CLOCK_PIN, 0) 'Wait for Clock to go low
          waitpeq (%100, |< CLOCK_PIN, 0) 'Wait for Clock to go high
          STR[noparse][[/noparse]52] := INA[noparse][[/noparse]DATA_PIN]  
          waitpne (%000, |< CLOCK_PIN, 0) 'Wait for Clock to go low
          waitpeq (%100, |< CLOCK_PIN, 0) 'Wait for Clock to go high
          STR[noparse][[/noparse]53] := INA[noparse][[/noparse]DATA_PIN]  
          waitpne (%000, |< CLOCK_PIN, 0) 'Wait for Clock to go low
          waitpeq (%100, |< CLOCK_PIN, 0) 'Wait for Clock to go high
          STR[noparse][[/noparse]54] := INA[noparse][[/noparse]DATA_PIN]  
          waitpne (%000, |< CLOCK_PIN, 0) 'Wait for Clock to go low
          waitpeq (%100, |< CLOCK_PIN, 0) 'Wait for Clock to go high
          STR[noparse][[/noparse]55] := INA[noparse][[/noparse]DATA_PIN]  
          waitpne (%000, |< CLOCK_PIN, 0) 'Wait for Clock to go low
          waitpeq (%100, |< CLOCK_PIN, 0) 'Wait for Clock to go high
          STR[noparse][[/noparse]56] := INA[noparse][[/noparse]DATA_PIN]  
          waitpne (%000, |< CLOCK_PIN, 0) 'Wait for Clock to go low
          waitpeq (%100, |< CLOCK_PIN, 0) 'Wait for Clock to go high
          STR[noparse][[/noparse]57] := INA[noparse][[/noparse]DATA_PIN]  
          waitpne (%000, |< CLOCK_PIN, 0) 'Wait for Clock to go low
          waitpeq (%100, |< CLOCK_PIN, 0) 'Wait for Clock to go high
          STR[noparse][[/noparse]58] := INA[noparse][[/noparse]DATA_PIN]  
          waitpne (%000, |< CLOCK_PIN, 0) 'Wait for Clock to go lo
          waitpeq (%100, |< CLOCK_PIN, 0) 'Wait for Clock to go high
          STR[noparse][[/noparse]59] := INA[noparse][[/noparse]DATA_PIN]  
          waitpne (%000, |< CLOCK_PIN, 0) 'Wait for Clock to go low
          waitpeq (%100, |< CLOCK_PIN, 0) 'Wait for Clock to go high
          STR[noparse][[/noparse]60] := INA[noparse][[/noparse]DATA_PIN]  
          waitpne (%000, |< CLOCK_PIN, 0) 'Wait for Clock to go low
          waitpeq (%100, |< CLOCK_PIN, 0) 'Wait for Clock to go high
          STR[noparse][[/noparse]61] := INA[noparse][[/noparse]DATA_PIN]  
          waitpne (%000, |< CLOCK_PIN, 0) 'Wait for Clock to go low
          waitpeq (%100, |< CLOCK_PIN, 0) 'Wait for Clock to go high
          STR[noparse][[/noparse]62] := INA[noparse][[/noparse]DATA_PIN]  
          waitpne (%000, |< CLOCK_PIN, 0) 'Wait for Clock to go low
          waitpeq (%100, |< CLOCK_PIN, 0) 'Wait for Clock to go high
          STR[noparse][[/noparse]63] := INA[noparse][[/noparse]DATA_PIN]  
        ser.dec(STR[noparse][[/noparse]0])
        ser.dec(STR)
        ser.dec(STR)
        ser.dec(STR)
        ser.dec(STR)
        ser.dec(STR)
        ser.dec(STR[noparse][[/noparse]6])
        ser.dec(STR[noparse][[/noparse]7])
        ser.dec(STR[noparse][[/noparse]8])
        ser.dec(STR[noparse][[/noparse]9])
        ser.dec(STR[noparse][[/noparse]10])
        ser.dec(STR[noparse][[/noparse]11])
        ser.dec(STR[noparse][[/noparse]12])
        ser.dec(STR[noparse][[/noparse]13])
        ser.dec(STR[noparse][[/noparse]14])
        ser.dec(STR[noparse][[/noparse]15])
        ser.dec(STR[noparse][[/noparse]16])
        ser.dec(STR[noparse][[/noparse]17])
        ser.dec(STR[noparse][[/noparse]18])
        ser.dec(STR[noparse][[/noparse]19])
        ser.dec(STR[noparse][[/noparse]20])
        ser.dec(STR[noparse][[/noparse]21])
        ser.dec(STR[noparse][[/noparse]22])
        ser.dec(STR[noparse][[/noparse]23])
        ser.dec(STR[noparse][[/noparse]24])
        ser.dec(STR[noparse][[/noparse]25])
        ser.dec(STR[noparse][[/noparse]26])
        ser.dec(STR[noparse][[/noparse]27])
        ser.dec(STR[noparse][[/noparse]28])
        ser.dec(STR[noparse][[/noparse]29])
        ser.dec(STR[noparse][[/noparse]30])
        ser.dec(STR[noparse][[/noparse]31])
        ser.dec(STR[noparse][[/noparse]32])
        ser.dec(STR[noparse][[/noparse]33])
        ser.dec(STR[noparse][[/noparse]34])
        ser.dec(STR[noparse][[/noparse]35])
        ser.dec(STR[noparse][[/noparse]36])
        ser.dec(STR[noparse][[/noparse]37])
        ser.dec(STR[noparse][[/noparse]38])
        ser.dec(STR[noparse][[/noparse]39])
        ser.dec(STR[noparse][[/noparse]40])
        ser.dec(STR[noparse][[/noparse]41])
        ser.dec(STR[noparse][[/noparse]42])
        ser.dec(STR[noparse][[/noparse]43])
        ser.dec(STR[noparse][[/noparse]44])
        ser.dec(STR[noparse][[/noparse]45])
        ser.dec(STR[noparse][[/noparse]46])
        ser.dec(STR[noparse][[/noparse]47])
        ser.dec(STR[noparse][[/noparse]48])
        ser.dec(STR[noparse][[/noparse]49])
        ser.dec(STR[noparse][[/noparse]50])
        ser.dec(STR[noparse][[/noparse]51])
        ser.dec(STR[noparse][[/noparse]52])
        ser.dec(STR[noparse][[/noparse]53])
        ser.dec(STR[noparse][[/noparse]54])
        ser.dec(STR[noparse][[/noparse]55])
        ser.dec(STR[noparse][[/noparse]56])
        ser.dec(STR[noparse][[/noparse]57])
        ser.dec(STR[noparse][[/noparse]58])
        ser.dec(STR[noparse][[/noparse]59])
        ser.dec(STR[noparse][[/noparse]60])
        ser.dec(STR[noparse][[/noparse]61])
        ser.dec(STR[noparse][[/noparse]62])
        ser.dec(STR[noparse][[/noparse]63])
        waitcnt (50_000_000 + cnt)
    
    

    Post Edited (tuki) : 5/17/2009 3:09:36 AM GMT
  • LeonLeon Posts: 7,620
    edited 2009-05-17 02:25
    Use Code tags properly!

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Amateur radio callsign: G1HSM
    Suzuki SV1000S motorcycle
  • tukituki Posts: 10
    edited 2009-05-17 02:45
    Sorry, i don't know how that happened. I guess I should have attached my code instead.
  • mctriviamctrivia Posts: 3,772
    edited 2009-05-17 02:53
    you put a / after code. edit the post and remove should be (code) with square brackets

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    My new unsecure propmod both 1x1 and full size arriving soon.

    Need to upload large images or movies for use in the forum. you can do so at uploader.propmodule.com for free.
  • SRLMSRLM Posts: 5,045
    edited 2009-05-17 02:55
    [noparse][[/noparse] code ]
    My code
    [noparse][[/noparse] /code ]


    is equal to

    My code
    
    
  • tukituki Posts: 10
    edited 2009-05-17 03:08
    There it is. Sorry about that and sorry that it is so long but I'm not very good at programming.
  • SRLMSRLM Posts: 5,045
    edited 2009-05-17 03:17
    You should cut that code down into two loops: one for the input, one for the output. It's fairly straightforward since all you're doing is inputting to an array, and shooting it back out via the serial port.
  • tukituki Posts: 10
    edited 2009-05-17 03:37
    Oh ok i get what you mean MagI02, i'll try to do it that way. Hopefully that will work. Thanks
  • MagIO2MagIO2 Posts: 2,243
    edited 2009-05-17 16:08
    Did you attach your Prop to some other device which generates the signals for the RFID plus signals for the Prop? Ok .. I did not get the point that you have a clock-signal. I thought you only receive the bitstream. Makes things easier, as you don't need the counters. (But isn't it the sense of a manchester bitstream that you don't need a clock signal ?)

    Besides the fact that your code is ugl... it's only good if you have a 100% reliable signals. Once you get out of sync with the sender, it's totally lost. That's why I meantioned the state machine. You have different states

    0 wait for start of transmission
    1 receive bits and count 1s
    2 receive bits

    In state 0 you wait for a clock signal and read the input. We need a 1 to switch to state 1.
    In state 1 you wait for a clock and read the input. If 0 go back to state 0 - if 1 count and if count equals 8 switch to state 2 ( the 9nth bit was read in state 0 )
    In state 2 read the rest of the bits (counting them) if 55 bits received, go back to state 0

    Further improvements could be to check the parity bits while reading. As soon as a transmission was wrong you can switch back to state 0
    At least when transmisstion is complete you should check the parity bits to see if you got valid data.
  • hairymnstrhairymnstr Posts: 107
    edited 2009-05-17 16:17
    The idea behind Manchester coding is to remove the DC level from the system as I recall, so in long periods with only one symbol or the other you do not get 'signal droop' in applications like RFID where there is no DC path between the transmitter and receiver. It's used in Ethernet as well because the transmitter/receivers use transform isolated differential mode signalling so there is no DC reference, you can only detect a change.

    Is Manchester code not a bitwise XOR of the data with a clock signal, if you have clock and data, could you not xor them again to get data?
  • MagIO2MagIO2 Posts: 2,243
    edited 2009-05-17 16:53
    No need to XOR it again. XOR is nothing else but a inverter which can be switched on and off. If the data is 0 then clock is not inverted, if data is 1 clock is inverted. But if you want to read that signal and you have the clock at hand, there is no need to XOR it. You simply read the pin at the right time and you get the original signal. If you read it at the wrong time you get the inverted signal.

    If you don't have the clock, you can not even XOR it. Then you would use the method I showed in my first post - measuring the pulse and/or pause length.
  • mctriviamctrivia Posts: 3,772
    edited 2009-05-17 18:34
    if i remember correctly a pll circuit easily generates the clock signal again.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    My new unsecure propmod both 1x1 and full size arriving soon.

    Need to upload large images or movies for use in the forum. you can do so at uploader.propmodule.com for free.
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2009-05-17 23:33
    Only last week I thought I might look at manchester coding. It is not simple! I have about 10 pages of scribbled notes and that was just trying to work out the waveforms before even thinking about coding it (in any language).

    Manchester coding encodes a 0 as a 0 to 1 transition and a 1 as a 1 to 0 transition. Or the other way, and yes, there are both standards out there. That seems simple enough. If you send a low into a transmitter, it will produce a nice square wave and if you send that for long enough you can lock onto the signal and use that as a clock. When you do lock on, you need to lock both the frequency and the phase. A 4046 is a good place to start, but it can be done in software too.

    Now, this is the tricky bit - as the signal arrives, you will be guaranteed to get a transition at each transition point. But, depending on the data, you may or may not get a transition half way between those two points. For a byte of 01010101 it works fine, but for 11001100 it could be possible to lock onto a clock of half the frequency. So your PLL (or PLL software emulation) needs to be able to lock on and then cope with missing pulses. On a 4046, you can program the lock and capture ranges such that it has a preferred frequency of roughly the desired frequency. And then it helps if it can go +/-10% (say) but not capture at f/2 or f*2. Again, that is easy in software if you know the approximate frequency of the signal, which I think you would with RFID.

    So you need send a Low into the transmitter (hopefully the RFID sends out some pulses to initialise), lock onto the 0 to 1 transition (or the 1 to 0?!), set a clock going, keep testing for transitions at that point (either L to H or H to L) and tweak the clock frequency every pulse. Once locked, you ignore transitions outside a capture range of +/-10% of where you expect one to be, so this will miss the transitions in between pulses (which will be there most of the time). Then you take the clock frequency, divide it by 4, wait 3/4 of the time your clock period, and sample the input at that time.

    Finally, you need to recover from possible errors if the clock gets out of synch.

    Not simple. I started with wikipedia, and then started drawing up diagrams for bytes like 00000000 and 11111111 and the tricky ones like 00110011 and 00001111. I'd have all that on a piece of paper before trying to turn it into code.

    For code, locking onto the clock, I'd assume there is the initialisation square wave, look for a 0 to 1 transition, set a clock going, work out a clock period, then start looking for the next transition after 90% of that clock period has elapsed, and stop looking for it at 110%. So that narrows the capture range.
  • Mike HuseltonMike Huselton Posts: 746
    edited 2009-05-18 05:47
    This is a discussion of Manchester decoding on the PicBasic Pro search site: www.picbasic.co.uk/forum/showthread.php?t=198&highlight=manchester+decode

    This discussion has code for the PicBasic Pro compiler. It is very similar in syntax to Spin, at least in general concepts.
    I use PicBasic Pro for external chips that I use for offloading funtions from the Propeller via I2C and other protocols.
    Small packages such as 8 pin DIPs are particularly easy to sprinkle around my designs.

    Melanie has been a lifesaver - she fills the role of Mike Green and OBC.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    JMH

    Post Edited (James Michael Huselton) : 5/18/2009 5:59:08 AM GMT
  • MagIO2MagIO2 Posts: 2,243
    edited 2009-05-18 06:33
    I don't understand this discussion ... what's wrong with what I said before?

    Method A - no clock available:
    You measure pulse and pause times using counter a and counter b. The bits themselve have a defined bit-time or a transfer frequency so to say. This means you have a defined low-time and high-time for each bit. You start with nine 1 bits - always and these can not occur in the data section, as the parity bits will avoid that! Say we have the following bits to send resulting in bitstream below

    · 1·· 1· ·1·· 1·· 1·· 1·· 1·· 1·· 1·· 1· ·0··0·· 0·· 1··0·· 0··0·· 1·· 1· ·1·· 1·· 0·· 1·· 1·· 1··0
    01 01 01 01 01 01 01 01 01 01 10 10 10 01 10 10 10 01 01 01 01 10 01 01 01 10

    So, we measure time of the first 1 an see that it's short, so we shift a 1
    Same for the next·8 bits.
    The 9th high-time is double as long. So we know that we received a 1 followed by a 0, so we shift·the one·into our receive buffer. And we switch mode: now we measure low-time.
    With single low-times we keep on shifting 0 into the receive buffer, with a double low-time we swich mode back to reading 1s.

    Method A2 ;o)
    Another way came just into my mind ... you can use the serial interface. As the frequency is fixed you simply can take the 'bit' frequency of the manchester as baud-rate. De facto you would then sample half of the bitstream.
    · 1·· 1· ·1·· 1·· 1·· 1·· 1·· 1·· 1·· 1· ·0··0·· 0·· 1··0·· 0··0·· 1·· 1· ·1·· 1·· 0·· 1·· 1·· 1··0
    01 01 01 01 01 01 01 01 01 01 10 10 10 01 10 10 10 01 01 01 01 10 01 01 01 10
    ^·· ^·· ^·· ^·· ^·· ^·· ^·· ^·· ^·· ^·· ^·· ^·· ^·· ^·· ^·· ^·· ^·· ^·· ^·· ^·· ^·· ^·· ^·· ^·· ^·· ^·· sample points
    At the speed of the RFID transmission this should be reliable. Only thing that needs to be changed in the Serial interface is that it has to receive 64 bits.

    Method B - somehow the clock is also provided:
    Then the bitstream of the previous example would look like that:
    01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01
    01 01 01 01 01 01 01 01 01 01 10 10 10 01 10 10 10 01 01 01 01 10 01 01 01 10
    · ^·· ^·· ^···^·· ^·· ^·· ^·· ^·· ^·· ^·· ^·· ^·· ^·· ^·· ^·· ^·· ^·· ^·· ^·· ^·· ^···^·· ^·· ^·· ^·· ^ sample points
    ·
    With each clock=high we shift in the bit ... that's it.
  • Mike HuseltonMike Huselton Posts: 746
    edited 2009-05-18 06:59
    MagIO2, you haven't provided concrete, runnable source code. This thread's originator wasn't looking for opinions or guesswork.

    This is one of the code examples extracted from the Picbasic Pro website replies:

    encod_r:
    For i=0 TO 7
    IF mydata.0=0 Then
    encoded.0[noparse][[/noparse]i*2]=0
    encoded.0[noparse][[/noparse]i*2+1]=1
    Else
    encoded.0[noparse][[/noparse]i*2]=1
    encoded.0[noparse][[/noparse]i*2+1]=0
    EndIF
    Next i
    Return

    Rec_r:
    For i=0 TO 7
    IF encoded.0[noparse][[/noparse]i*2]=0 Then
    IF encoded.0[noparse][[/noparse]i*2+1]=1 Then
    mydata.0=0
    EndIF
    Else
    mydata.0=1
    EndIF
    Next
    Return

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    JMH

    Post Edited (James Michael Huselton) : 5/18/2009 7:27:57 AM GMT

  • MagIO2MagIO2 Posts: 2,243
    edited 2009-05-18 07:59
    Being helpful is a complex thing ... of course it would help alot to post some running code. But that's only helpful for a short timeframe. In the end a graduation based on other people work is worth nothing. If he managed to write his own code -only with some hints- that's helpful as well ... and helpful on a large timescale, because things you did by yourself are worth much more!

    In my opinion he has to provide the code and we can discuss about it. Giving him some starting-point ideas is sufficient at this point.

    In addition, we don't even know the exact setup yet. Do we really have a clock or should we provide the clock because the coil is attached to the prop? What clock is it then, the clock send to the coil (which is 64 cycles per bit) or is it the bit-clock?

    @tuki:
    What do you think? What's the exact deadline? Do we have the whole week?

    Post Edited (MagIO2) : 5/18/2009 8:09:51 AM GMT
  • mctriviamctrivia Posts: 3,772
    edited 2009-05-18 08:17
    I think both sides of the argument of is concept or code better correct. I tought myself php by looking up examples of code and looking up what functions are available. But this only helps in learning a new language. It does not teach you technics or data theory. For that you nee concepts and to go ahead and figure out how to write your own code. There is no better way to understand something then to build it from scratch from the basic building blocks. This is why they teach technics like bubble sort, or using binary tree to do hufman compression. In most higher level languages these have already been build into nice neat black boxs. but if you only ever use the black box you will never learn how it works.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    My new unsecure propmod both 1x1 and full size arriving soon.

    Need to upload large images or movies for use in the forum. you can do so at uploader.propmodule.com for free.
  • Mike HuseltonMike Huselton Posts: 746
    edited 2009-05-18 09:03
    Students tend to wait until the last minute. My reply was intended with this in mind.

    If the poster truly enjoys the challenge and thrill of intellectual discovery, then why was he asking this forum for help?

    Tuki writes "I know what I have to do I just do not know how to translate it in code and since I have never used Spin my problem becomes that much worse."
    So, I decided to give him the solution. He still has to translate the code into Spin or Assembly syntax.

    This discussion has gotten gone on long enough for me. Time to move on to more interesting things...

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    JMH

    Post Edited (James Michael Huselton) : 5/18/2009 9:12:46 AM GMT
  • MagIO2MagIO2 Posts: 2,243
    edited 2009-05-19 18:05
    @tuki : Any news here?
  • tukituki Posts: 10
    edited 2009-05-19 20:46
    I think there is more to this problem than I had originally thought. I saw some code from microchip that they use in their own RFID reader and from what I could understand they do more than just read the values as soon as the tag starts outputting them. It's in assembly and it is close to 1000 lines so it's going to take me a while to understand it. I have a feeling that I have to check for the header of nine 1's before I can start storing the actual data. What is getting displayed on the terminal right now is always different at the beginning but eventually you can see that there is a pattern. I have to check the terminal again to see what I have to wait for before the pattern begins, when I figure that out, I'm certain the code I already have, no matter how ugly it may be, will work. I'll keep you guys updated and I want you to know that I appreciate your help.
  • MagIO2MagIO2 Posts: 2,243
    edited 2009-05-19 20:55
    Why don't you start with writing all the bits you read to the serial interface? If you leave the tag in range of the coil it will continuously send the data and you should find the nine 1 bits in this stream and from there on the pattern should be always the same.

    Finding the nine 1s is exactly what state 0 and 1 of the state-machine should do.
  • Mike HuseltonMike Huselton Posts: 746
    edited 2009-05-19 22:21
    I agree with MagIO2's approach. Empirical analysis of the bit stream is much quicker than unravelling some unknown code.

    Plus, you will learn something.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    JMH
  • Harrison.Harrison. Posts: 484
    edited 2009-05-19 23:39
    Micah Dowty posted his RFID Reader code on the OBEX: obex.parallax.com/objects/374/. It's completely software based, only requiring a few passives and a coil for reading EM4102 (125KHz) tags. It worked so well that I decided to use it instead of purchasing the Parallax RFID reader.
Sign In or Register to comment.