Home > Arduino > Magnetic Card lock with the Arduino

Magnetic Card lock with the Arduino

February 17th, 2010 Leave a comment Go to comments

I have posted alot of projects recently, and here is another project with the Arduino!
This projects is about making a magnetic card lock using the Arduino, a servo and a $4 cheap magnetic card reader from AllElectronics.com

Magnetic Card Lock project


Magnetic Card Reader Connections

The card reader, which you can see in the first picture, has 7 pins. The picture below shows theese pins functionality!

I’ve made a video about the project which explains it all!
httphd://www.youtube.com/watch?v=S1i1DAMpy5E

If you want to try it yourself, you can grab the code underneath and change the checkCode character array to match the string on your card!

#include <string.h>

#include <Servo.h>
Servo servo1;

 /* Magnetic Card lock with the Arduino and servo's
 * by Thomas Jespersen http://elec.tkjweb.dk
 *
 * Reads a magnetic stripe and opens lock (turns servo) if card is the same as programmed
 *
 */

// Connections: DATA = Pin 2, CLOCK = Pin 3, CARD IN = Pin 5
// See PDF "Magnetic Stripe Card Reader! << HACKMIAMI.pdf" for more connection information


int cld1Pin = 5;            // Card status pin
int rdtPin = 2;             // Data pin
int reading = 0;            // Reading status
volatile int buffer[400];   // Buffer for data
volatile int i = 0;         // Buffer counter
volatile int bit = 0;       // global bit
char cardData[40];          // holds card info
int charCount = 0;          // counter for info
int DEBUG = 0;
const byte checkCodeLen = 23;
char checkCode[checkCodeLen+1] = ";0123456789=0123456789?";
boolean unlock = false;

void setup() {
  Serial.begin(9600);

  servo1.attach(9);
  servo1.write(10);

  // The interrupts are key to reliable
  // reading of the clock and data feed
  attachInterrupt(0, changeBit, CHANGE);
  attachInterrupt(1, writeBit, FALLING);
}

void loop(){

  // Active when card present
  while(digitalRead(cld1Pin) == LOW){
    reading = 1;
  }

  // Active when read is complete
  // Reset the buffer
  if(reading == 1) {

    if (DEBUG == 1) {
      printBuffer();
    }

    decode();
    reading = 0;
    i = 0;

    int l;
    for (l = 0; l < 40; l = l + 1) {
     cardData[l] = '\n';
    }

    // Code added by mindthomas for buffer clearing (If not, you can just insert card slightly, and then last card data will be written)
    for (l = 0; l < 200; l = l + 1) {
      buffer[l] = 0;
    }
    // End of added code

    charCount = 0;
  }
}

// Flips the global bit
void changeBit(){
  if (bit == 0) {
    bit = 1;
  } else {
    bit = 0;
  }
}

// Writes the bit to the buffer
void writeBit(){
  buffer[i] = bit;
  i++;
}

// prints the buffer
void printBuffer(){
  int j;
  for (j = 0; j < 200; j = j + 1) {
    Serial.println(buffer[j]);
  }
}

int getStartSentinal(){
  int j;
  int queue[5];
  int sentinal = 0;

  for (j = 0; j < 400; j = j + 1) {
    queue[4] = queue[3];
    queue[3] = queue[2];
    queue[2] = queue[1];
    queue[1] = queue[0];
    queue[0] = buffer[j];

    if (DEBUG == 1) {
      Serial.print(queue[0]);
      Serial.print(queue[1]);
      Serial.print(queue[2]);
      Serial.print(queue[3]);
      Serial.println(queue[4]);
    }

    if (queue[0] == 0 & queue[1] == 1 & queue[2] == 0 & queue[3] == 1 & queue[4] == 1) {
      sentinal = j - 4;
      break;
    }
  }

  if (DEBUG == 1) {
    Serial.print("sentinal:");
    Serial.println(sentinal);
    Serial.println("");
  }

  return sentinal;
}

void decode() {
  int sentinal = getStartSentinal();
  int j;
  int i = 0;
  int k = 0;
  int thisByte[5];

  for (j = sentinal; j < 400 - sentinal; j = j + 1) {
    thisByte[i] = buffer[j];
    i++;
    if (i % 5 == 0) {
      i = 0;
      if (thisByte[0] == 0 & thisByte[1] == 0 & thisByte[2] == 0 & thisByte[3] == 0 & thisByte[4] == 0) {
        break;
      }
      printMyByte(thisByte);
    }
  }

  cardData[charCount] = '\0';

  Serial.print("Stripe_Data:");
  for (k = 0; k < charCount; k = k + 1) {
    Serial.print(cardData[k]);
  }
  Serial.println("");


 // Check if the card data is the same as the data in checkCode - if yes, unlock (turn servo)
 unlock = true;
 for (k = 0; k < checkCodeLen; k++) {
   if (cardData[k] == checkCode[k]) {
     if (DEBUG == 1) {
       Serial.print(cardData[k]);
       Serial.print("=");
       Serial.println(checkCode[k]);
     }
   } else {
     if (DEBUG == 1) {
       Serial.print(cardData[k]);
       Serial.print("!=");
       Serial.println(checkCode[k]);
     }
     unlock = false;
     break;
   }
 }

 if (unlock) {
  servo1.write(200);
  delay(2000);
  servo1.write(10);
  unlock = false;
 }


}

