125kHz RFID module: simpler Wiegand code

I had some problems with the Wiegand demo code, in particular it wasn’t returning the numbers printed on the tags. This simpler version does return the numbers on the tags and is I think a bit clearer, though it will be a little slower.

The main problem with the original code seems to be that the data pins are mislabelled in the data sheet. The DATA1 line, that is the line that goes low when the output bit is 1, is actually pin 1 on the board (the one closest to the edge), not pin 2. The DATA0 line is pin 2.

Anyway here is the code, hope this helps someone:

[code]//******************************
#ifndef RFID
#define RFID
//==============================
#define DATA0 9 // DATA0 from RFID module (pin 2) connected to this Arduino pin. Note these seem to be mislabelled on the data sheet?
#define DATA1 8 // DATA1 from RFID module (pin 1) connected to this Arduino pin
//==============================
#endif
//******************************

unsigned long tag=0;
unsigned char receive_count=0;

void setup()
{
Serial.begin(115200);
pinMode(DATA0, INPUT);
digitalWrite(DATA0, HIGH); // pullup
pinMode(DATA1, INPUT);
digitalWrite(DATA1, HIGH); // pullup

}
void loop()
{
unsigned char data0=0,data1=0;
// data1 low = bit 1 transmitted, data0 low = bit 0 transmitted
data0 = digitalRead(DATA0);
data1 = digitalRead(DATA1);
//--------------------------------------------
if(data0 != data1) // new bit detected
{
if (receive_count != 0) { // skip the first parity bit
tag <<= 1; // shift previous bits left
if (!data1) { // bit is one if data1 is low
tag |= 1;
}
}
receive_count++;
delayMicroseconds(80); //Data impulse width delay 80us
}
else // no card incoming or finish reading card
{
if(receive_count>= 25) //output card number, skipping the last parity bit so don’t wait for bit 26
{
// Serial output will take longer than 80uS, otherwise you might need a delay here to make sure you skip the final parity bit
Serial.println(tag, DEC);

    // start new tag
    receive_count = 0;
    tag = 0;
  }
  //----------------------------------------------------      
}

} [/code]

2 Likes

Thank you so much, dave.

It’s true there’s mistakes about the pin maps of data0 and data1 on the datasheet.

To make the read data more reliable, you can add some delay after the Serial.print().

All the best,

-Icing

Dave - thanks for the Weigand code.
I have a piece of code after the serial.println line that moves a servo, wiats for 1 sec then returns the servo. Adding this code, withthe associated attaching of the servo to a digital pin, causes the reading of the tag number to fail - I end up with 3 or 4 digits. I assume it’s because the weigand data is not being held and stored and so I miss some data with the servo control code running??
Thanks
Kevin

Hi Kevin, yes it needs to be polling the input lines constantly to read the whole number. You could use interrupt-driven code like the code from this game: thebox.myzen.co.uk/Hardware/ … eople.html

This code basically works unchanged with the Seeedstudio reader except that it reads all 26 bits including the parity bits at the start and end of the code. You can strip them off with code like this to get the same number as printed on the tags:

unsigned long masked = reader3>>1 & 0xffffff; // strip parity bits

over 13 Years Later and this problem is still the same.

got a seeedgrove rfid reader which works in UART and Wiegand. For Wiegand the Pins need to be switched.

Thanks for sharing this solution and solving my problem as well :slight_smile: