arduinoWeigandKeyboard/hidReader.ino

106 lines
2.6 KiB
C++

/* Based on:
* 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
*/
#include <limits.h>
#include <Keyboard.h>
// LED pins
#define LED_GREEN 11;
#define LED_RED 12;
#define BEEP_BEEP 10;
#define WEIGAND_WAIT_TIME 3000 // time to wait for another weigand pulse.
#define DATA_SIZE 32
volatile uint32_t dataBits = 0; // stores all of the data bits
volatile size_t bitCount = 0; // number of bits recieved
volatile unsigned char flagDone; // goes low when data is currently being captured
volatile unsigned int weigand_counter; // countdown until we assume there are no more bits
inline void gotBit() {
bitCount++;
flagDone = 0;
weigand_counter = WEIGAND_WAIT_TIME;
}
// interrupt that happens when INTO goes low (0 bit)
void ISR_INT0() {
//Serial.print("0");
dataBits &= ~(1UL << (DATA_SIZE - bitCount));
gotBit();
}
// interrupt that happens when INT1 goes low (1 bit)
void ISR_INT1() {
//Serial.print("1");
dataBits |= 1UL << (DATA_SIZE - bitCount);
gotBit();
}
void setup() {
pinMode(2, INPUT); // DATA0 (INT0)
pinMode(3, INPUT); // DATA1 (INT1)
Serial.begin(9600);
attachInterrupt(0, ISR_INT0, FALLING);
attachInterrupt(1, ISR_INT1, FALLING);
weigand_counter = WEIGAND_WAIT_TIME;
Keyboard.begin();
}
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;
uint32_t data = dataBits >> (DATA_SIZE - bitCount + 1);
Serial.print("Read ");
Serial.print(bitCount);
Serial.print(" bits: ");
Serial.println(data, BIN);
// standard 26 bit format:
// P: parity bit, F: facility code, C: card code
// PFFFFFFFFCCCCCCCCCCCCCCCCP
if (bitCount == 26) {
uint8_t facilityCode = (data >> 17);
uint16_t cardCode = (data >> 1);
// TODO: check parity bits
Keyboard.print(facilityCode);
Keyboard.print('\t');
Keyboard.print(cardCode);
Keyboard.print('\n');
printBits(facilityCode, cardCode);
}
else {
// TODO: handle failures and other formats
}
// reset for the next card
bitCount = 0;
}
}
void printBits(uint8_t facilityCode, uint16_t cardCode) {
Serial.print("FC = ");
Serial.print(facilityCode);
Serial.print(", CC = ");
Serial.println(cardCode);
}