HID Reader Inadala with KFS Cards wiegand

Hi,

I need to get the value from my RFID Card (KSF Format) Wiegand.

Im using this code that I found here:

http://www.pagemac.com/projects/rfid/arduino_wiegand

/*
 * HID RFID Reader Wiegand Interface for Arduino Uno
 * Written by Daniel Smith, 2012.01.30
 * www.pagemac.com
 *
 * This program will decode the wiegand data from a HID RFID Reader (or, theoretically,
 * any other device that outputs weigand data).
 * The Wiegand interface has two data lines, DATA0 and DATA1.  These lines are normall held
 * high at 5V.  When a 0 is sent, DATA0 drops to 0V for a few us.  When a 1 is sent, DATA1 drops
 * to 0V for a few us.  There is usually a few ms between the pulses.
 *
 * Your reader should have at least 4 connections (some readers have more).  Connect the Red wire 
 * to 5V.  Connect the black to ground.  Connect the green wire (DATA0) to Digital Pin 2 (INT0).  
 * Connect the white wire (DATA1) to Digital Pin 3 (INT1).  That's it!
 *
 * Operation is simple - each of the data lines are connected to hardware interrupt lines.  When
 * one drops low, an interrupt routine is called and some bits are flipped.  After some time of
 * of not receiving any bits, the Arduino will decode the data.  I've only added the 26 bit and
 * 35 bit formats, but you can easily add more.
 
*/
 
 
#define MAX_BITS 100                 // max number of bits 
#define WEIGAND_WAIT_TIME  3000      // time to wait for another weigand pulse.  
 
unsigned char databits[MAX_BITS];    // stores all of the data bits
unsigned char bitCount;              // number of bits currently captured
unsigned char flagDone;              // goes low when data is currently being captured
unsigned int weigand_counter;        // countdown until we assume there are no more bits
 
unsigned long facilityCode=0;        // decoded facility code
unsigned long cardCode=0;            // decoded card code
 
// interrupt that happens when INTO goes low (0 bit)
void ISR_INT0()
{
  //Serial.print("0");   // uncomment this line to display raw binary
  bitCount++;
  flagDone = 0;
  weigand_counter = WEIGAND_WAIT_TIME;  
 
}
 
// interrupt that happens when INT1 goes low (1 bit)
void ISR_INT1()
{
  //Serial.print("1");   // uncomment this line to display raw binary
  databits[bitCount] = 1;
  bitCount++;
  flagDone = 0;
  weigand_counter = WEIGAND_WAIT_TIME;  
}
 
void setup()
{
  pinMode(13, OUTPUT);  // LED
  pinMode(2, INPUT);     // DATA0 (INT0)
  pinMode(3, INPUT);     // DATA1 (INT1)
 
  Serial.begin(9600);
  Serial.println("RFID Readers");
 
  // binds the ISR functions to the falling edge of INTO and INT1
  attachInterrupt(0, ISR_INT0, FALLING);  
  attachInterrupt(1, ISR_INT1, FALLING);
 
 
  weigand_counter = WEIGAND_WAIT_TIME;
}
 
void loop()
{
  // This waits to make sure that there have been no more data pulses before processing data
  if (!flagDone) {
    if (--weigand_counter == 0)
      flagDone = 1; 
  }
 
  // if we have bits and we the weigand counter went out
  if (bitCount > 0 && flagDone) {
    unsigned char i;
 
    Serial.print("Read ");
    Serial.print(bitCount);
    Serial.print(" bits. ");
 
    // we will decode the bits differently depending on how many bits we have
    // see www.pagemac.com/azure/data_formats.php for mor info
    if (bitCount == 35)
    {
      // 35 bit HID Corporate 1000 format
      // facility code = bits 2 to 14
      for (i=2; i<14; i++)
      {
         facilityCode <<=1;
         facilityCode |= databits[i];
      }
 
      // card code = bits 15 to 34
      for (i=14; i<34; i++)
      {
         cardCode <<=1;
         cardCode |= databits[i];
      }
 
      printBits();
    }
    else if (bitCount == 26)
    {
      // standard 26 bit format
      // facility code = bits 2 to 9
      for (i=1; i<9; i++)
      {
         facilityCode <<=1;
         facilityCode |= databits[i];
      }
 
      // card code = bits 10 to 23
      for (i=9; i<25; i++)
      {
         cardCode <<=1;
         cardCode |= databits[i];
      }
 
      printBits();  
    }
    else {
      // you can add other formats if you want!
     Serial.println("Unable to decode."); 
    }
 
     // cleanup and get ready for the next card
     bitCount = 0;
     facilityCode = 0;
     cardCode = 0;
     for (i=0; i<MAX_BITS; i++) 
     {
       databits[i] = 0;
     }
  }
}
 
void printBits()
{
      // I really hope you can figure out what this function does
      Serial.print("FC = ");
      Serial.print(facilityCode);
      Serial.print(", CC = ");
      Serial.println(cardCode); 
}

But when I hover the Card over the reader I get "Unable to decode."

Then I found this code here: Indala ASR 503 - Device Hacking - Arduino Forum

volatile unsigned long reader1 = 0;

volatile int reader1Count = 0;
volatile int overallCount = 0;

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

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

void setup()
{
  Serial.begin(9600);

  attachInterrupt(0, reader1Zero, RISING);//DATA0 to pin 2
  attachInterrupt(1, reader1One, RISING); //DATA1 to pin 3
  delay(10);
  
  for(int i = 2; i<4; i++){
    pinMode(i, OUTPUT);
    digitalWrite(i, HIGH); 
    digitalWrite(i, LOW); 
    pinMode(i, INPUT);
    digitalWrite(i, HIGH);
  }
  delay(10);
  
  reader1 = 0;
  reader1Count = 0;
}

void loop()
{
  if(reader1Count >=34){
     int serialNumber=(reader1 >> 7) & 0x3fff;
     int siteCode= (reader1 >> 21) & 0x1ff;

     Serial.print("Site code: ");
     Serial.println(siteCode);
     Serial.print("Card No: ");
     Serial.println(serialNumber);
     
     reader1 = 0;
     reader1Count = 0;
  }
}

And then I get values from every time I pass the card I get random values.

Im attaching a picture of the Indala card with the KFS.

In the card there is a number 71:59475, thats the number I need to get.

UPDATE Using the first code I detect the bitCount variable value is 32, so it seems the Card is a 32 Bit Wiegand card.

I really appreciate any help!! Please

I had the same problem, using a 32-bit Motorola HID reader. Here is the code I used:

else if (bitCount == 32) {
      // 32 bit Motorola format
      // facility code = bits 2 to 17

      //for (i=0; i<9; i++) {
      //   facilityCode <<=1;
      //   facilityCode |= databits[i];
      //}
 
      // card code = bits 9 to 29
      for (i=9; i<30; i++) {
         cardCode <<=1;
         cardCode |= databits[i];
      }

I commented out the Facility Code, as I don't use it.

variable value is 32, so it seems the Card is a 32 Bit Wiegand card

So you need to add the decoding for 32 bits in place of the

else {
      // you can add other formats if you want!

For a start you can just copy the 35 bit HID Corporate 1000 format code, and then expand the number of bits it moves into the serialNumber variable. Most Weagand codes have the first and last bit as parity bits, I see that code is not checking them. There might also be parity bits between faculty code and the serial number.

void printBits()
{
      // I really hope you can figure out what this function does

The function just prints out the two number you have found from the card, however it shows the numbers in decimal. Often these numbers are displayed as hex.