Go Down

Topic: Wiegand 26 bit + UNO RFID Door Lock Help/Contribution (Read 1 time) previous topic - next topic

Kushballz

I've been a long-time lurker of the forums and thought I'd finally contribute something useful to the community. I had trouble finding a simple code to interface a Wiegand 26 bit RFID reader with the UNO. I still have a problem where a card will be misread and the site code and serial will be random numbers. For example, card 419-7610 will sometimes read as 443-13777, 931-7610, 116-15287, or other variants. Rereading the card will eventually match. I'm not sure if it is a reader problem or a problem with the code, but either way, it works. Sometimes it just takes an extra swipe or two. Any help with that would be appreciated!

Code: [Select]

/* Wiegand RFID Door Lock (CrazyPeople)
* Code By Mike Cook April 2009, Edited by Kushballz April 2014
* Standard 5-wire Weigand RFID Reader (13.56MHz)
* (BLK=GND,RED=12-15VDC,GRN=DATA0, WHT=DATA1, GRY=Buzzer, VIOLET=disconnected for Wiegand 26 and GND for Wiegand 44)
* Reader DATA 0 (GRN) to Pin 2, DATA 1 (WHT) to Pin 3
* Site codes are first portion of RFID card, Serial is Last portion of RFID card (sitecode#-serial#)
* LOW output "strike" var sent to pin 12. Connect to relay to drive door lock solenoid
* Interrupt service routine gathers Wiegand pulses (zero or one) until 26 have been recieved
* Then a sting is sent to processing
*/
int strike = 12;
int validSiteCodes[] = {419, 149, 151, 411, 164};
int validSerialNumbers[] = {7610, 11962, 11018, 8346, 4506};// see if site code and serial number are in the lists...

volatile long reader1 = 0;
volatile int reader1Count = 0;

void reader1One(void) {
  reader1Count++;
  reader1 = reader1 << 1;
  reader1 |= 1;
}

void reader1Zero(void) {
  reader1Count++;
  reader1 = reader1 << 1;
}

void setup()
{
  pinMode(strike,OUTPUT);
  digitalWrite(strike,HIGH);
  Serial.begin(9600);
  // Attach pin change interrupt service routines from the Wiegand RFID readers
  attachInterrupt(0, reader1Zero, RISING);//DATA0 to pin 2
  attachInterrupt(1, reader1One, RISING); //DATA1 to pin 3
  delay(10);
  // the interrupt in the Atmel processor mises out the first negitave pulse as the inputs are already high,
  // so this gives a pulse to each reader input line to get the interrupts working properly.
  // Then clear out the reader variables.
  // The readers are open collector sitting normally at a one so this is OK
  for(int i = 2; i<4; i++){
  pinMode(i, OUTPUT);
   digitalWrite(i, HIGH); // enable internal pull up causing a one
  digitalWrite(i, LOW); // disable internal pull up causing zero and thus an interrupt
  pinMode(i, INPUT);
  digitalWrite(i, HIGH); // enable internal pull up
  }
  delay(10);
  // put the reader input variables to zero
  reader1 = 0;
  reader1Count = 0;
}

void loop()
{
  if(reader1Count >=26){
int serialNumber=(reader1 >> 1) & 0x3fff;
int siteCode= (reader1 >> 17) & 0x3ff;
Serial.print("Site Code: ");
Serial.print(siteCode);
Serial.print(" Serial: ");
Serial.println(serialNumber);
  reader1 = 0;
  reader1Count = 0;
if(IsTagValid(siteCode, serialNumber)
){
  digitalWrite(strike,LOW);
}
  else
    digitalWrite(strike,HIGH);
    delay(3000);
    digitalWrite(strike,HIGH);   // Open the door. It's cold out here!
}
     }

boolean IsTagValid(int siteCode, int serialNumber)
{
   boolean valid = false;

   // Determine how many valid tags there are
   int validTagCount = sizeof(validSiteCodes)/sizeof(int);

   // Loop through the arrays to see if siteCode
   // and serialNumber are present

   for(int t=0; t<validTagCount; t++)
   {
      if(validSiteCodes[t] == siteCode &&
         validSerialNumbers[t] == serialNumber)
      {
          valid = true;
          break;
      }
   }

   return valid;

Go Up