Part 1: Alarmduino

Oliver Higgins

Issue 2, August 2017

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

Log in

Ever wondered how alarms work? How do they know that somebody is moving or how to detect a broken window? Want to set up a custom alarm system that can be tailored to your needs? How about we add IoT capabilities to provide remote access to alarm/disarm, or even open a door?


A modern alarm system can very easily amount to thousands of dollars. On top of that, back to base monitoring and fees can be a costly exercise. While DIY kits exist they are often not tailored to exactly what you need to suit your application. An alarm consists of three basic parts, the inputs, outputs, and control unit. We will be using an Arduino Mega as our control unit, and add various inputs and outputs to make a custom alarm system that can work off as little as 5V. The system can handle multiple inputs and outputs and is designed to be a starting point for any custom application you have in mind. We have broken up this project into two logical steps. The first is circuit design and prototyping. Part 2 will enable remote access and enhance functionality, as well as put it into a tidy case for real-world application.


The modern alarm is quite simple, however the logic is not always easy to follow. The alarm has a straightforward task, check to see if something has happened that should not be and if it is, do something about it, Pretty simple? It is a little more complex, but the premise is correct. An alarm system will have several different types of triggers it can use to determine if there is a change in the state. This includes reed switch, window break detectors, movement detectors and pressure sensors to name a few.

We will use the Arduino to check the various inputs and see if anything has changed. We do this by creating wired loops on which we place our detectors. In its simplest form, imagine we took a wire out of pin 20 of the Arduino, looped it all around our house and then joined it to 5V on the Arduino. (I have omitted the real circuit for the sake of explanation). We check to see if there is 5V on pin 20. All good? Yes, the Arduino goes off and checks the other loops, then comes back to the loop on pin 20? Still 5V? Yes? Let’s continue. The closed loop will continue to be fine until it is broken. When the Arduino detects that there is no longer 5V present on pin 20 the system trips the alarm and triggers the outputs. This way we can have multiple “breaks” in one loop. The magnetic reed window/door switch is like this. We wire them into a daisy chain with several linked via the normally closed (NC) option. If any of them get triggered, (i.e. opening the window moves the magnet away from the switch) the entire loop is triggered. We can have multiple loops, and these are referred to as zones.

Once the system is triggered through these zones, we need to process this information and decide what to do about it. For the sake of simplicity, this system will detect a signal or break in any zone and trigger the outputs. The outputs, in this case, are a small piezo sirens and a relay that could trigger a siren or strobe.

Block Diagram
Block Diagram of the Logic


The system starts out by importing the libraries then setting up the input and output pins used in the project. Once the setup phase is complete the system goes into an idle state [1].

Idle State

On the bottom row of the screen, you will see three options: ARM, TEST and SET. The Arduino will just sit here until we choose an option. We have two choices to arm the system: press button one, which is the “Arm” option or uses the RFID card or key fob. Either of these will trigger the arming sequence. The unit will beep three times before a long beep. On-screen you will see a countdown and then “System Armed”. This triggers the “armed” flag.

The system now continues to loop, checking each zone, one after each other. All of this occurs within the chkZones function. If any of the zones (pins) are high, then the “alarmActive” flag will be switched, and the system calls the soundAlarmOn function. This function is what triggers the outputs, such as the piezo and the relay. The alarm will sound until the disarm function is called when the RFID is swiped.

If the unit is not tripped the chkZone loop continues until it is disarmed. The main screen contains two other options. First, "Test" simply triggers a testing function that calls the outputs for five seconds so that you can test that works. You will hear the piezo and any relays etc will trip. The second option is for checking the inputs. Hold this down and you will see "Zones" and "Trip" [2].

Zones and Trip

If the zone is active (i.e. it has been tripped) it will show a “+”. If it's in a normal state, then it will be “-“. It gives you a clear indication of what's going on around the installation.

The system works with active and passive sensors, so it's rather versatile. While we have seven distinct zones (you could easily expand to more), you can have multiple sensors on each zone for virtually unlimited monitoring application. In addition to monitoring zones, we also have assignable output triggers in the event of an alarm, to drive sirens / strobes, or deploy the laser beam sharks.

Let’s take a moment to break down the technology that is being used in this project.


Radio Frequency Identification (RFID) uses electromagnetic fields to identify and track tags attached to objects automatically. The technology can be classed into active and passive IDs. Passive IDs are utilised in a situation such as door swipes or 'tap-and-go' credit cards. Passive tags use the nearby RFID reader's radio waves to collect energy and use it to power the transmission of the encoded data. Active tags need a source of energy to operate but have a greater operating range. These are used in application such as race timing and tracking. RFID tags can be attached to anything from parcels, to food to animals and even people.

The technology itself has been around for some time but has taken considerable research and development to bring to market. The inexpensive passive RFID “chip” needs to be exposed to 1000 times the amount of energy it needs to retransmit its data, and this needs to be done in a safe way. The ID tags can be used for more than just distinct user identification, but depending on the model, you can embed a significant amount of data.

The RFID unit used in this project is the RFID-RC522. This is a very common unit designed for interfacing with micro controllers such as the Arduino. The unit is capable of reading from a very close distance, and the tags can hold a reasonable amount of data. If you wanted to, you could include a significant amount of data to ensure that the keys are more robust to hacking. However, in this case, we will just read the ID from the unit, and if it matches the ones listed internally, the alarm will activate/deactivate.

In addition to RFID to provide arm/disarm, you could integrate a keypad. However we’ll focus on remote accessability in Part 2, which will provide a second arm/disarm method.

LCD 16x2

For this project we will be using the 16x2 Liquid Crystal Display (LCD). It is called the 16x2 LCD due to it being two rows of 16 characters that we can use to display any information we feel relevant back to the user. There are a number of different ways to work with the 16x2 LCD. From a hardware perspective you can use the standalone unit, which will have a variation of 16-pin interface or there are several iterations of an LCD shield. The shield is great and includes buttons, but it does limit you in terms of size and the reduction of I/O pins. For this project we will be using the standalone unit which means we only need to use six pins to drive the display.

The brilliant part about using the 16x2 is that Arduino has the LCD Library included and it is incredibly easy to use. We need to include the library, initialise the object, then simply tell the LCD what we want to say and where to put it!


There are two types of inputs we're using here, passive and active. The system can use either, but they need to be treated a little differently.

A passive input such as our magnetic reed switch, literally opens and closes a connection. Because this is a mechanical connection, it's possible for voltages to float on the wires, and provide false readings to the Arduino. For this reason, we use a resistor on the zone to ensure that unless power is being applied, the Arduino reads the zone as low.

For the PIR sensors we're using, they're active sensors which means they require power to operate, and feed a signal back to our Arduino. For this reason, they provide a clear logic signal to our Arduino and no resistor is required on the zone.


The magnetic reed switch is the go-to security device. They exist to trigger the alarm system if a door or window gets opened when it is not meant to be. They come in two parts and consist of a magnet and reed switch. Inside they have two small pieces of the metal set very close to each other. When a magnet comes close to the unit, the magnetic field draws the two pieces of metal together, closing the circuit. Using this and the Arduino we can sense when the reed switch’s magnet is moved (i.e. on the windowpane) and trigger the alarm.


The Passive Infrared sensor (PIR) is one of the most commonly used security devices after the reed switch. The PIR uses the infrared light spectrum to detect movement. This works by having two slots in the lens that “sees” through. When the unit is idle, both slots see the same amount of infrared light. When a person or an animal passes through one of the beams, it detects the difference between the two readings and triggers the output to go high.


The piezo buzzer is used in this example as it is small and low power. Having said that, it can still make substantial noise at close distances. In the case of the alarm, you would want a louder siren, but the piezo works well to show how the system works. We have also used it in the project to signal things such as the alarm countdown and the reading of the RFID card.


The alarm needs to do something once it has detected a break in one of the zones. To do this, we need an output. The most common of these would be the flashing strobe and an alarm siren. The code itself easily allows modification to trigger alternatives, such as send a tweet or making it IoT aware, which we’ll go through in more detail in Part 2. For now we have provided a relay output which you can connect to anything you like, to sound/illuminate in an alarm scenario. For this project, we have included two output wiring examples, but several outputs are provided in pins 29-33 and 48.


1 x Arduino Mega 2560XC4420 Z6281
1 x LCD 16x2QP5516 Z7013
1 x RFID Tag Reader (RFID-RC522)XC4506 Z6356
1 x RFID TagsXC4506 S5376
1 x PiezoAB3462 S6109
1 x PIR Input (optional)XC4444 Z6382
1 x NC Reed Switch (optional)LA5072 S5153
1 x 3 Push ButtonsSP0609 S1120
4 x 10kΩ ResistorsRR0596 R7782


This circuit might look daunting at first, but it's really just a series of smaller circuits. For this reason, we'll tackle it bit by bit, until you have a full working circuit. Some connections will use the breadboard, others such as the LCD will be made directly.

CONNECT THE LCD: Depending on your unit you may need to solder a header on. To breadboard this we need to place the headers “up” as it makes it easier to jump the headers over to the breadboard. A 10k variable resistor can be used between pin 3 and GND, however we're simply connecting direct to GND for full contrast. Using the following pinout to connect your LCD.

1 (VCC) 5V
3 (VO) GND
4 (VO) A8
5 (R/W) GND
6 (E) A9
7 (DBO) NC
9 (DB2) NC
10 (DB3) NC
11 (DB4) A10
12 (DB5) A11
13 (DB6) A12
14 (DB7) A13

Test using the LCD_Hello_World.ino. This will display “HELLO WORLD!” on line 1 and a count on line 2 [3]. If you don’t see any output, go back and check your wiring.

Hello World

CONNECT THE RFID READER: The pin out for the unit [4] is as follows;

SDA 53
SCK 52
RST 49
3.3V 3.3V
RFID Reader

Please note this unit runs on 3.3V not 5V as the LCD is powered from. Once it is hooked up, you will get a red LED (on this model) to indicate it has power. In the resources, you will find the RFID_DUMPINFO sketch, run this code and you will get all the information that is on your RFID tag displayed on the serial monitor.


This circuit uses three buttons [5] to interface with the system. They provide you with various functionality when you don't specifically want to arm or disarm, including functionality to test the zones. It's important to note that, like the mechanical reed switch we need to be very clear to the arduino about our intention. For this reason we use resistors when wiring our tactile switches. The Arduino then receives either a clear 5V signal, or a clear GND signal.



PIR Connections:


Reed Switch Connections:


Note: Remember to ground your zone when using reed switches.


Piezo Module (Alarm Feedback):

In our system, the small piezo provided feedback. Note: If you're not using an active module, connect the + to pin 29 instead of 5V.

S 29
+ 5V

Relay Module (For Siren / Strobe):

When the alarm is triggered, we switch the relay. This is to provide power to alert systems, such as a strobe, siren, or warbler. You will need to have a separate power source for these items as most run on 12-24V.

S 28
+ 5V

The relay contacts should be configured using the NC / Common contacts. If your siren or strobe runs from 12V, you will need a separate power supply for it. You do not need to connect anything to the relay output for testing if you do not wish to do so. The light on the relay module illuminates to show you it has triggered.


There are two libraries required for this build. LiquidCrystal.h for the 16x2 LCD is built in, and MFRC522.h is required to run the RFID reader. We have included it in the package. Please install it into your libraries directory or the local directory of the project.

The most significant thing you will need to understand is how the LCD library works. Its probably simplest to think about it as a very similar function as the Serial.println(). You have two lines in which we can write too. We need to tell it which line and where to start writing. Then we give it a string and it prints it to the screen. The library and unit provides a built-in character set, so we just sent it a normal string. A basic instantiation and usage of the LCD would be:

lcd.begin(16, 2);

This starts the LCD object and tells it that it is has 16 columns and 2 rows.

lcd.setCursor(0, 1);
lcd.print("hello, world!");

This is the simplest way to output a message to the screen. It is similar to the Serial.println() function and will write whatever your message is to the LCD.

However we don’t always want to write to the very first section of the screen and we may need to specify. The alarm will sound until the disarm function is called when the RFID is swiped. The above code will set the cursor to column 0, line 1. Line 1 is the second row, since counting begins with 0.

Note: The characters do not clear until you send a new character in its place. In this project we have written the clearScreen function. This just saves sending nulls or spaces at the end of any strings that you send to the LCD.


You will need to setup the zones used by your project. How many do you intend on monitoring? We have setup seven zones. If they're unused, they must be grounded to avoid false triggering.

int Zone01 = 34; 
int Zone02 = 35; 
int Zone03 = 36; 
int Zone04 = 37; 
// add a line for each new zone, and assign
This diagram shows all major connections required for prototyping and testing, with each of the 7-zones broken out and grounded for reliable operation.
This diagram shows all major connections required for prototyping and testing, with each of the 7-zones broken out and grounded for reliable operation.


The outputs are defined on the following pins. If you wish to add more just continue with the pattern. You have more pins available up to pin 44, then wire them in accordingly.

// outputs 
int relayOut = 28; 
int piezoOutput = 29; 
int Output01 = 30; 
int Output02 = 31; 
int Output03 = 32; 
int Output04 = 33;


With the current version of the code, we need to manually add in the RFID Tag ID. Once you have all the components connected load the DumpInfo.ino file and run. Make sure you have the serial monitor open. Once the unit has booted, swipe your RFID tag, and the number will be displayed. Repeat, to get a copy of all the tags you wish to use. Once you have these numbers (they will look like this “48:93:163:124”) we need to add them into the code. Find the following line:

int keys = 2; // number of cards
// tags saved, next line 
String results[2] = { "80:231:86:128",
  "48:93:163:124" };

Decide how many tags you will be using and change “int keys = 2;” to this number, you will also need to change “String results[2] “ to the same number. Finally add your TAG ID “{ “80:231:86:128”, “48:93:163:124” };” as a string with a comma in between. There is no comma after the last value, i.e. { "x", "y", "z" }.


Once you have coded your RFID tags to the system, there’s little need to recompile the sketch unless you make substantial hardware changes or need to enable zones you have disabled via code.

There are three simple functions with the on-board tactile switches; These could be omitted, but they provide very useful functionality.

