unexplained problem reading wiegand protocol
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.
so eventualy in cardnumber0 and in cardnumber 1 is the complete 42 bit of the wiegand bus.
Any advice is welcom.
stef
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
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
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 ─────── 0V X2 Terminal Block (CH1) In ─────── 12V -ve ────────────── -ve +ve ────────────── +ve D1 ────────────── D1 D0 ────────────── 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 ┌──┤ ┌──┤ ┌──┤ ┌──┤ ┌──┤ ┌──┤ ┌──┤ ┌──┤ ┌──┤ ┌──┤ ┌──┤ ┌──┤ ┌──┤ ┌──┤ ┌──┤ ┌──┤ 0000_0000_0110_0011_1000_0000_0011_0111_0011_0000_0100_0000_0001_0000_0011_0000   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 {{ ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ │ TERMS OF USE: MIT License │ ├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ │Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation │ │files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, │ │modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software│ │is furnished to do so, subject to the following conditions: │ │ │ │The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.│ │ │ │THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE │ │WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR │ │COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │ │ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │ └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ }}wiegand-protocol-format-pr25.pdf
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
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
I know, not the best explanation, but the best I can give on short notice.
Duane J
not the centre. Presumably the right alloy is needed (otherwise everyone would be doing this with steel wire!).
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
Up to the next project.
stef
Regards,
Coley
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.