Shop OBEX P1 Docs P2 Docs Learn Events
unexplained problem reading wiegand protocol — Parallax Forums

unexplained problem reading wiegand protocol

stefstef Posts: 173
edited 2012-11-13 13:57 in Propeller 1
Hi

I used in a few projects now the folowing routine to read the wiegand bus from a standard HID access control reader. I got this with help from other forum members and it has worked perfect until now. In my recent project it is working but sometimes it is reading a differend number. If you then look at the binery format of that number everything is shifted one place to the left and aded a zero on the right side. basicly it has read the same number but schifted. I looked with a scoop and at that point it is the same number as always in pulses on the data 0 and data 1 lines. So why is it sometimes doing that? Does somebody have some hints on resolving this or optimizing this spin so i can resolve this. I'm sertainly not the best in spin but i like to learn.
 state := %11<<4                                      ' setup mask state for RDR_D0 and RDR_D1 pins
  Repeat
    cardnumber[0] := 0                                  ' Initialise variables
    cardnumber[1] := 0
    Bits := 0
    cardnumber_L := 0
    Repeat      
      waitpne(state,state,0)                            ' Wait for D0 or D1 to change
      Read := INA[WD0..WD1]                       ' Store the state of D0 and D1
      cardnumber[0] <<= 1                               ' Shift cardnumber 0 left by 1 bit
      cardnumber[0] |= ((cardnumber[1] & (%1<<31))>>31) ' copy the MSB of cardumber 1 to LSB or cardnumber 0
      cardnumber[1] <<= 1                               ' Shift cardnumber 1 left by 1 bit
      IF Read == %01                                    ' If the D1 input was low
        cardnumber[1] |= %1                             ' Set the LSB of cardnumber 1
      waitpeq(state,state,0)                            ' Wait for D0 and D1 to go high
      Bits++                                            ' Increase the number of bits received
    Until Bits == 42
The code example is not the complete project. Just the part to read the wiegand bus.
so eventualy in cardnumber0 and in cardnumber 1 is the complete 42 bit of the wiegand bus.

Any advice is welcom.

stef