void printMyByte(int thisByte[]) {
  int i;
  for (i = 0; i < 5; i = i + 1) {
    if (DEBUG == 1) {
      Serial.print(thisByte[i]);
    }
}
    if (DEBUG == 1) {
      Serial.print("\t");
      Serial.print(decodeByte(thisByte));
      Serial.println("");
    }

    cardData[charCount] = decodeByte(thisByte);
    charCount ++;
}

char decodeByte(int thisByte[]) {
    if (thisByte[0] == 0 & thisByte[1] == 0 & thisByte[2] == 0 & thisByte[3] == 0 & thisByte[4] == 1){
      return '0';
    }
    if (thisByte[0] == 1 & thisByte[1] == 0 & thisByte[2] == 0 & thisByte[3] == 0 & thisByte[4] == 0){
      return '1';
    }

    if (thisByte[0] == 0 & thisByte[1] == 1 & thisByte[2] == 0 & thisByte[3] == 0 & thisByte[4] == 0){
      return '2';
    }

    if (thisByte[0] == 1 & thisByte[1] == 1 & thisByte[2] == 0 & thisByte[3] == 0 & thisByte[4] == 1){
      return '3';
    }

    if (thisByte[0] == 0 & thisByte[1] == 0 & thisByte[2] == 1 & thisByte[3] == 0 & thisByte[4] == 0){
      return '4';
    }

    if (thisByte[0] == 1 & thisByte[1] == 0 & thisByte[2] == 1 & thisByte[3] == 0 & thisByte[4] == 1){
      return '5';
    }

    if (thisByte[0] == 0 & thisByte[1] == 1 & thisByte[2] == 1 & thisByte[3] == 0 & thisByte[4] == 1){
      return '6';
    }

    if (thisByte[0] == 1 & thisByte[1] == 1 & thisByte[2] == 1 & thisByte[3] == 0 & thisByte[4] == 0){
      return '7';
    }

    if (thisByte[0] == 0 & thisByte[1] == 0 & thisByte[2] == 0 & thisByte[3] == 1 & thisByte[4] == 0){
      return '8';
    }

    if (thisByte[0] == 1 & thisByte[1] == 0 & thisByte[2] == 0 & thisByte[3] == 1 & thisByte[4] == 1){
      return '9';
    }

    if (thisByte[0] == 0 & thisByte[1] == 1 & thisByte[2] == 0 & thisByte[3] == 1 & thisByte[4] == 1){
      return ':';
    }

    if (thisByte[0] == 1 & thisByte[1] == 1 & thisByte[2] == 0 & thisByte[3] == 1 & thisByte[4] == 0){
      return ';';
    }

    if (thisByte[0] == 0 & thisByte[1] == 0 & thisByte[2] == 1 & thisByte[3] == 1 & thisByte[4] == 1){
      return '<';
    }

    if (thisByte[0] == 1 & thisByte[1] == 0 & thisByte[2] == 1 & thisByte[3] == 1 & thisByte[4] == 0){
      return '=';
    }

    if (thisByte[0] == 0 & thisByte[1] == 1 & thisByte[2] == 1 & thisByte[3] == 1 & thisByte[4] == 0){
      return '>';
    }

    if (thisByte[0] == 1 & thisByte[1] == 1 & thisByte[2] == 1 & thisByte[3] == 1 & thisByte[4] == 1){
      return '?';
    }
}

Categories: Arduino Tags:
  1. acanthephyra
    September 6th, 2010 at 15:36 | #1

    Hi there, neat project!

    I was wondering what writer you’re using for this one and where you bought it from; anywhere in the EU? (would make it easier)

    Cheers,

    Manuel

  2. September 7th, 2010 at 08:01 | #2

    Hi Manuel.
    I know everything about buying stuff inside or outside of EU, as I live in Denmark where we have to pay 25% TAX on everything that comes outside of EU πŸ™
    The reader/writer I’m using is like this one from Sparkfun: http://www.sparkfun.com/commerce/product_info.php?products_id=8634
    Though I got it for almost nothing, as I have good contacts in China. I sold one on eBay some time ago for about $100, but if I buy a stock, I can get them to you for about $50!

    But unfortunately theese come from China and not EU!

    Best Regards
    Thomas Jespersen

  3. george
    September 9th, 2010 at 01:04 | #3

    hello my fried manuel i want to buy this item in low cost and must be the same of your project to work on your code….. please link me one site to buy this magnetic card reader…..

  4. george
    September 9th, 2010 at 01:12 | #4
  5. george
    September 9th, 2010 at 01:13 | #5

    edit * sorry my fried homas Jespersen

  6. September 9th, 2010 at 10:55 | #6

    @george
    Unfortunately you can’t buy the reader I’m using anymore – but the reader you linked to will work with some minor changes in the code πŸ™‚

    Thomas

  7. May 26th, 2011 at 09:09 | #7

    Hi Manuel.
    Could you send to me about, how magnetic card and magnetic card strip work and join with computer?

  1. No trackbacks yet.