Opening Doors

Second post! That's a thing, right? Good.

Last time, I got as far as reading out bits from the card. I noticed a few things about the output bits:

  • The first half of the code was always the same.
  • The code was around 35 bits long.

With enough cards, I could have reverse-engineered the card code, but Cyborg Mode is easier. A few quick searches turned up a site explaining the HID format. In essence, the card has two pieces of data stored on it: a 12 bit facility code (same of all Lafayette cards), and a 20-bit card code (different on each). A quick aside: 220=1,048,576, so Lafayette's 2,500 students use only a smidge of the possible combinations.

So, I have 35 bits read in, but only the last 20 are relevant for our use case. I have bits coming in one at a time, and I need to check for a match after the stream stops.

I still need to decide how to store and check data. An int only holds 8 or 16 bits (depending), and strings are messy to create. Longs, though, hold 32 bits of data - almost the whole card. I could create a revolving long of the last 32 bits read. It would hold almost an entire card, and flush out the last data read before beginning. The << operator shifts bits left, and the + operator will add. (Shocking, I know.) Writing the new code was incredibly easy. Just add a few lines to the working program from last time.

//The volatile keyword is required for variables modified inside of an interrupt.
volatile long current = 0;
volatile boolean changed = false;

void DATA1() {
  current = current << 1; //Shift bits left
  current += 1; //Add one to the end.
  changed = true;
  Serial.print(1);
}

void DATA0() {
  //Shift bits left; (add zero)
  current = current << 1;
  changed = true;
  Serial.print(0);
}

void setup() {
  Serial.begin(9600);
 
  attachInterrupt(0, DATA0, FALLING);  // DATA0 (green) on HID reader, Pin 2 on Arduino
  attachInterrupt(1, DATA1, FALLING);  // DATA1 (white) on HID reader, Pin 3 on Arduino
  delay(10);
}

void loop() {
delay(100);
if(changed) { //Print iff the value has changed.
Serial.println(current);
changed = false;
}
}

This new code tracks the last 32 bits of the card, which is enough to uniquely identify all cards on campus. The ones I scanned all had values of around -881170000, give or take a few hundred thousand. That is, the first bits are all the same, and the ones towards the end aren't.

I added functionality for checking the read key against a list of approved keys, and that's where I stand as of writing. To do:

  • Add a servo to actually unlock the door
  • Use a button and EEPROM to allow for adding more keys
  • Other features? Alarm? Timeout? Awesomesauce?