I have two Raspberry Pis running python code to retrieve the serial number of an RFID tag. One has an RFID reader with a Wiegand interface hooked to GPIO pins and other has an RFID reader that behaves like a keyboard connected over USB. However, I get different numbers from the two reader when scanning the same RFID tag.
For example, for one tag, I get 57924897 from the Raspberry Pi with the Wiegand reader and 0004591983 from the Raspberry Pi with the USB keyboard reader.
Can sombody explain the difference? Are both readers reading the same? Or are they just reading some different parameter?
Looking at those two values, it seems that you do not properly read and convert the value from the Wiegand interface.
The USB keyboard reader reads the serial number in 10 digit decimal form. A Wiegand reader typically trunkaes the serial number into a 26 bit value (1 parity bit + 8 bit site code + 16 bit tag ID + 1 parity bit).
So let's look at the two values that you get:
When you take a close look at the binary representation of those two values, you will see that they correlate with each other:
So it seems as if the Wiegand value matches the inverted value obtained from the USB keyboard reader:
So the inverted value (logical NOT) from the Wiegand interface matches the value read by the USB reader.
Next, let's look at the two parity bits. The data over the Wiegand interface typically looks like:
The first line being the bits numbered as they arrive over the Wiegand wires. The second line being the same bits as they need to be interpreted by the receiver, where
PE
(b0
) is an even parity bit overD23..D12
(b1..b12
),PO
(b25
) is an odd parity bit overD11..D0
(b13..b24
), andD23..D0
are the data bits representing an unsigned integer number.So looking at your number, you would have received:
If we check the parity bits
PE
andPO
, we get:contains 4 ones (
1
), hence even parity is met.contains 7 ones (
1
), hence odd parity is met.So, to summarize the above, your code reading from the Wiegand interface does not properly handle the Wiegand data format. First, it does not trim the parity bits and second, it reads the bits with wrong polarity (zeros are ones and ones are zeros).
In order to get the correct number from the Wiegand reader, you either have to fix you code for reading from the Wiegand interface (to fix polarity, to skip the first and the last bit from the data value, and to possibly check the parity bits). Or you can take the value that you currently get, invert that value, and strip the lower and upper bits. In C, that would look something like this: