This post describes an RFID (Radio-frequency identification) security system intended for domestic applications. It consists of:
- An RFID card reader. In this case I am using the ID-12 reader, which is simple to interface to as you can use RS232 serial communications at 9600 baud.
This can be obtained from (amongst other places) Sparkfun Electronics for around $US 30.
http://www.sparkfun.com/products/8419
- A piezo buzzer for making an audible beep to confirm whether or not your card was accepted.
- An electric door strike mechanism. This particular model requires a 12V DC current to operate it. The strike can be configured as "fail safe" (unlocked) or "fail secure" (locked). I configured it to "fail secure" so that if the power is lost the door is locked. Thus the program has to send a current down to unlock the door.
- An Arduino Uno programmed to detect cards being presented and decide whether or not to unlock the door.
- A few components including an N-channel logic-level MOSFET transistor. This switches the low-current and low-voltage output from the Atmega328 chip to control the higher voltage and higher current from the Vin pin so it can operate the strike.
- Connecting wires.
We require 6 wires between the processor and the door mechanism:
- +5V power (for the ID-12)
- Ground return
- Data from the ID-12 (the card number)
- Electric strike pin 1
- Electric strike pin 2
- Piezo buzzer
The test setup looks like this:
Close-up of the (prototyping) board the extra components were soldered onto:
The RFID cards come in various configurations, like:
These are passive devices, so they don't require a battery. Each one is preconfigured with a 12-character hex code. This code is transmitted by the ID-12 device when a card is detected.
The circuit is as follows:
Tip:
The electric strike is powered directly from the 12V supply (marked as Vin on the schematic).
I took power from the Vin pin on the Arduino, however strictly speaking that is really more like 11V because it is on the other side of a reverse-polarity protection diode, which would therefore drop around 0.7V.
You may find it better to have an independent 12V supply for the strike (or a 24V one if you use a 24V strike) and then power the Arduino from a lower-voltage supply, like a 7V one, which saves the onboard voltage regulator from getting as hot as it does when running from 12V.
The Arduino code to make it all works is as follows:
/*
RFID security system.
Author: Nick Gammon
Date: 5th August 2011
See: http://www.gammon.com.au/forum/?id=11283
Released into the public domain.
*/
#include <Tone.h>
#define DOORLOCK 7
#define SPEAKER 8
#define UNLOCK_TIME 2000 // milliseconds
// note, retype rather than copy and paste or you get a funny extra character
const char * ids [] =
{
"2E3612010225", // 1 - Tom
"8E40736E6073", // 2 - Dick
"A609CA0E4311", // 3 - Harry
"A3EC57520837", // 4 - visitor
NULL // end of table marker
};
Tone tone1;
void setup()
{
Serial.begin(9600);
tone1.begin(SPEAKER);
pinMode (DOORLOCK, OUTPUT);
digitalWrite (DOORLOCK, LOW); // lock door initially
}
#define MAX_ID 20
char cur_id [MAX_ID] = "";
int len = 0;
void loop()
{
char inByte;
const char ** p = NULL;
if (Serial.available() > 0) {
// get incoming byte:
inByte = Serial.read();
switch (inByte)
{
case 2: // start of text
len = 0;
break;
case 3: // end of text
cur_id [len] = 0;
Serial.println (cur_id);
for (p = ids; *p; p++)
{
if (strcmp (cur_id, *p) == 0)
{
Serial.println ("Accepted.");
digitalWrite (DOORLOCK, HIGH); // unlock door
tone1.play(NOTE_C5, 100);
delay (300);
tone1.play(NOTE_C5, 100);
delay (UNLOCK_TIME);
digitalWrite (DOORLOCK, LOW); // lock door again
break; // stop testing IDs
}
} // end of for
// no match?
if (*p == NULL)
{
Serial.println ("REJECTED.");
tone1.play(NOTE_E2, 300);
delay (1000);
}
Serial.flush ();
len = 0;
break;
case 10: // newline
case 13: // carriage return
break;
default:
if (len >= (MAX_ID - 1))
break;
cur_id [len++] = inByte;
break;
} // end of switch
} // end of incoming data
} // end of loop
Near the start of the sketch are the valid card IDs. If one of those is presented, the door unlocks for UNLOCK_TIME milliseconds (ie. 2 seconds as currently written). Then it locks again.
To find your card IDs, just run the sketch, open a serial monitor, and wave each card at the reader. You should see something like:
So, just add that number to the table of valid IDs. Repeat for other cards.
If a card is lost, just remove it from the table to deactivate it, and then add in the number for the replacement card.
In the current system you have to recompile and re-upload the sketch whenever you need to add or remove cards. However this only takes a few seconds to do.
This system is simple, by design. Improvements you could make are:
- Add a real-time clock chip, so you can tell when the cards are presented.
- Log the opening attempts (successful or not) to EEPROM, or a printer
- Have a "keep unlocked" card (eg. to keep the door open all day) and another card to "relock".
- You might make it "fail safe" (in case of fire) so in that case you configure the strike to fail in the open position, and reverse the sense of the lock/unlock actions (the digitalWrite).
- If you added a clock chip, you could configure some cards to only work at certain times. For example, you might have a card for the cleaners that only opens the door between 9 am and 5 pm on Fridays.
- Add an LCD display
- Add some sort of system for adding new cards by presenting some sort of "master" card first, and then the card to be added.
|