A library to read HID RFID cards through the wiegand protocol. This was tested with the HID ProxPoint Plus 6005BG00.

Dependents:   HID_ProxCard_Wiegand_Example

Wiegand Library for HID ProxPoint Plus

While this library should be able to read any wiegand input, the buffer can only store 64 bits, and it expects there to be less than a 5ms delay between each bit sent.

Here is a picture of some example wiring:

To use this library use the following pin attachments, the 6005BG00 has its pinouts on its back label (top right).

6005BG00 WireMBED PIN
data0p30
data1p29
holdp28
GNDGND
DRAINGND
5-16V (red)Vu

Here is a picuture of it wired up: /media/uploads/cbookman3/10264542_10152398127452363_476958199_n.jpg

include the mbed library with this snippet

void void onCardRead();
Wiegand rfid(p30, p29, p28, &onCardRead);

int main() {
  while(1) {
    rfid.doEvents(); //checks if data has been fully read, and calls the callback
  }
}

void onCardRead() {
  /*
    Do stuff with data, as we've fully read the card.
    WHen this function exits, RFID reader will be reset to read
    Another Card
  */
   //returns the unique student identifier on a buzzcard  (6 digit number on back of buzzcard below gatech seal)
    uint64_t rawCardData = rfid.getBits(14,33); 
}

Description of public methods

methoddescription
Wiegand(PinName pdata0, PinName pdata1, PinName pHold, void (*onCardRead)());constructor, call WIegand wiegand (...)
void doEvents(void)checks if all RFID data has been read though the use of a timer, and calls the onCardRead callback
uint8_t bitsRead(void)returns the number of bits read
uint64_t getBits(uint8_t start, uint8_t end)Returns the bits read from in [start,end] (Inclusive). If its an invalid range, returns 0

Example Program

Import programHID_ProxCard_Wiegand_Example

Example program to read HID ProxCards using the gatech BuzzCard format with a HID ProxPoint Plus 6005BG00.

Here is a video of the example program in action:

ProxPoint Plus 6005BG00 Oscilloscope Capture

/media/uploads/cbookman3/oscopecapture.jpg

Gatech BuzzCard Protocol

The rfid buzzcard unique student identifier can be found on the back of your buzzcard below the shiny gatech seal (6 digit number). Each buzzcard's rfid tag stores 35 bits of data, but only bits [14,33] contain your id (bit index starts at 0, and range is inclusive).