Button 1: ARM - This is an instant-arm function, and activates the same state as scanning a valid RFID tag. It’s useful to allow “exit arm” functionality for someone to lock up without providing a fob.

Button 2: TEST - This will sound the piezo and trigger the relay for two seconds, so you can check wiring and such.

Button 3: SET - This will check all your alarm zones and check for any zones currently in “alarmed state”.

You really aren’t limited to the number of sensors you attach to each zone, and the number of zones could be expanded with some minor code adjustments too.

We have tested PIRs and reed switches using 30m of standard alarm cable, and everything seems to be stable over that distance. The current draw is small, keeping voltage drop to a minimum.


We don't currently have a solution for backup power, which is a very prudent measure in security systems. We described an Arduino UPS system in Issue #1, which would be suitable for this project. It uses a rechargeable lithium battery and DC-DC converter to provide power, while being automatically recharged via USB when mains power is available. We can easily connect an off-the-shelf UPS however, which may be useful if you're running 12V sirens/strobes and have other power considerations.


We're using active low method for our zone monitoring. This means that when everything is in a "safe" state, there is 0V being received by the arduino on each zone. Only when a sensor is tripped, is 5V present on the zone. We did this due to the way the arduino PIR modules are designed. They provide GND when nothing is detected, and 5V when it is activated. However, if you're using PIR modules that can be configured for low output in alarmed states, or you're using passive hardware such as reed switches, you can suitably modify the sketch to handle this.

One potential pitfall of this setup is that it is theoretically possible for an intruder to cut the wiring to the sensors, preventing them from triggering the alarm. Of course, it's a little bit "Mission Impossible" unless you have your wiring dangling in a convenient place for them to reach, but it is possible. Additionally if a sensor fails, there's a wiring fault, or other incident, it could fail to send an alarm signal back to the unit. By using active high monitoring, the alarm will trigger on a true activation, but also if wires between zones are cut, or there's a fault with the zone wiring.

It is possible to invert the logic response from the PIR also, but this seemed like alot of work. Let's face it, if you have very high security requirements, you're probably not installing a DIY alarm. Sharks with lasers on their heads are far more appropriate. But i digress...

In order to reconfigure the system to handle an active high system, it's rather straight forward. You can also mix and match high / low zones depending on your sensors if you wish. The system will still report zone faults the same way.

Here is an example to reconfigure Zone 1. The process is the same for all zones.

Around line 52, locate the following code block:

if (digitalRead(Zone01) == HIGH) {

Now change HIGH to LOW. This tells the system that LOW should show as a problem on the screen.

if (digitalRead(Zone01) == LOW) {

Around line 123, locate:

if (digitalRead(Zone01) == HIGH) {
    alarmActive = 1;

Now change HIGH to LOW.

if (digitalRead(Zone01) == LOW) {

This tells the system that is Zone 1 does fall low (i.e. doesn't have 5V present), then this is a problem. Now around line 215, locate:

pinMode(Zone01, INPUT); //Alarm Loop 1
digitalWrite(Zone01, LOW);

Next change LOW to HIGH.

digitalWrite(Zone01, HIGH);

This ensures the Arduino appropriately sets up the zone.

That's it! You have now improved the tamper resistance on Zone 1 and converted it to active high monitoring.


When installing an alarm system there are many instances where you'll want more than one sensor per zone. Perhaps you want switches on each window or door, maybe even a PIR too. Whether it’s a particular room or an entire floor of a house, whatever your purpose, there are instances where you’ll want a zone to be a truly identifiable "breach zone".

Our system will support multiple sensors without too much work being required. You simply need to wire your sensors in parallel. That is, each one is provided power, and each returns to the same zone pin for that sensor.

For instance, we set up Zone 1 to listen on pin 34 of the Arduino. If you have three PIR sensors, each "signal" output still points to the same place, pin 34 on the Arduino.

One benefit of parallel configuration is that wiring becomes very simple. You can have one line of 4-core alarm cable per zone. You simply splice each sensor into the cable as appropriate, connecting the 5V and signal wires for passive sensors, or 5V, GND, and signal wires for active sensors.

Note: If you have adjusted your zone to active high as described previously, then your wiring requirements will now be different. Sensors must now be run in series with each other. If you use active high configuration with parallel wiring, if one sensor is tripped, another sensor on the same zone can still be providing voltage feedback to the controller, and the unit will still assume everything is fine.


We'll cover multiple sensors in greater detail, to create a full installable item. While this is a fully functioning prototype, to avoid problems with loose wires and false alarms, it really needs to be moved to a proper protoboard so connections can be soldered. We’ll also add IoT functionality to allow remote arm/disarm, dynamic learning of RFID tags, add some additional programme flexibility, as well as a few other cool features. Don’t miss it!

Part 2

Part 3