Shop OBEX P1 Docs P2 Docs Learn Events
Reading input pins @ timed intervals and storing in an array — Parallax Forums

Reading input pins @ timed intervals and storing in an array

JetManJetMan Posts: 39
edited 2012-07-31 17:23 in Propeller 1
I'm working on creating a card reader solution for my house. I have currently connected a wiegand card reader to pins 0..1 of my prop. I'm attempting to figure out how to correctly time the reading of the pin pulses and then compile them in to one long binary value once done.

The wiegand data stream flows at approximately 50us pulses with 1ms mark space. pins are alternating data (when P0 goes high it equals a zero , when P1 goes high it equals a one)

this is my code so far , but I keep getting random numbers that never change despite reading different cards.
{{
  26-Bit Wiegand Card Reader
}}
CON
  _clkmode = xtal1                          
  _xinfreq = 8_000_000                                         

OBJ
  pst    : "Parallax Serial Terminal"

VAR

  byte  WD1
  byte  bitcount
  byte  RX_DT[26]
  long  bit_time
  long  space_time

PUB ReadCard 

  pst.Start(115_200)
  bit_time := 400    '640 = 80us
  space_time := 8_000  '8_000 = 1ms
  bitcount := 0
  dira[0..1]~
  dira[16]~~ 
  Repeat
    bitcount := 0
    If INA[0] <> INA[1]       
      CDR 