Comments

  • ColeyColey Posts: 1,110
    edited 2012-11-06 13:57
    Nice to see my code is still useful to you ;-)

    Without knowing the card structure I would guess that it's additional parity bits.

    How many bits are read and how many should you expect to read?

    Regards,

    Coley
  • MagIO2MagIO2 Posts: 2,243
    edited 2012-11-06 13:58
    Do you have a documentation of the wiegand bus?
  • ColeyColey Posts: 1,110
    edited 2012-11-06 14:21
    @Stef

    This code may be of use to you, it uses the counters to keep track of the bits received....
    {{*****************************************
    * Wiegand Output Demo                   *
    * Author: Graham Cole                   *
    * Copyright (c) 2010 GFS Ltd            *
    * See end of file for terms of use.     *
    *****************************************
    
    
     Setup uses Smart Wiegand Splitter PCB SWS-1-8
    
    
     Connect as follows:-
    
    
     X1 Terminal Block              
    
    
     Power &#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;  0V                X2 Terminal Block (CH1)
     In    &#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472; 12V
                   -ve &#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472; -ve
                   +ve &#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472; +ve
                    D1 &#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472; D1
                    D0 &#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472; D0
    
    
     Use PropPlug port to communicate with Parallax Serial Terminal (PST) 
    
    
     Test Data 65805730401030 (14 Chars)
     Using each character represented at BCD we get 14*4 bits = 56 Bits
     Data will be appended with leading zeros to reach 64 bits which means we can have up to 16 characters
    
    
     Test Data will be converted as follows:-
     
        0    0    6    5    8    0    5    7    3    0    4    0    1    0    3    0
     &#9484;&#9472;&#9472;&#9508; &#9484;&#9472;&#9472;&#9508; &#9484;&#9472;&#9472;&#9508; &#9484;&#9472;&#9472;&#9508; &#9484;&#9472;&#9472;&#9508; &#9484;&#9472;&#9472;&#9508; &#9484;&#9472;&#9472;&#9508; &#9484;&#9472;&#9472;&#9508; &#9484;&#9472;&#9472;&#9508; &#9484;&#9472;&#9472;&#9508; &#9484;&#9472;&#9472;&#9508; &#9484;&#9472;&#9472;&#9508; &#9484;&#9472;&#9472;&#9508; &#9484;&#9472;&#9472;&#9508; &#9484;&#9472;&#9472;&#9508; &#9484;&#9472;&#9472;&#9508; 
     0000_0000_0110_0011_1000_0000_0011_0111_0011_0000_0100_0000_0001_0000_0011_0000
     &#61600;                                                                             &#61600;
     MSB                                                                         LSB
    
    
     Wiegand data will be clocked out MSB first.
    
    
     ANPR data is input via Parallax Serial Terminal (PST) and can be up to 16 digits in length
     ANPR data is stored in two longs anprnumber[0] and anprnumber[1]
     This data is appended with leading zeros to 16 digits and then converted in BCD nibbles
     The converted data stream is transmitted in Wiegand format on CH1 of the splitter board
     Received wiegand data is sent back to PST for comparison
     
    
    
    }}
    
    
    CON
      _clkmode = xtal1 + pll16x
      _clkfreq = 80_000_000
    
    
      tpw = (_clkfreq/1_000_000)*35 ' Time Pulse Width 35uS  ( 25uS is minimum value)
      tpi = (_clkfreq/1_000)*2      ' Time Pulse Interval 2mS ( 1mS is minimum value)
      
      CH1_D1 = 01                   ' Wiegand D1 Output (Channel 1) 
      CH1_D0 = 00                   ' Wiegand D0 Output (Channel 1)
      RDR_D1 = 16                   ' Wiegand D1 Input  
      RDR_D0 = 17                   ' Wiegand D1 Input
      LED_1  = 05                   ' LED 1
      LED_2  = 06                   ' LED 2
      
    VAR
      byte  anprdata[20]
      long  anprnumber[2]
      long  cardnumber[2]
      long  cardread 
      long  anprsize
      long  bits
      long  facility
      long  card
      long  stack_1[10]
      long  stack_2[10]
      
    OBJ
      pst   :       "Parallax Serial Terminal"
    
    
    PUB Start
    
    
      cognew(W_Input,@stack_2)                              ' Start Wiegand reader in new cog
      pst.Start(115_200)                                    ' Start Parallax Serial Terminal in new cog
      
      Repeat  
        Repeat
          pst.Clear
          pst.Str(@DemoHeader)                              'Print demo header; uses string in DAT section.
          pst.Chars("-", strsize(@DemoHeader))
          pst.Str(String(pst#NL, pst#NL, "Present Card Credential"))        
          Repeat until Cardread == 1
          pst.Str(String(pst#NL, pst#NL, "Received Wiegand Data..........", pst#NL))
    
    
          pst.Str(String(pst#NL, "Binary Data", pst#NL))     
          pst.Bin(cardnumber[0],32)
          pst.Char(" ")
          pst.Bin(cardnumber[1],32)
          pst.char(pst#NL)
    
    
          pst.Str(String(pst#NL, "Decimal Data", pst#NL))    
          pst.dec(cardnumber[0])
          pst.Char(" ")
          pst.dec(cardnumber[1])
    
    
          pst.Str(String(pst#NL, pst#NL, "Hex Data", pst#NL))    
          pst.hex(cardnumber[0],8)
          pst.Char(" ")
          pst.hex(cardnumber[1],8)    
    
    
          pst.Str(String(pst#NL, pst#NL, "Bits :- "))
          pst.dec(Bits)   
          if bits == 26
            card := CardNumber[0] >> 1                        ' strip parity
            card &= $00FF_FFFF                                ' extract card & facilty number
            facility := card >> 16                            ' extract facility code $00 to $FF
            card &= $FFFF                                     ' extract card number $0000 to $FFFF
            pst.str(string(pst#NL, pst#NL," Facility Code "))
            pst.dec(facility)
            pst.str(string(pst#NL," Card Number   "))
            pst.dec(card) 
          CardRead := 0
    
    
          pst.Str(String(pst#NL, pst#NL, "Press any key to continue...."))
          pst.CharIn  
    
    
    
    
    
    
    PUB W_Input | Read, state, timeout, timeout2            ' Reads a Wiegand data stream
    
    
      state := %11 << RDR_D1                                ' setup mask state for RDR_D0 and RDR_D1 pins
      DIRA[RDR_D0..RDR_D1]~                                 ' Make RDR_D0 and RDR_D1 inputs
      CardRead := 0
                                               
      ctra := %11000_000 << 23 + RDR_D0 << 9 + RDR_D1       'Establish logic mode A=1 & B=1
      frqa := 1                                             
      
      ctrb := %10111_000 << 23 + RDR_D0 << 9 + RDR_D1       'Establish log mode A=0 or B=0
      frqb := 1
    
    
      
      Repeat                                                '
      
        cardnumber[0] := 0                                  ' Initialise variables
        cardnumber[1] := 0                                  '
        Bits := 0
        Timeout := 0
     
        waitpne(state,state,0)                              ' Wait for initial pulse
        
        Repeat
        
          phsa := 0                                         ' Clear counter A
       
          Repeat                                            ' Repeat
            Read := INA[RDR_D0..RDR_D1]                     ' Store the state of D0 and D1
            if phsa > tpi                                   ' Check if counter A is greater than time pulse interval
              Timeout := 1                                  ' If so, flag the timeout variable
              quit                                          ' Exit from repeat loop
          Until Read <> %11                                 ' Until either D0 or D1 lines go Low
          
          phsb := 0                                         ' Clear counter B  
          
          if Timeout == 0
          
            cardnumber[1] <<= 1                               ' Shift cardnumber 1 left by 1 bit
            cardnumber[1] |= ((cardnumber[1] & (%1<<31))>>31) ' copy the MSB of cardumber 0 to LSB or cardnumber 1
            cardnumber[0] <<= 1                               ' Shift cardnumber 0 left by 1 bit
            IF Read == %10                                    ' If the D1 input was low
              cardnumber[0] |= %1                             ' Set the LSB of cardnumber 0
    
    
          Repeat                                              ' Wait for D0 and D1 to go high
            if phsb > tpw
              Timeout := 1
              quit
          Until INA[RDR_D0..RDR_D1] == %11
          
          If Timeout == 0
            Bits++
          
        Until Timeout == 1 or Bits == 64
    
    
        If Timeout == 0
          CardRead := 0
        Else
          CardRead := 1                                            ' Increase the number of bits received
        
        Repeat Until CardRead == 0
      
    DAT
    
    
    DemoHeader    byte "GRANTfen Smart Wiegand Splitter - Card Bit Length Checker", pst#NL, 0
      
    {{
    &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;
    &#9474;                                                   TERMS OF USE: MIT License                                                  &#9474;                                                            
    &#9500;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9508;
    &#9474;Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation    &#9474; 
    &#9474;files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy,    &#9474;
    &#9474;modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software&#9474;
    &#9474;is furnished to do so, subject to the following conditions:                                                                   &#9474;
    &#9474;                                                                                                                              &#9474;
    &#9474;The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.&#9474;
    &#9474;                                                                                                                              &#9474;
    &#9474;THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE          &#9474;
    &#9474;WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR         &#9474;
    &#9474;COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,   &#9474;
    &#9474;ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                         &#9474;
    &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9496;
    }}
    
  • ColeyColey Posts: 1,110
    edited 2012-11-06 14:27
  • Duane C. JohnsonDuane C. Johnson Posts: 955
    edited 2012-11-06 14:41
    Slightly off topic:

    Where can one buy "wiegand wire"?
    Just the wire to play with or do experiments.
    I have looked for this for at least 15 years and can't find a source.
    I don't want the card readers.

    Duane J
  • kwinnkwinn Posts: 8,697
    edited 2012-11-06 17:06
    Not sure about "weigand wire", but it seems to work well with shielded pairs and shielded twisted pairs up to a couple of hundred feet with the shield is used for the common conductor.
  • Duane C. JohnsonDuane C. Johnson Posts: 955
    edited 2012-11-06 17:22
    No no, kwinn;

    Wiegand Wires are used in the actual magnetic sensor used in the Wiegand keycards. These have a Wiegand protocol .

    I'm looking for the magnetic Wiegand Wires which are the heart of the sensors.

    Duane J
  • kwinnkwinn Posts: 8,697
    edited 2012-11-06 17:47
    As far as I can see from the card readers I work with that is just copper wire with a thin layer of (lacquer?) insulation like that used in transformers. It is the 125KHz signal from the card reader that "reads" the card based on how much of that signal it absorbs.

    I know, not the best explanation, but the best I can give on short notice.
  • Duane C. JohnsonDuane C. Johnson Posts: 955
    edited 2012-11-06 17:54
    Did you look at the links in my message?

    Duane J
  • Mark_TMark_T Posts: 1,981
    edited 2012-11-06 18:39
    Magnetic avalanche - very clever. Sounds like the work-hardening is done by twisting and un twisting which preferentially distorts the outer layers of the wire,
    not the centre. Presumably the right alloy is needed (otherwise everyone would be doing this with steel wire!).
  • stefstef Posts: 173
    edited 2012-11-07 05:18
    Hi Coley

    Nice catch. Yes I started with your code. It was working perfect until now.

    Thiks for the help and the new code. I will set it up this evening at home and get back with the result.
    I need to modify it to work with 42 Bit because this project is running on that.

    I will keep you informed.

    Stef
  • stefstef Posts: 173
    edited 2012-11-13 05:22
    After a lot of searching and with the help of Coley his code I found the problem. Of course it had nothing to do with the propeller who was working ok. It was back again a mistake from me. Never the less it is resolved. I learned back again a lot.
    Up to the next project.

    stef
  • ColeyColey Posts: 1,110
    edited 2012-11-13 07:41
    Glad you managed to sort out the problem Stef, it's always satisfying when you finally get it working ;-)

    Regards,

    Coley
  • kwinnkwinn Posts: 8,697
    edited 2012-11-13 13:57
    @Duane, re:
    Did you look at the links in my message?

    Duane J

    No, I did not look at the links in your prior posting before my prior post, but I have now. Thanks for posting those links. I picked up some good information there. Now I am wondering what kind of cards the system is using. The data is sent in the Weigand format over 2 wires + ground, but the cards are not slid through a card reader (like mag stripe cards), they only need to be placed near the surface of the reader. I know the reader uses a magnetic coil energized by a 125KHz signal and assumed it was reading Weigand cards. Perhaps not. This security stuff is relatively new to me so it looks like I still have a bit more to learn about it.
Sign In or Register to comment.