I am relatively new to Arduino but I am loving it. I am interested in connecting an RFID Reader with a Wiegand output to my Arduino. I have found the following on the old forum;
Thanks for your reply. I have tried using a few different tags and getting some odd results. They seem to vary in length. I would assume for each tag I should get 26 binary digits? I was hoping that from here I can parse out the tag ID. It seems to vary depending on the batch/ type of tag I use. Is this normal or is there something I'm doing wrong in the code?
The code is written to work with 26-bit tokens. If you have tokens with different numbers of bits you will have to add some additional code, such as detecting a delay after the last bit. 34-bit seems to be a popular size.
In the 26-bit standard:
The first bit is an Even Parity bit for the next 12 bits.
The next 8 bits are the Facility Code
The next 16 bits are the Card Number
The last bit is an Odd Parity bit for the previous 12 bits.
Great to hear from you again. So correct me if I'm wrong; tags can have varying number of bits along with different formats? I have a variety of tags i.e. bracelets, card and fobs. Depending on what I'm using I get a different number of bits.
That is what HID says in the document I pointed to. There is nothing magic about the number 26, it's just one of the many available formats.
What I would do is note the time when the latest bit arrived. If it has been more than, say, 100 milliseconds (0.1 second) since the last bit arrived, the code is probably complete. Then from the number of bits and the pattern of bits you can identify each tag. For tags with more than 32 bits of data you should probably just keep the last 32 rather than trying to keep all the bits.
I have been playing with this for the last couple of hours and something just doesn't seem right. I have purchased a 100 identical tags but when I read them some have 26 bits while others have less. Two things I have noticed/ thought of.
The Arduino has internal pull-up resistors that are enabled by digitalWrite(pin,HIGH) after pinMode(pin, INPUT). Is that code missing?
Every tag I read starts with a 1
Is that binary, hex, or decimal?
The first bit is a parity bit for the first 12 data bits. The 12 data bits are the facility code (which should be all the same for a single batch of cards) and the top four bits of the card sequence number (which I would not expect to change until the lower 12 bits overflow). That would meant that the first 13 bits in a batch of cards will likely always be the same.
The code only prints wen you get 26 or more bits. How do you know that you are sometimes getting fewer than 26? Please post your full program and a sample of your serial monitor results.
I can imagine that Serial.print() drops leading zeros but that data looks too random to be right. Is that the same token each time or different tokens each time?
Remove the right most bit from the code (parity bit)
Retain the next 24 bits
Add 0's to the left most part of the code to make a total of 24 bits (I think println() gets rid of zeros to the left)
Then the numbers match with what is printed on the tag.
Example:
10001111100100100000001
0010 0011 1110 0100 1000 00001
Now it is a matter of doing this within the program.
On the old forum this was discussed but I didn't quite grasp what they were talking about. The term bit manipulation was used along with masking. I understood the bit manipulation aspect.
Example:
10001111100100100000001
tagID=(reader1 >> 1)
10001111100100100000001
This means that the code is shifted one step to the right. The one drops off. This gets rid of the parity bit.
The masking I am not entirely sure about.
tagID=(reader1 >> 1) & 0xFFFFFF
I think this grabs a specific number of bits from what is left in the code. The 0xFFFFFF is HEX for 24.
Example
0010 0011 1110 0100 1000 0000
I have tried to do this in the sketch but not quite there;
The variable tagID needs to be declared as long NOT int. An int can only handle 16 bits while a long can handle 32 bits which is slightly more than what we need.
John, thanks so much for your help. I'm a very happy man!
WhiteNite1971:
I think this grabs a specific number of bits from what is left in the code. The 0xFFFFFF is HEX for 24.
0xFFFFFF (also 0x00FFFFFF) is HEX for 0b00000000111111111111111111111111
The bitwise AND operation (&) will put a 1 where both values have a 1 and 0 where either value has a 0.
Since you are not working with signed numbers (numbers that can be less than zero) you should probably use 'unsigned long' for both reader1 and tagID. They will work as plain long integers but using unsigned values where you don't need the sign is good practice.