PUB CDR
  pst.str (String(pst#CS)) 
  repeat 26
    If INA[0] := 1
      byte[@RX_DT][bitcount] := 1
      bitcount ++
      waitcnt (bit_time + cnt)
    If INA[1] := 1
      byte[@RX_DT][bitcount] := 0
      bitcount ++
      waitcnt (bit_time + cnt)  
   waitcnt (space_time + cnt)
  
  repeat 26
    pst.Str (String(pst#NL,"Bit:"))
    pst.dec (WD1++)
    pst.str (String(pst#TB,"Dat:"))
    pst.dec (RX_DT[bitcount])
    bitcount ++
  bitcount := 0



Wiegand Reader.spin

Comments

  • kwinnkwinn Posts: 8,697
    edited 2012-07-30 18:51
    AFAIK the weigand signals are normally high ( pulled up to +5V ) with low pulses on the 0 and 1 line. Do you invert the signal somewhere?
  • JetManJetMan Posts: 39
    edited 2012-07-30 18:54
    Good eye , but yes I do have a set of transistors to and resistors to couple the 5v logic to my 3.3v bus pulled low. I'm inverted .
  • AribaAriba Posts: 2,690
    edited 2012-07-30 22:49
    Now you read the bits asynchron and it would be surprising if the bitrate matches exactly the one of the card reader.
    You need to synchronize to the low to high edges of the signals. The fastest way is to use waitpne / waitpeq.
    I think it is also much simpler to collect the bits at the moment you receive them, insted of storing them in an array first.
    Here is a possible code:
    PUB CDR : value
     repeat 26
       waitpne(%00,%11,0)            'wait for a pulse on P0 or P1
       value := value << 1 + ina[1]  'shift bit in
       waitpeq(%00,%11,0)            'wait for idle
    
     pst.str(string(13,"received bits: %"))
     pst.bin(value,26)
     pst.str(string(13,"facility: "))
     pst.dec(value>>17 & $FF)
     pst.str(string(13,"tag id: "))
     pst.dec(value>>1 & $FFFF)
    
    This expects always 26 bits for one value, I don't know this wiegand protocoll, so I can't say if this is always the case. I also don't know it is LSB first or MSB first (the code above is for MSB first).

    Andy

    Edit: changed the debug output a bit after googling the wiegand protocol.
  • JetManJetMan Posts: 39
    edited 2012-07-31 16:02
    Andy,

    Thanks for the reply . I've tried using waitpne and waitpeq previously also with no results. I sampled your code into my project and it still produces all zeroes. I've tried several different permutations of code but so far all I've been able to get is some repeating numbers using a series of if statements. I don't know what I'm missing but it's driving me nuts here. I know the prop is seeing my pins change state and I know the card reader output is as specified because I monitored both pins using my o-scope. ???????
  • kuronekokuroneko Posts: 3,623
    edited 2012-07-31 16:21
    I have my doubts that you'll catch the pulses in SPIN. You only run at 8MHz which - as indicated - gives you a bit time of 640 cycles. This is simply not enough time to get out of the waitpxx and then sample the pin before it goes down again. I'm not even sure if increasing clkfreq would help without running some tests. How good are you with PASM?

    One other thing you could try first is program a counter in POSEDGE mode on the one-bit. Then - after you detected the pin change - you simply look at the counter, e.g.
    repeat 26
       waitpne(%00,%11,0)            'wait for a pulse on P0 or P1
       value := value << 1 + [COLOR="orange"]phsa~[/COLOR]   'shift bit in
       waitpeq(%00,%11,0)            'wait for idle
    
    This reads the bit value (0/1, frqa == 1) and (post-)clears it for the next event. HTH
  • JetManJetMan Posts: 39
    edited 2012-07-31 16:36
    I don't know why but I was just sitting here looking at my CLK freq knowing it was too slow. I have another complication that makes it difficult for me to increase though. When I run the prop @ 8MHz with no pllx it works great and can communicate with the serial term , led outputs etc. As soon as I attempt to implement a pllx adder to increase clk freq it just dies and has no response. That even stands true for pll1x ... on up to pll8x . I thought maybe it was the crystal so I switched to another and got the same results. I have tried with the case of the crystal grounded and un-grounded and still no dice with pllx multipliers.
  • SapiehaSapieha Posts: 2,964
    edited 2012-07-31 16:42
    Hi JetMan.

    You need be happy that You can run Propeller on 8MHz Crystal at all.

    Edited:
    PLL8x and smaller shall be possible
    To use pll16x You can't have any crystal that is bigger as 7MHz

    JetMan wrote: »
    I don't know why but I was just sitting here looking at my CLK freq knowing it was too slow. I have another complication that makes it difficult for me to increase though. When I run the prop @ 8MHz with no pllx it works great and can communicate with the serial term , led outputs etc. As soon as I attempt to implement a pllx adder to increase clk freq it just dies and has no response. That even stands true for pll1x ... on up to pll8x . I thought maybe it was the crystal so I switched to another and got the same results. I have tried with the case of the crystal grounded and un-grounded and still no dice with pllx multipliers.
  • kuronekokuroneko Posts: 3,623
    edited 2012-07-31 16:51
    Sapieha wrote: »
    To use pll_X You can't have any crystall that is bigger as 7MHz
    You're aware that the Hydra uses a 10MHz crytal and works just fine?
  • JetManJetMan Posts: 39
    edited 2012-07-31 17:02
    Hey I'm a new guy here but the prop manual plainly states that xtal3 is for crystals 20 - 60 mhz and then goes on to show using xtal3 in conjunction with the = pll_x commands up to 16x !! I found my issue with pll though. I was using a three year old prop that had floated around in stat foam in my chip box for three years . Apparently the pll circuitry is OVERLY sensitive. I busted out a much newer prop in the bag and pll works. Still no card data even at 64MHz but it works with PLL anyhow ! :) happiness is fast approaching
  • kuronekokuroneko Posts: 3,623
    edited 2012-07-31 17:07
    JetMan wrote: »
    Still no card data even at 64MHz but it works with PLL anyhow ! :) happiness is fast approaching
    Phew! Can you try the counter version? If that doesn't work I'd like you to switch back to ina[x] sampling but keep the counter enabled in parallel. Then after the loop just print out the phsa value to see if it caught anything at all.

    This test program should give us an idea what's coming to those pins. You'll have to add display code and clock setup:
    PUB count
    
      ctra := constant(%0_01010_000 << 23 | 0)  ' POSEDGE on pin 0
      ctrb := constant(%0_01010_000 << 23 | 1)  ' POSEDGE on pin 1
    
      frqa := frqb := 1
    
      repeat 26
        waitpne(%00, %11, 0)
        waitpeq(%00, %11, 0)
    
      frqa := frqb := 0
    
    ' display phsa, phsb
    
  • JetManJetMan Posts: 39
    edited 2012-07-31 17:23
    Thanks guys , finally got it working... no counter needed . I have the simple waitpne/waitpeq setup with bit shifting . Since finding and identifying my bad chip progress quickened . Just had bit reads inverted. some times its hard to keep track of whats high and low and when. especially with my inversion on the npn transistors.
Sign In or Register to comment.