Friday, June 27, 2008

Arduino RFID Door lock

This project is for an RFID accessible door lock controlled by an Arduino microcontroller. Most of this kind of project is pretty straight forward and just takes some trial-and-error and a lot of reading. I'm sure a lot of people want to try something very similar for themselves, so here is what I have done.

The basic premise is that when an RFID tag is detected in the field the data is sent to the Arduino. The Arduino compares the tag to a list of valid tags. If it matches then the servo is turned and the LED changes color. Which way the servo turns is determined by which way it turned last. If its open, it closes. If its closed, it opens. Therefore, the only way to lock or unlock this door is with a valid RFID tag.

Things you'll need:
  • Arduino Decimilia (or equivalent)
  • Parallax RFID Reader
  • Standard Servo
  • Jumper Wires
  • Project Box
  • Deadbolt lock assembly you don't mind destroying
  • Standoffs
  • Cutting/drilling tool (Dremel)
Optional things:
  • LEDs (2)
  • LED Housings (2)
  • Breakaway headers (male and female)
  • Soldering iron
  • Solder
  • Basic soldering skills
  • Solder-less bread board
You will probably want to mock this up on a breadboard first to be sure everything works before you start cutting and soldering.

Once you are ready to build the final product the first thing to do is figure out how you want to mount the components. Keep in mind where wires, connectors, and LEDs are going to be. Be mindful of the height of your standoffs and how they will affect things mounted on the outside. I had installed the LED first without determining how far it would stick into the box and it almost touches the Arduino board. I ended up having to bend the connecting wires down slightly rather than drill another hole. Measure everything and drill as needed. This is alway an organic process for me and I always end up with more holes than I want or need.

I soldered all my wires to breakaway headers to make it easier to connect and disconnect components. The male pins visible below are for the servo and the female connector is for an optional external LED mounted on the door knob to see the door state on the outside. You can also see the LED mounted on the box. This one is so the door state can be determined on the inside of the door


Here is the basic wiring diagram:

If you copy and paste the code I have below make sure you connect all the wires in the same places. In my setup the RFID GND is connected to the GND on the top row, SOUT goes to 8, /ENABLE goes to 2, and VCC goes down and around to 5V on the bottom. The yellow or white wire of your servo is the control wire. It will go to pin 4. Red gets spliced on to the same wire on the reader that connects to 5V. Black is ground and is connected to GND on the bottom.

The hardest part is figuring out how the servo is going to interface with your deadbolt. I'm afraid there isn't much help I can give you on this part. I went through three or four designs before I found one that worked with my deadbolt and the parts I have. Consider this a mechanical engineering exercise. All you have to do is find some way of connecting that servo wheel to the overcentering portion of the deadbolt. Since all deadbolts are different and there is no way you'll be able to replicate what I have done (mostly because I don't know where these pieces came from) I'm not going to bother posting pictures of it.

All of that, plus this code and you should be off and ready to over complicate your entry procedures!


//BEGIN CODE

#define servoPin 4 // control pin for servo motor (White or yellow wire of servo)
#define minPulse 500 // minimum servo position (Open position)
#define maxPulse 2200 // maximum servo position (Closed position)
#define rxPin 8 // SOUT pin of RFID module
#define txPin 9
#define enable 2 // /ENABLE pin of RFID module
#define LED1 13 // LED output pin
#define LED2 12 // other LED output pin for two-way LED (yellow)
#define switchPin 7

boolean open = true; // default start up is to assume the lock is open
int val = 0;
char code[10];
int bytesread = 0;
int pulse, switchVal;

char tag1[11] = "0800335036"; // this is size 11 because it is a NULL terminating string
char tag2[11] = "0800330A99";
char tag3[11] = "0F03028B4F";



void LEDControl(int state){

switch (state){
case 1:
digitalWrite(LED1,HIGH);
digitalWrite(LED2,LOW);
break;
case 2:
digitalWrite(LED2,HIGH);
digitalWrite(LED1,LOW);
break;
case 3:
for(int y=0;y<5;y++){
digitalWrite(LED1,HIGH);
digitalWrite(LED2,LOW);
delay(250);
digitalWrite(LED2,HIGH);
digitalWrite(LED1,LOW);
delay(250);
}
}

}

boolean checkTag(char *tag){

for (int x=0;x<10;x++){
if( tag[x] != code[x]){
return false;
}
}
return true;
}