Committer:
cbookman3
Date:
Wed Apr 23 16:44:05 2014 +0000
Revision:
2:47ffa4e32ce3
Parent:
1:a960b42eb198
added keyboad emulation;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
cbookman3 0:21edeadd0ca0 1 #include "Wiegand.h"
cbookman3 0:21edeadd0ca0 2 #include "mbed.h"
cbookman3 0:21edeadd0ca0 3
cbookman3 0:21edeadd0ca0 4 Wiegand::Wiegand(PinName pdata0, PinName pdata1, PinName pHold, void (*onCardRead)()) : _data0ISR(pdata0), _data1ISR(pdata1), _hold(pHold) {
cbookman3 0:21edeadd0ca0 5 _onCardRead = onCardRead;
cbookman3 0:21edeadd0ca0 6 /*
cbookman3 0:21edeadd0ca0 7 stop reader from sending us any data
cbookman3 0:21edeadd0ca0 8 and ensure after this block that no data through
cbookman3 0:21edeadd0ca0 9 wiegand gets sent
cbookman3 0:21edeadd0ca0 10 */
cbookman3 0:21edeadd0ca0 11 _hold = 1;
cbookman3 0:21edeadd0ca0 12 wait_ms(250);
cbookman3 0:21edeadd0ca0 13 _sizeOfBuffer = sizeof(_buffer)/sizeof(*_buffer);
cbookman3 0:21edeadd0ca0 14 _resetBuffer();
cbookman3 0:21edeadd0ca0 15
cbookman3 0:21edeadd0ca0 16 /* Attach our interrupts, and start the ISRs */
cbookman3 0:21edeadd0ca0 17 _attachInterrupts();
cbookman3 0:21edeadd0ca0 18 _hold = 0; //start sending data
cbookman3 0:21edeadd0ca0 19 }
cbookman3 0:21edeadd0ca0 20
cbookman3 0:21edeadd0ca0 21 /*
cbookman3 0:21edeadd0ca0 22 Check if we've read all card data
cbookman3 0:21edeadd0ca0 23 */
cbookman3 0:21edeadd0ca0 24 void Wiegand::doEvents(void) {
cbookman3 1:a960b42eb198 25 if(_bitsRead > 0 && _lastISR.read_ms() > 5) {
cbookman3 0:21edeadd0ca0 26 _onCardRead();
cbookman3 0:21edeadd0ca0 27 _resetBuffer();
cbookman3 0:21edeadd0ca0 28 _hold = 0;
cbookman3 0:21edeadd0ca0 29 }
cbookman3 0:21edeadd0ca0 30 }
cbookman3 0:21edeadd0ca0 31
cbookman3 0:21edeadd0ca0 32 /*
cbookman3 0:21edeadd0ca0 33 return number of bits currently read
cbookman3 0:21edeadd0ca0 34 */
cbookman3 0:21edeadd0ca0 35 uint8_t Wiegand::bitsRead(void) {
cbookman3 0:21edeadd0ca0 36 return _bitsRead;
cbookman3 0:21edeadd0ca0 37 }
cbookman3 0:21edeadd0ca0 38
cbookman3 0:21edeadd0ca0 39 /*
cbookman3 0:21edeadd0ca0 40 Returns the bits read from in [start,end] (Inclusive).
cbookman3 0:21edeadd0ca0 41 if [start,end] not in range of the bits read, 0 is returned
cbookman3 0:21edeadd0ca0 42 */
cbookman3 0:21edeadd0ca0 43 uint64_t Wiegand::getBits(uint8_t start, uint8_t end) {
cbookman3 0:21edeadd0ca0 44 //make sure the start and end indexes don't over index our read bit buffer
cbookman3 0:21edeadd0ca0 45 if(!(start < _bitsRead) || !(end < _bitsRead)) {
cbookman3 0:21edeadd0ca0 46 return 0;
cbookman3 0:21edeadd0ca0 47 }
cbookman3 0:21edeadd0ca0 48 uint64_t output = 0;
cbookman3 0:21edeadd0ca0 49 for(int i = start; i <= end; ++i) {
cbookman3 0:21edeadd0ca0 50 output <<=1;
cbookman3 0:21edeadd0ca0 51 output |= 0x1 & _buffer[i];
cbookman3 0:21edeadd0ca0 52 }
cbookman3 0:21edeadd0ca0 53 return output;
cbookman3 0:21edeadd0ca0 54 }
cbookman3 0:21edeadd0ca0 55
cbookman3 0:21edeadd0ca0 56 /*
cbookman3 0:21edeadd0ca0 57 Resets the buffer to its intial state (0), and _bitsRead = 0
cbookman3 0:21edeadd0ca0 58 */
cbookman3 0:21edeadd0ca0 59 void Wiegand::_resetBuffer(void) {
cbookman3 0:21edeadd0ca0 60 for(int i = 0, l = _sizeOfBuffer; i <l; ++i) { _buffer[i] = 0; }
cbookman3 0:21edeadd0ca0 61 _bitsRead = 0;
cbookman3 0:21edeadd0ca0 62 }
cbookman3 0:21edeadd0ca0 63
cbookman3 0:21edeadd0ca0 64 /*
cbookman3 0:21edeadd0ca0 65 Attach ISRs to the rising edge
cbookman3 0:21edeadd0ca0 66 */
cbookman3 0:21edeadd0ca0 67 void Wiegand::_attachInterrupts(void) {
cbookman3 0:21edeadd0ca0 68 _data0ISR.rise(this, &Wiegand::_data0ISRAction);
cbookman3 0:21edeadd0ca0 69 _data1ISR.rise(this, &Wiegand::_data1ISRAction);
cbookman3 0:21edeadd0ca0 70 }
cbookman3 0:21edeadd0ca0 71
cbookman3 0:21edeadd0ca0 72 /*
cbookman3 0:21edeadd0ca0 73 Data0ISR Routine, called by rising edge of data0
cbookman3 0:21edeadd0ca0 74 */
cbookman3 0:21edeadd0ca0 75 void Wiegand::_data0ISRAction(void) {
cbookman3 0:21edeadd0ca0 76 _lastISR.reset();
cbookman3 0:21edeadd0ca0 77 _lastISR.start();
cbookman3 0:21edeadd0ca0 78 _hold = 1;
cbookman3 0:21edeadd0ca0 79 if(_bitsRead < _sizeOfBuffer) {
cbookman3 0:21edeadd0ca0 80 _buffer[_bitsRead++] = 0;
cbookman3 0:21edeadd0ca0 81 }
cbookman3 0:21edeadd0ca0 82 }
cbookman3 0:21edeadd0ca0 83
cbookman3 0:21edeadd0ca0 84 /*
cbookman3 0:21edeadd0ca0 85 Data1ISR Routine, called by rising edge of data1
cbookman3 0:21edeadd0ca0 86 */
cbookman3 0:21edeadd0ca0 87 void Wiegand::_data1ISRAction(void) {
cbookman3 0:21edeadd0ca0 88 _lastISR.reset();
cbookman3 0:21edeadd0ca0 89 _lastISR.start();
cbookman3 0:21edeadd0ca0 90 _hold = 1;
cbookman3 0:21edeadd0ca0 91 if(_bitsRead < _sizeOfBuffer) {
cbookman3 0:21edeadd0ca0 92 _buffer[_bitsRead++] = 1;
cbookman3 0:21edeadd0ca0 93 }
cbookman3 0:21edeadd0ca0 94 }