|A while ago I described an RFID access-control system: http://www.gammon.com.au/forum/?id=11283
This post expands on the concepts there, adding in much easier management of access cards.
What is RFID?
Radio-frequency identification (RFID) uses radio frequencies to activate and communicate with RFID cards/tags. Here is a photo of a typical RFID card, with the light shining through it:
You can see it is mostly empty space, with a loop aerial around the edge and a small chip in one corner. When it comes within range of a suitable low-power transmitter (the RFID reader) the aerial picks up enough energy to be rectified, and then used to power the chip. The chip responds by drawing extra power from the aerial (loading it) to "send" a unique train of pulses - the identification number.
Types of cards
Various frequencies are in use around the world (see: Wikipedia - RFID). The cards I will be describing here use the 125 kHz frequency. Some cards are read-only, whereas others can be written to. Some examples of writeable cards are commuter cards (MiFare or Myki in Australia).
Other examples are the tags used for toll-ways, typically they will have a supplementary battery to boost their range, as they may need to be read, at some distance, as you pass a reading station at 100 km/hour.
Cards come in different shapes. Examples are:
- Rectangular white cards. Some of them are quite thin (0.7 mm) and could be stuck inside an invitation:
- Plastic buttons (suitable for use on key-rings) - these come in assorted colours:
- Waterproof wrist bands:
- Cute colourful silicon wrist bands:
- Adhesive tags (could be stuck inside an invitation, for example):
- Small buttons - could be sewn into clothes:
- Small tags designed for insertion inside a pet (probably not applicable in this situation, but could be useful at a cattery):
The system described in this post is intended to be low-cost. Cheap enough to use for event management for private events, or access control for your house. Estimated costs are:
- RFID reader: $US 7 from eBay. Cheap reader based on the ATtiny85 processor.
See this post for more details about the HZ-1050 reader: http://www.gammon.com.au/forum/?id=12849.
- RFID cards: Around 30 cents each from eBay.
- Arduino or similar processor to read the data from the RFID reader and make decisions: $US 30 for an Arduino Uno, somewhat cheaper (like $US 5) if you buy a clone or make your own up from parts.
- Other parts like LEDs, small speaker for a playing tones, a couple of dollars.
Speaker with current-limiting resistor.
Fly-back protection diode on back of speaker.
- Optional extras like an SD card interface ($15), clock board ($9), electric door strike ($22).
SD card interface.
You could use a system like this for:
- Access control for your house or small business. Instead of giving yourself, partner, children, friends or employees keys to the house or shop, give them an RFID card. If it is lost or stolen you can delete that card from the system and issue a new one, saving the expense of getting all the locks changed. Plus you can optionally log who enters the premises when, in case of a dispute.
- Event management for things like a 21st birthday party. Say you invite 100 people, and have a couple of friends manning the door to the party. They probably won't recognize all the guests, so you need some way of identifying guests from gate-crashers. Since the cards are so cheap, it is no big deal if some people don't show up. You could decorate them with adhesive stickers with colour printing to make them look nice.
- Event management for things like clubs or sports games. When people buy a ticket (or membership) they can be issued with a card which gives them access for a single event, or recurring events.
- A checkpoint on an outdoor activity, where you need to know participants visit certain places (for example, orienteering).
The reader outputs the code for a card when it is held close to the reader, using serial transmission. The Arduino can read that and compare it to a list of known cards, and then beep, flash an LED, or unlock a door, to allow access. For manned events, like a party, the person at the door could wave the card over the reader, and grant or deny entry based on whether the red or green LED lights up, or by the sound of the tone that is played.
The "known good" cards are stored in EEPROM of the processor. As described below special "administrator" cards are used to add or remove cards from the system. Since the EEPROM survives power-down, the reading station should always be able to work, immediately after being powered on.
As an option, you can log accesses to a disk file, so you could later see who entered the building or event, and when they did it (if you also have the optional clock board), and indeed see if they came to the event at all.
To keep costs down (and avoid needing to have a screen or keypad) special cards are used to administer the system. These are special in the sense that their card numbers are hard-coded into the program.
Current administration cards are:
- Add new user
- Delete user
- Pass-out user
- Enter administration mode (to protect the next two actions)
- Erase all users
- Start an event (mark all guests as outside)
Example administrator cards, suitably labelled.
A possible problem at a party would be that a guest would gain access, and then arrange for their card to be used by a friend, for example by throwing their card to them through an open window, or arranging for multiple cards to be taken out and handed over.
To stop this, the system will (optionally) record a user as "inside" or "outside". If they are outside they are allowed in. Once they gain access their "user record" is marked as "inside" (in the EEPROM) and the device beeps in a different way if that card is used again. This stops multiple uses of the same card.
However, to allow a guest to temporarily leave (eg. to fetch something from the car) the person manning the door can wave the "pass-out" administrative card over the reader, followed by the guest's card. This then grants a pass-out, and the guest is marked as being "outside" again.
One problem I confronted when designing this was, how to manage a lost or stolen card? Although there is a "delete user" administrative card, you need to have the card to be deleted present for it to know which card to delete. However if the problem card has been lost, it is no longer present to be given to the reader.
Without the ability to delete users, apart from the security problem if this is your house, an event like a football game might be exploited by users contacting you and claiming to have lost their card. Then when you issue a second one, there are now two cards that will grant access to the event, for the price of one. So clearly we need a way of deleting cards after they are issued.
The simplest solution (bearing in mind how cheap the cards are) is to issue two cards per user. One is sent or given to the user, the second one is retained with their name written on it (or it is put in an envelope with the user's name). Then if you need to delete a user you use the secondary (or "backup") card in conjunction with the "delete user" administrative card.
The administrator of the system will possess an "add user" card. To add a new user you wave that card over the reader which then beeps in a way which indicates it is waiting for two cards (the primary card and the backup card). You then present the primary card and the beep changes slightly. You then present the backup card, and the process is complete. You file away the backup card as described above, and mail or give the primary card to the user.
Deleting all cards
Prior to an event you could use the "delete all cards" administrative card to reset the "known cards" to be empty, and then start adding new ones. Because it could be disastrous if you absent-mindedly used this card in error, you first have to present the "administrator mode" card first.
For events which require pass-outs (like a party or sporting event) the "start event" card is used to mark every user as outside the venue. Similarly to the "delete all cards" card, you first have to present the "administrator mode" card first.
The code supports assorted "status" LEDs (which are optional to use). One of six LEDs will be lit all the time to indicate the current "state" of the code:
- Event active (the normal state) - waiting for a user card to be presented
- Administrative mode - will now accept "Delete all cards" or "Start event" card
- Add card - waiting for a new card to be presented
- Add backup card - waiting for the new backup card to be presented
- Pass out - waiting for a card to be presented for pass-out status
- Delete card - waiting for a card to be presented for deletion
All of these states (except "normal" state) are activated by presenting the appropriate adminstrative card. They can all also be cancelled by presenting the same administrative card a second time.
These LEDs, if used, could be presented on the side of a box containing the device, with appropriate labels printed next to each one.
The actual pins used for each status LED are defined in the code. The initial pin numbers are:
const int LED_pins  =
2, // STATE_EVENT_ACTIVE,
3, // STATE_ADMIN,
4, // STATE_ADD_CARD,
5, // STATE_ADD_BACKUP_CARD,
6, // STATE_PASS_OUT,
7, // STATE_DELETE_CARD,
A0, // LED_ACTION_ACCEPTED
A1, // LED_ALREADY_THERE
A2, // LED_ERROR
If you choose not to use some or all of them, set that pin number to NOT_USED in that array.
In addition to the "state" LEDs are three "action" LEDs which blink briefly after certain actions. You might wire them up with colour coding like this:
- LED_ACTION_ACCEPTED - green
- LED_ALREADY_THERE - yellow
- LED_ERROR - red
Normally you expect to see the "action accepted" LED blink after presenting a card. The "already there" LED would indicate a warning, such as trying to add a card which is already added. The "error" LED indicates an error situation, such as trying to delete a card which is not on file.
You must, of course, have current-limiting resistors in series with each LED (eg. 330 ohms). Otherwise your output pins will be damaged.
If you want to automatically unlock a door, you can install an electric strike (pictured above) in place of the strike plate normally on a door jamb, and have the Arduino unlock it. Because of the power required to open the lock you will need a MOSFET and separate power supply. These strikes often require 12 or 24 volts to unlock, and quite a lot of current (eg. 1/2 an amp or 500 mA). This circuit assumes that the strike is normally closed (locked) and it unlocks when power is applied.
R1 limits current to the Gate pin from the Arduino output. R2 ensures that the lock is closed if the Arduino is unpowered. Across the strike is a fly-back diode to protect the MOSFET. The power to the strike would be 12 or 24 volts depending on what sort you obtained.
More details about circuits for driving devices like strikes, motors, etc: http://www.gammon.com.au/motors
For a speaker I used a 100 ohm impedance speaker from Pololu (https://www.pololu.com/product/1261) - cost: $2. To limit the current from the output pin I added a 100 ohm resistor in series with the speaker. I also added a 1N4148 fly-back diode to protect the output pin, since a speaker is an inductive device (see photos above).
SD card for logging
If you want to log accesses, perhaps to monitor who enters and leaves your premises and at what time, or to make a note of who arrived at your party or sports event, you can add an SD card breakout board (pictured above).
This can be connected to the SPI hardware pins like this:
This particular board has level-shifting built into it, as SD cards normally operate at 3.3V.
I used the SdFat library which you can get from here:
The SdFat library seems to be undergoing changes/improvements as at April 2015. The code may not compile with the new version of the SdFat library.
An archived version of the SdFat library (which works with this sketch) is available from:
Unzip that file, and from within the folders inside it, copy the SdFat folder into your "libraries" folder (which is under your Arduino sketchbook folder - not inside the Arduino application folder). Then restart the Arduino IDE.
In order for the disk logging to know when things happen, a clock board is handy. This can connect to the I2C pins of the Arduino. It has a battery backup so it can remember the time, even when powered down.
The clock library came from https://github.com/adafruit/RTClib
The code stores the "known" cards in EEPROM (electically erasable programmable read-only memory). It uses 2 bytes to store the count of known cards, and 9 bytes per user as follows:
- Primary card number (4 bytes)
- Backup card number (4 bytes)
- Status: Inside / Outside / Deleted
The "deleted" status is used when you delete a card. Instead of shuffling remaining cards around, that slot is marked as "empty" so when you add a new card it can take an existing empty slot.
Thus, the number of users we can store in the 1024 bytes of EEPROM on an Atmega328 is:
(1024 - 2) / 9 = 113 users
This should be enough for domestic use, a small business, or a modest sized party. If you want to store more cards you could add on a separate EEPROM chip, for example as described here: http://www.gammon.com.au/i2c (see reply #2).
A 24LC256 chip stores 32 k bytes, and could share the I2C pins with the clock. With 32 kB of EEPROM you could store:
(32768 - 2) / 9 = 3640 users
If you need more than that, you should probably be looking at a more sophisticated system. :)
The code for this project is here: https://github.com/nickgammon/Party_RFID_system/
You can clone a copy using Git or use the "Download ZIP" button to get a copy of the code.
The code is organized into a number of .ino files, separating out the various parts of the system: LEDs, sounds, clock, disk, etc.
If this is the first time you have downloaded the code you should copy the file Configuration.h.orig as Configuration.h. This is the configuration for your particular setup (eg. pin numbers, baud rate, whether you are using a door lock, and so on). By having these in a separate file you can easily change them, and if you ever get an updated copy of the software, the new file Configuration.h.orig will not overwrite your configuration changes.
I have been using two different types of RFID readers: the ID12, and the HZ-1050. The difference is, that although they both use serial comms, the HZ-1050 sends 4 bytes of "binary" data, whereas the ID12 sends the card number in ASCII. Change this define in Configuration.h depending on what sort of reader you have:
// whether to use ID12 style or HZ-1050 style
#define USE_ID12 false
During testing I used SoftwareSerial instead of the hardware serial for the RFID reader. This saved having to disconnect and reconnect the reader each time I uploaded a new version of the software. If you want to use SoftwareSerial make this define true:
// whether to use hardware or software serial
#define USE_SOFTWARE_SERIAL true
I used the ReceiveOnlySoftwareSerial library (which saves space by not using the "sending" code, a copy of which can be obtained from:
This was written by whiteglint143 on the Arduino forum.
For reading and writing structures to EEPROM I used the EEPROMAnything library, a copy of which can be obtained from:
For debugging memory usage I used the memdebug library from Andy Brown's web site:
For debugging, messages are printed to serial output. This won't be visible if you are operating stand-alone, but can be useful for finding the card numbers of your administrative cards when you first set up the system. You could initially plug the Arduino into your computer (as usual), turn on the Serial Monitor, present your administrative cards, and see what their numbers are. Then you could modify the Configuration.h file to put the appropriate numbers into it.
For example, present your desired card, and watch the serial monitor:
Got card E5075B
Now you know the number of that card. You could then make that the "add card" administration card, for example.
Workflow for a party
Say you are organizing an 18th birthday party. First delete all existing cards (present the "administration mode" card and then "erase all users" card to the reader).
For each guest, present the "add card" card to the reader. It should beep once, and then do two quick beeps every 1.5 seconds (meaning "two cards needed"). Present the primary guest card. It will beep once and then do one quick beep every 1.5 seconds (meaning "one card needed"). Present the backup card to the reader. Note the guest's name on the backup card, and mail out the primary card to the guest. Perhaps stick onto the primary card some colourful invitation message, using labels in a colour printer.
Before mailing the card, you could test it by presenting it to the reader again. The "access allowed" tone should sound. That confirms it was registered OK. If you present it again you should get the "user is already inside" tone. You can cancel that by using the pass-out card.
If someone loses their card, present the "delete user" card to the reader, followed by the backup card you retained for them. This deletes both cards from the system. Now you can issue a new primary card (you could re-use the backup card in this case).
On the day of the party, mark everyone as "outside" by presenting the "administration mode" card and then "start event" card to the reader. Now you are ready to go.
At the party, guests should provide their card, and you can check it is valid, and that they have not already used it. For a pass-out, present the pass-out card to the reader, followed by the guest's card.
How secure it is?
The RFID system's security is based on the difficulty of making a clone of a card. Each card is manufactured with a unique ID so theoretically it should be impossible to make a copy. Certainly it would be harder than photocopying a party invitation. However searching on eBay reveals that you can purchase writable cards, and also devices which make copies of existing cards. So it is possible that someone might get such a device, obtain an existing card, and copy it.
So how big an issue is this? For a party, someone would have to obtain a copy of an existing card, in order to copy it. Even then, if you are using the pass-out system only the first copy would be allowed into the event, so it would not be in the interests of people to lend out their cards for copying.
For access control to your house, where you are not using pass-outs, security is a bigger concern, but really you are no worse off than if you used ordinary house keys, and someone got their hands on them and made a copy. So basically, protect your access cards to your house or business in the same way you protect your brass keys, and it should be just as secure.
The system described above is basically built around a single device, and thus is suitable for a single point of entry, to a house or party. If you wanted multiple access points you might add in radio transmitters/receivers, or an Ethernet network connection. Another enhancement would be to store card numbers on a disk file (on the SD card) rather than in EEPROM. This would make it easier to make multiple copies of the list of cards, for insertion into devices at multiple access points.
My LED breakout board has 300 ohm SMD resistors mounted underneath the board between the incoming pins and the LEDs.
Access control system mounted in box (artist's impression):
- Nick Gammon