Projects

Keyless Entry

RFID Access Control with Attendance Recording

Johann Wyss

Issue 36, July 2020

This article includes additional downloadable resources.
Please log in to access.

Log in

Grant access to multiple users to a room or system using RFID technology, and record the date and time on when they enter.

BUILD TIME: 3 HOURS (+ 3D PRINTING TIME)
DIFFICULTY RATING: Intermediate

We see RFID (Radio Frequency Identification) technology used in many parts of our life these days, from ticketing systems on public transport to gaining entry to our workplaces. Gymnasiums, for example, use the technology to grant access to members at any time of day or night, and record the member’s attendance without any staff at the gym at the time. RFID tags are in our passports, the DVDs we rent from the local kiosk, in the books we borrow from the library, and much more. Consider also the tag stuck to your car’s windscreen that beeps when you pass under a toll point.

Using RFID technology for gaining access to a room or building means there’s no need for physical keys that can be lost, stolen and copied, which could mean replacing your locks in some circumstances. It also means you know specifically who is entering based on their unique RFID number, and with the right systems in place, you can record the date and time of them entering.

This brings us to our project, which makers can build using commonly available RFID tags and readers.

THE BROAD OVERVIEW

For this project, we are building an RFID ingress control system that will give you the ability to control an electronic door lock and record the time and details of the person who used it.

The project uses an RFID reader module, various RFID tags, key-fobs and wafer cards, an RTC (Real Time Clock) module for timing purposes, and an SD Card Module to store the data. All managed by an Arduino Uno microcontroller, with information displayed on an LCD screen.

In our application, we will trigger an electronic door lock, however, you could just use the system for attendance purposes or to trigger other devices.

HOW IT WORKS

RFID TECHNOLOGY

RFID technology is an exciting field that was developed in the 1980s as a replacement for the humble barcode. The benefits of the technology are that you don’t need a line-of-sight to read the information as a barcode does. This means your products zipping down a production line don’t all need to be sorted in a way that the barcode is in a position ready to be scanned. This technology became a revolution in the manufacturing industry and is now widely being used across many industries.

Other RFID applications include:

  • Small RFID chip implanted in pets to help identify the owner if it escapes.
  • Passport and driver's license to provide rapid data verification as well as making it very difficult to make fraudulent copies.
  • Retail stores use the technology as a means of detecting and preventing theft of their merchandise.
  • Video game add-ons, such as Skylanders™ to identify which character you’re playing with.

Whilst we use RFID in our everyday lives, for the most part, most of us know very little about how it works.

There are two types of RFID tags:

  • Passive, powered via the RFID reader.
  • Active, with the RFID chip powered by a small battery.

Both technologies are essentially the same, however, the active with its battery gives the chip significantly more range. Passive RFID cards, like the ones we are using for this project, have a maximum transit / receive distance of about 10 metres, whereas the RFID chip in your car’s toll reader has a maximum read distance of up to 100 metres.

With that said, the maximum transmit distance relies on various factors including the transmit power. For this project, we found that the combination of this reader and the supplied RFID cards the maximum transmit / receive distance was about 50mm.

To get into how the RFID system works, we need to take a look at the tags themselves. To do this, we decided to open up one of the supplied RFID tags.

The electronics inside are little more than a coil of wire, and a small IC hidden under a blob of epoxy.

When a tag is brought close to the reader, the reader's coil is inductively coupled to the coil on the RFID tag. This coupling allows a small amount of energy to be wirelessly transferred from the powered reader into the coil of the RFID chip to power the small IC. Naturally, for inductive coupling to work, the RFID reader must transmit a constantly changing / pulsating DC i.e. an AC signal called the carrier wave. For the RFID module and cards, we are using this carrier wave that has a frequency of 13.56MHz, that’s 13.5 million cycles per second!

As you can see in the image shown here, there is a coil around the perimeter of the lower section of the RFID reader’s circuit board. This coil allows a small amount of energy to transfer from the reader into the RFID card to power it.

Interestingly, the RFID chip on the card does not actually transmit anything in the traditional sense. Instead, the data is transferred via a process called load modulation or task manipulation. The IC on the RFID card turns a load attached to the coil on and off in sequence to the data stored on the card.

This switching of the load causes the coil on the RFID card to consume more current. This causes the voltage on the RFID reader’s coil to sag when the load on the card is active. By reading the voltage at the antenna / coil of the RFID reader, we can detect the highs and lows, and therefore, create a data stream of ones and zeroes.

This data stream is then decrypted if needed, and can be processed as normal. The cards we are using have a maximum data storage of 1Kb, which means quite a significant amount of data can be stored on the card itself. However, for this project, we are simply going to use the unique identifier (UID) for each card to differentiate it from other cards.

Note: It is possible to change the UID on a card, so using the RFID UID is not a secure method. Therefore, you should avoid using such technology as the only means of protecting anything valuable.

We will write a program that reads the RFID UID of a card. If the UID matches the UIDs stored in the program, it will display a welcome message on an LCD and record the action onto an SD card. After this, it pulls a digital pin high, which can be used as a signal to control a device such as a solenoid or electronic door strike, such as this one from Jaycar.

LA5077 Door Strike from Jaycar.

Keep in mind that the signal from our project isn’t adequate to trigger a solenoid or door strike directly, so we need to use a relay or other means to control such large loads. There are many ways to do this, ranging from transistors to relays, with arguably the most convenient being a relay.

When using a relay module, the signal wire is galvanically isolated from the connecting circuitry by the use of an integrated optocoupler. A transistor is also used to allow sufficient current through a relay coil to actuate it. When pulled high, the signal wire allows current to flow into the optocoupler input, which allows current to flow from VCC and through the output of the optocoupler. This current then flows into a transistor which allows current to flow from VCC through the coil of the relay and through the transistor to ground. The current flowing through the relay coil causes it to magnetise the relay wiper, pulling the wiper of the relay from the Normally Closed (NC) position to the Normally Open (NO) position. This allows current to flow from the Common (COM) pin into the normally open (NO) pin.

How you connect the hardware to this will depend on your specific system, however, most door locks will require a high pulse to activate them as they want the door to remain locked in the event of a power outage. As such, they should be connected to the normally open connection of the relay.

The Prototype:

Electronics

Parts Required:JaycarAltronicsCore Electronics
1 x Arduino Uno or CompatibleXC4410Z6240CE05629
1 x RFID Module with RFID Card or TagXC4506Z6356CE07140
1 x SD Card ModuleXC4386Z6353CE05113
1 x Realtime Clock ModuleXC4450-CE07141
1 x 1602 LCD ScreenQP5521Z7002ADRF0063
1 x I2C Backpack for LCDsXC3706-018-LCD1602-I2c
1 x Relay ModuleXC4419Z6325CE05137
1 x SD Card (Formatted to FAT16 or FAT32)XC4989D0328CE04628

Parts Required:

You’ll also need a breadboard and prototyping hardware.

Use the Fritzing diagram and connection guides shown here to wire up your prototype circuit.

Note: You will notice that the modules share the same pins on the Arduino Uno. For the prototype, you can overcome this by using a breadboard.

Realtime Clock

The Realtime Clock uses the I2C protocol, and as such, shares the same pins as the LCD backpack.

SD CARD MODULE

The SD card module uses the SPI communication protocol.

RC522 RFID MODULE

Like the SD card module, the RFID module also uses the SPI communication protocol.

Note: The RFID module’s VCC requires 3.3V. Powering it to 5V will damage the module. The data pins, however, can support 5V.

LCD Screen

The LCD utilises the I2C backpack, which must first be soldered onto the back of the 1602 LCD (see notes below). This backpack reduces the number of pins for the LCD from 16 down to 4.

LCD BACKPACK

The I2C LCD backpack needs to be soldered to the 1602 LCD. For this project, we opted to solder the backpack directly to the LCD using the supplied male header. Ideally, you would join these together by using a female header on the LCD so that the two modules can be separated. In our application, however, this would mean the faceplate would have to be 9mm thicker, which we figured would make the project way too bulky.

It is important to note, if you do solder the backpack directly to the module, the backpack may foul against the LCD’s metal frame and potentially cause a short circuit.

To overcome this, we used a piece of cardboard to act as a spacer between the Backpack and the LCD module, ensuring that when we solder the backpack into position that there is sufficient clearance. This cardboard can be removed after soldering if desired.

Before we move on, it’s important to double-check the address of your I2C LCD backpack. To do this, we use the I2C scanner program that you can find on the Arduino playground here: https://playground.arduino.cc/Main/I2cScanner/

With the I2C LCD connected to the Arduino, run this sketch and it will display the address of your LCD on the serial monitor. You will need to record this address as it will need to be added to this line of the main program.

LiquidCrystal_I2C lcd = LiquidCrystal_I2C(address here, 16, 2); 

You simply replace the text ‘address here’ with the hex value provided by the I2C scanner sketch. In most cases, the I2C backpack will have the address 0x26, and as such, we have left the main code as this.

LiquidCrystal_I2C lcd = LiquidCrystal_I2C(0x26, 16, 2); 

None the less, it’s easier to identify the address now than troubleshooting later with the circuit constructed. It will save you lots of time if the address is different on your module.

THE CODE

INSTALLING THE LIBRARIES

This sketch uses several libraries generously provided by various members of the Arduino community for us to use. In order for the code to successfully compile and upload to the Arduino Uno, you will need to install them. To do so, simply search for and install them directly from the Arduino Integrated Development Environment (IDE).

Select Tools > Manage Libraries or press Ctrl+Shift+I.

Use the filter in the search section to find the necessary libraries, and select Install for each one.

The SPI.h library is now part of the standard Arduino lineup and won’t need to be manually installed. If you get an error related to this library, we recommend you upgrade to a newer version of the Arduino IDE.

THE CODE

The code is too long to include in its entirety in the magazine. It is available to download from our website, and we will simply explain the main functions here. We have attempted to make the code as portable as possible to enable makers to easily modify certain parameters to suit their application.

Our code uses five different RFID cards, along with five arbitrary names. Naturally, these values will need to be changed to suit your application. The first value you will need to change is the value stored in the constant called CARDS.

#define CARDS 5

This defines how many cards you will be using, change the 5 to the number you will have installed.

The string named 'building' allows you to name the building that this RFID device is controlling ingress too.

String building = ("DIYODE"); 

This string can be a maximum of 16 characters so that it fits on the 16-character display. To centre the name on the screen you can change the value stored in:

#define pos 5 

To do this, you simply do a little math: (16 − characters in building name) / 2.

If the building name has 6 characters like DIYODE does its ((16 – 6)/2) which is 5.

This should be a whole number so if you get a fraction you will need to simply round up or down. However, the code will do this for you.

You can now store the unique card IDs for each of the cards you intend to use in the following two-dimensional array.

{171, 38, 239, 26},
{105, 54, 171, 213},
{194, 96, 17, 28},
{78, 67, 68, 209},
{138, 14, 113, 151}
};

Note: When storing the unique IDs, you can ignore the leading zeros of a number.

If you don’t know what the UID is for a card you can use the READNUID example from the RFID / MFRC522 library. This example will scan an RFID card and display the unique ID via the serial monitor.

This will allow you to discover and record the UID of each card you intend to use. Simply add the decimal value to the array. You will need to keep track of the RFID cards, so you may want to consider writing on or otherwise marking the card in a way so that you know its position in the array. This will make it much easier when assigning a name to that position.

With the UID identified and recorded for each of the cards you intend to use you can now assign them to a person, and thus record the names in the program by changing the names array.

String names[(CARDS)] = {
"Barry White",
"Jack Black",
"Peter Gray",
"Sally Green",
"Max Power"
}; 

In order to fit the name on the LCD screen, the names must be 16 characters or less. The position of the name directly correlates with the position of the UID. Therefore, the first element of the names array is matched with the first 4 elements of the UID array.

These are the only values that you are likely to need to change to customise the project for your specific needs.

All in all, the code itself is fairly straightforward and written completely in functions. The first function readCard() was derived from the READNUID example code provided with the MFRC522 library. We modified this example to make it more useful for our desired project.

This function reads the UID and stores each 3-digit number into an array of 4 elements while omitting the leading zeroes.

From there, we enter the compare function to compare the elements in each array, looking for a match. If a match is found, we enter the displayUID() function and display a welcome message on the LCD. We also initiate a timer used to later clear the display back to the default.

After the displayUID function, we enter the write data function which writes the date, time, unique card number and personnel name to the SD card.

The code then enters the unlock function which pulls a digital pin high for the duration of a timer. This duration is by default set to 2000mS and can be adjusted if needed by changing the variable delayTime.

This means the door will remain unlocked and welcome message will be displayed for 2 seconds after a known card is detected. After this time, the digital pin is pulled low and the LCD returns to the default setting.

The SD card records the date and time of the unlock as well as the unique ID and name of the person who owns the card.

Likewise, the data is also sent serially for situations where the device is attached to a computer for real-time monitoring. The output will look similar to this screenshot.

The Main Build:

To turn our prototype into something more permanent, we designed two 3D printed enclosures so we could mount the LCD and RFID reader in one location and the SD card, Realtime clock and Arduino in another area. This way, the LCD and reader can be on one side of a wall and the sensitive electronics can be on the other side, protected in an enclosure.

ADDITIONAL Parts Required:JaycarAltronicsCore Electronics
1 × Pack of 100mm Cable TiesHP1196H4031AFIT0343
1 × Female Pin Header StripHM3230P5390PRT-00115
1 × Male Pin Header StripHM3211P5430POLOLU-965
Heatshrink TubingWH5520W0882ADA1649

ADDITIONAL Parts Required:

3D printed Enclosure

We have designed custom 3D printed enclosures to suit the modules. The print files can be downloaded from our website.

Note: If you don’t have access to a 3D printer, you could use Jiffy boxes or similar enclosures from your favourite electronics or hardware store, and use the appropriate mounting hardware. An electrical junction box could be fastened (screwed) to the back of a rectangle of brushed aluminium or stainless steel sheet for an extra "security" message. Add a dummy lens for an extra strong message.

INPUT PANEL

The input panel houses the LCD display and the RFID module, and needs to be mounted to the external wall of your secure room or building.

Note: This 3D printed enclosure is in no way weather resistant so it is only suitable for internal mounting.

This input panel allows the user to touch their card or keyfob to the faceplate and receive a welcome message if their login is successful.

The faceplate was printed on our Flashforge Creator Pro at a 200-micron layer height using black 3D Fillies brand PLA. It’s designed to print without supports and laying flat on the build surface as shown. It takes about 3.5-hours to print.

The faceplate has four mounting holes that will allow you to screw it directly to the wall adjacent to the door entry. The cables will need to be routed through the wall so they can be connected to the control box.

CONTROL BOX

The second enclosure will house the RTC, Arduino Uno and the SD card, and is mounted on the other side of the wall so that it cannot be easily reached by unauthorised individuals. We made two holes in the case to allow the user to attach and power the device from the USB port. This will also allow for real-time serial output. There is also a slot that allows the user to insert and remove an SD card.

There is also the option to power the Arduino directly via the Vin pin if desired which will allow the user to power the device from a 6–20V supply. This is handy as 12V is a very common voltage for door locks and solenoids. This means you can power the device from one single power supply, and even add a 12V UPS in case the power goes out.

Like the faceplate, the control box and lid were both printed on our Flashforge Creator Pro at a 200-micron layer height using Flashforge branded black PLA. The control box took 4-hours to print, and is printed without supports in the orientation shown.

Note: Depending on your slicer and printer’s capabilities, you may find you need support material to bridge the overhangs for the SD card slot and the Arduino’s USB port. Take this into consideration when slicing the files.

The lid took about 1.5 hours on the Flashforge and press fits into the control box. You may find that you get little blobs of stitching on the rim of the lid where it fits into the control box. This stitching is a seam where the 3D printer transitions from one layer to the next. If your slicer does this in the same position on every layer you get a very noticeable seam running vertically along the print. This seam may cause the lid to not fit correctly. If this is an issue for you, you can use a hobby knife to carefully remove the little extra plastic.

To help reduce the amount of work required to remove this seam, make sure your slicer is not set to starting and stopping each layer at a random spot.

Note: Some small issues were discovered during the assembly and the design has been modified to rectify these issues, thus you may notice some slight differences between the images here and the files you will be printing.

Project Assembly

To assemble the project, we need to create a simple wiring harness that will connect each component to the Arduino Uno. This was quite possibly the most time-consuming part of the project. You need to make the cables as short as practical to reduce wastage and filling the control box with coils of wire. The best way we found to do this was to first attach the modules to the enclosure in their positions.

Screw the Arduino down with just one screw as you will need to remove the Uno later to run the cables through the hole in the back of the enclosure. This hole is designed to line up with a hole in the wall it’s mounted to, which will allow the cables to link both units.

Starting with the control box, secure the RTC module, SD card module, and Arduino Uno using #4 screws.

We then cut a male pin header strip that we had available.

One 2-pin strip to attach SCL and SDA of the LCD and RTC to analog pins A5 and A4 of the Arduino Uno.

One 4-pin strip to go into the two ground pins, 5V pin, and 3.3V pin of the Arduino Uno. This will provide the power and ground signals for the modules.

One 6-pin strip for digital pins 8 – 13 of the Arduino Uno. These pins are the SPI signal wires for the RFID module and the SD card module.

Likewise, we created a similar plug for each of the modules using female headers.

A 4-pin female header strip was made for the I2C LCD.

An 8-pin female header strip was made for the SPI SD card module (only 6 wires were connected).

A 4-pin female header strip was made for the I2C RTC module.

An 8-pin female header strip was made for the SPI RFID module (Only 7 pins were used).

To join the wires, we first stripped about 10mm of the insulation away, giving us plenty of room to work. We then placed two wires parallel to each other and twisted the exposed wires together to form a strong mechanical bond. We then slid a 20mm length of heatshrink over these two wires (to insulate the join after soldering). We then twisted the third wire around these two and soldered all three wires together.

Once soldered you can insulate the join by sliding the heatshrink over the solder connection and apply heat to shrink it. You can also use electrical tape or liquid electrical tape if you wish. This technique will produce a very strong join for three wires, and will need to be used on most connections in this project.

Take your time and you will get great results.

Once you’re done, you can simply use the male and female pin headers as a plug and socket to join all of the modules to the Arduino Uno.

Note: The wires for the RFID module and LCD need to be routed underneath the Arduino Uno and through a hole on the bottom of the controller enclosure.

When everything is placed and working correctly you should use cable/zip ties to keep the wires in check and to prevent twisting, knots or strain on connections.

Programming

If you’re new to Arduino or having issues getting started you may want to check out our "Setting up the Arduino IDE guide" from Issue 17 where we go through the fundamentals of using the Arduino from the install process to adding libraries and uploading a sketch on various different operating systems. You can find it here: https://diyodemag.com/education/fundamentals_setting_up_the_arduino_ide

Testing & Troubleshooting

Testing the prototype is fairly straightforward for this project. We have added some basic error messages to help identify potential faults. Below are the potential errors and how to rectify them.

Blank LCD

If there is no information displayed on the LCD, your first action should be to adjust the potentiometer on the back of the I2C backpack module. This potentiometer adjusts the contrast of the display and should make the display visible.

If this does not rectify the display issues, double-check the connections. Make sure the SDA, SCL and power and ground connections are correct. If the fault is still not rectified, ensure that the code has been correctly uploaded to the microcontroller.

You should also double-check that the address set in the code matches the address of the LCD. You can use the Arduino playground I2C scanner to do this, as mentioned earlier.

RTC Failure

This error message will be displayed on the LCD if there is an issue with communication between the microcontroller/Arduino and the RTC module. This would normally occur if the SCL and SDA connections are incorrectly connected, or insufficient power is being delivered to the module.

Double-check all connections and rectify any potential issues. If this error persists, consider switching the module to ensure it is functioning correctly.

No SD card

If you see ‘No SD Card’ displayed on the LCD, the most likely cause is that the SD card has not been inserted or is the wrong format. Make sure that the SD card is correctly inserted and that the formatting is in the FAT16 or FAT32 (file allocation table) format. Most SD cards come supplied from the factory in this format, however, if the SD card has been used in other devices such as a camera or media player etc., you may need to reformat it.

If that still does not rectify the fault double-check that the wiring is correct and that the modules are receiving the correct voltage.

WHERE TO FROM HERE?

As a door access and logging device there isn’t too far to push this project. Naturally, making it wireless and recording the data to an online cloud would be the most obvious improvement. However, the technology used is both pretty impressive and prevalent. Using just the objects on hand, we were able to retrieve data from a Queensland driver's license, a United Kingdom passport, public transport cards, Visa payWave cards and various student IDs. In fact, it's highly likely that this reader will work with any RFID chips designed to run on the 13.56MHz frequency. Of course, the data is always going to be encrypted, and thus it is only for an educational benefit.

Johann Wyss

Johann Wyss

DIYODE Staff Technical Writer