boolean findGoodTag(){
if (checkTag(tag1)){ return true;}
else if (checkTag(tag2)){ return true;}
else if (checkTag(tag3)){ return true;}

// Add more lines right here like the one above if you have more tags

else{
Serial.print("Bad tag: ");
Serial.println(code);
LEDControl(3);
return false;
}

}
void moveServo(){

if (open){
pulse = minPulse;
open = false;
LEDControl(1);
}
else if (!open){
pulse = maxPulse;
open = true;
LEDControl(2);
}

for (int x =1;x<150;x++){
delay (10); // don't know why this works, but it does
digitalWrite(servoPin, HIGH); // start the pulse
delayMicroseconds(pulse); // pulse width
digitalWrite(servoPin, LOW); // stop the pulse
}

}



void setup() {

pinMode(servoPin, OUTPUT); // Set servo pin as an output pin
pinMode(LED1,OUTPUT); // Set LED pin as output
pinMode(LED2,OUTPUT); // Set LED pin as output
Serial.begin(9600);
Serial.println("Begin");
pinMode(enable,OUTPUT); // Set digital pin 2 as OUTPUT to connect it to the RFID /ENABLE pin
digitalWrite(enable, LOW); // Activate the RFID reader
pinMode(switchPin, INPUT);
}

void loop() {
SoftwareSerial RFID = SoftwareSerial(rxPin,txPin);
RFID.begin(2400);

switchVal = digitalRead(switchPin);



if((val = RFID.read()) == 10)
{ // check for header
if(switchVal == HIGH){
Serial.println("Button");
moveServo();
}
bytesread = 0;
while(bytesread<10)
{ // read 10 digit code
val = RFID.read();
if((val == 10)||(val == 13))
{ // if header or stop bytes before the 10 digit reading
break; // stop reading
}
code[bytesread] = val; // add the digit
bytesread++; // ready to read next digit
}



if((bytesread == 10) && (findGoodTag()))
{ // if 10 digit read is complete
digitalWrite(enable, HIGH); // dectivate the RFID reader
moveServo();
delay(500);
digitalWrite(enable, LOW); // Activate the RFID reader
}
}
}

12 comments:

Unknown said...

Do you still check this site? When I try to add your code to the Arduino, I get the following error:

In function 'void loop()':
error: 'SoftwareSerial' was not declared in this scope

Shawn Augustson
http://www.ArduinoFun.com

Dylan Bowen said...

same here. any ideas?

Unknown said...

The solution is simple, Scott Zumwalt just forgot to include the header file for SoftwareSerial.
Just add the following string at the top of your arduino code and everything should work fine:

'#include SoftwareSerial.h'
>> place 'SoftwareSerial.h' between '<>'

(can't publish the code correctly because of my comment limitations)

Nice project you have there btw.

JuNeder said...

Do you have any idea how to integrate a txt file with a small database and code in arduino to read and approve as appropriate.

Thanks

Unknown said...

JuNeder - I am working on a lock that stores a list of valid card numbers as a text file on a SD card. It also has a network connection that allows you to add/remove cards remotely. Let me know if you want some code :-)

Luiz Henrique █▓ said...

What's the type of the servo which you are using ?

Sexyladyme26 said...

Finding the right door hardware for your application can be difficult.Most durable heavy duty closer designed for the most demanding, high use and abuse applications.


quality door

Sexyladyme26 said...

Nice posts are display in this blog that to using the great info is visible in this blog. I am really thank you very much for providing the different articles and the interesting info in this website.


quality door

Sexyladyme26 said...

Great review hun haven't tried this brand before but will look into it soon. How very generous of them to send u a fresh set from their updated range now that's what I call good customer service!



door hinges

Unknown said...

Is there a reason when I scan the tag once or twice, the servo will open, then close?

I am trying to modify the code for the user to scan the RFID card, then the servo opens (or reaches 180 degrees), and scans again for the servo to close (or go back to 0 degrees).

What would have to change?

Anna Schafer said...

Which way the servo turns is determined by which way it turned last. If its open, it closes. If its closed, it opens. Therefore, the only way to lock or unlock this door is with a valid RFID tag.carlocksmithinmckinneytx.com

Elizabeth J. Neal said...

The Arduino compares the tag to a list of valid tags. If it matches then the servo is turned and the LED changes color. Which way the servo turns is determined by which way it turned last. If its open, it closes. locksmith indianapolis 46226