Skip to content

Instantly share code, notes, and snippets.

@linuxgemini
Created April 8, 2021 12:44
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save linuxgemini/aa53940856bc9a212b8ca4fd39d7018f to your computer and use it in GitHub Desktop.
Save linuxgemini/aa53940856bc9a212b8ca4fd39d7018f to your computer and use it in GitHub Desktop.
/*
* HID RFID Reader Wiegand Interface for Arduino Uno
* Originally by Daniel Smith, 2012.01.30 -- http://www.pagemac.com/projects/rfid/arduino_wiegand
*
* Updated 2016-11-23 by Jon "ShakataGaNai" Davis.
* See https://obviate.io/?p=7470 for more details & instructions
*
*
* Updated 2021-04-08 by linuxgemini
*/
#define MAX_BITS 128 // max number of bits
#define WIEGAND_WAIT_TIME 3000 // time to wait for another wiegand 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 wiegand_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;
wiegand_counter = WIEGAND_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;
wiegand_counter = WIEGAND_WAIT_TIME;
}
void setup() {
pinMode(2, INPUT); // DATA0 (INT0)
pinMode(3, INPUT); // DATA1 (INT1)
Serial.begin(9600);
Serial.println("Ready.");
// binds the ISR functions to the falling edge of INTO and INT1
attachInterrupt(0, ISR_INT0, FALLING);
attachInterrupt(1, ISR_INT1, FALLING);
wiegand_counter = WIEGAND_WAIT_TIME;
}
void loop() {
// This waits to make sure that there have been no more data pulses before processing data
if (!flagDone) {
if (--wiegand_counter == 0)
flagDone = 1;
}
// if we have bits and we the wiegand counter went out
if (bitCount > 0 && flagDone) {
unsigned char i;
Serial.print("Read ");
Serial.print(bitCount);
Serial.print(" bits. ");
Serial.print("Binary: ");
for (i=0; i<bitCount; i++) {
Serial.print(databits[i], HEX);
}
Serial.print(", ");
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!
if ((bitCount % 8 == 0) && bitCount != 0) {
Serial.print("Hex: ");
int index = 0;
uint8_t acc = 0;
while (index < bitCount) {
acc = 0;
for (i=0; i<8; i++){
acc = acc << 1;
if(databits[index + i] == 1) acc |= 1;
}
char tmp[16];
sprintf(tmp, "%02X", acc);
Serial.print(tmp);
index = index + 8;
}
Serial.println();
} else {
// 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() {
Serial.print("FC = ");
Serial.print(facilityCode);
Serial.print(", CC = ");
Serial.println(cardCode);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment