2020-03-28 17:18:54 -04:00
|
|
|
// Based on: http://www.pagemac.com/projects/rfid/arduino_wiegand
|
|
|
|
|
2020-03-28 16:09:35 -04:00
|
|
|
#include <Keyboard.h>
|
|
|
|
|
2020-03-28 17:08:27 -04:00
|
|
|
// DATA pins
|
|
|
|
#define DATA0 2
|
|
|
|
#define DATA1 3
|
|
|
|
|
2020-03-28 17:07:52 -04:00
|
|
|
#define WEIGAND_WAIT_TIME 500 // time to wait for another weigand pulse.
|
2020-03-28 16:09:35 -04:00
|
|
|
|
|
|
|
#define DATA_SIZE 32
|
2020-03-28 17:07:52 -04:00
|
|
|
volatile uint32_t dataBits = 0; // stores all of the data bits
|
|
|
|
volatile size_t bitCount = 0; // number of bits recieved
|
2020-03-28 16:09:35 -04:00
|
|
|
|
2020-03-28 17:07:52 -04:00
|
|
|
volatile unsigned long weigand_idle_start;
|
2020-03-28 16:09:35 -04:00
|
|
|
|
2020-03-28 17:09:09 -04:00
|
|
|
inline void gotBit(char bit) {
|
2020-03-28 17:07:52 -04:00
|
|
|
weigand_idle_start = millis();
|
2020-03-28 17:19:16 -04:00
|
|
|
//Serial.print(bit, BIN);
|
2020-03-28 17:09:09 -04:00
|
|
|
bitWrite(dataBits, DATA_SIZE - bitCount, bit);
|
2020-03-27 17:14:10 -04:00
|
|
|
bitCount++;
|
|
|
|
}
|
2020-03-28 16:09:35 -04:00
|
|
|
|
2020-03-28 17:18:54 -04:00
|
|
|
// interrupts for DATA0/DATA1
|
|
|
|
void ISR_INT0() { gotBit(0); }
|
|
|
|
void ISR_INT1() { gotBit(1); }
|
2020-03-28 16:09:35 -04:00
|
|
|
|
2020-03-27 17:14:10 -04:00
|
|
|
void setup() {
|
2020-03-28 17:08:27 -04:00
|
|
|
pinMode(DATA0, INPUT);
|
|
|
|
pinMode(DATA1, INPUT);
|
2020-03-28 16:09:35 -04:00
|
|
|
|
2020-03-27 17:14:10 -04:00
|
|
|
Serial.begin(9600);
|
2020-03-28 16:09:35 -04:00
|
|
|
|
2020-03-28 17:08:27 -04:00
|
|
|
attachInterrupt(digitalPinToInterrupt(DATA0), ISR_INT0, FALLING);
|
|
|
|
attachInterrupt(digitalPinToInterrupt(DATA1), ISR_INT1, FALLING);
|
2020-03-28 16:09:35 -04:00
|
|
|
|
|
|
|
Keyboard.begin();
|
2020-03-27 17:14:10 -04:00
|
|
|
}
|
2020-03-28 16:09:35 -04:00
|
|
|
|
2020-03-27 17:14:10 -04:00
|
|
|
void loop()
|
|
|
|
{
|
2020-03-28 17:18:54 -04:00
|
|
|
// Check if last bit was recieved more than WEIGAND_WAIT_TIME ago
|
2020-03-28 17:07:52 -04:00
|
|
|
if (bitCount > 0 && (millis() - weigand_idle_start) >= WEIGAND_WAIT_TIME) {
|
2020-03-27 17:14:10 -04:00
|
|
|
unsigned char i;
|
2020-03-28 16:09:35 -04:00
|
|
|
uint32_t data = dataBits >> (DATA_SIZE - bitCount + 1);
|
|
|
|
|
2020-03-27 17:14:10 -04:00
|
|
|
Serial.print("Read ");
|
|
|
|
Serial.print(bitCount);
|
2020-03-28 16:09:35 -04:00
|
|
|
Serial.print(" bits: ");
|
|
|
|
Serial.println(data, BIN);
|
|
|
|
|
|
|
|
// standard 26 bit format:
|
|
|
|
// P: parity bit, F: facility code, C: card code
|
|
|
|
// PFFFFFFFFCCCCCCCCCCCCCCCCP
|
|
|
|
if (bitCount == 26) {
|
2020-03-28 17:11:24 -04:00
|
|
|
uint8_t facilityCode = (data >> 17) & 0xFF;
|
|
|
|
uint16_t cardCode = (data >> 1) & 0xFFFF;
|
2020-03-28 16:09:35 -04:00
|
|
|
// TODO: check parity bits
|
|
|
|
|
|
|
|
printBits(facilityCode, cardCode);
|
2020-03-27 17:14:10 -04:00
|
|
|
}
|
|
|
|
else {
|
2020-03-28 16:09:35 -04:00
|
|
|
// TODO: handle failures and other formats
|
2020-03-27 17:14:10 -04:00
|
|
|
}
|
2020-03-28 16:09:35 -04:00
|
|
|
|
|
|
|
// reset for the next card
|
|
|
|
bitCount = 0;
|
2020-03-27 17:14:10 -04:00
|
|
|
}
|
|
|
|
}
|
2020-03-28 16:09:35 -04:00
|
|
|
|
|
|
|
void printBits(uint8_t facilityCode, uint16_t cardCode) {
|
2020-03-28 17:18:54 -04:00
|
|
|
Keyboard.print(facilityCode);
|
|
|
|
Keyboard.print('\t');
|
|
|
|
Keyboard.print(cardCode);
|
|
|
|
Keyboard.print('\n');
|
|
|
|
|
2020-03-28 16:09:35 -04:00
|
|
|
Serial.print("FC = ");
|
|
|
|
Serial.print(facilityCode);
|
|
|
|
Serial.print(", CC = ");
|
|
|
|
Serial.println(cardCode);
|
2020-03-27 17:14:10 -04:00
|
|
|
}
|