If you have a friend that has an alarm system in his or her home, I am sure you’ve all seen these white motion sensors that are usually fixed above doors to detect anybody that would walk through the house when the alarm is on. They are usually the first block of any alarm system. Problem is, they cost a lot. I have seen some of these modules that cost nearly $100 (about 75 euros), and of course, you are then usually bound to use the same supplier for your whole home automation system.

In this article, we are going to see that you can reproduce exactly the same functionalities for a much lower cost, with any sensor you want, and of course using open-source hardware. Let’s dive into the project !

Hardware Requirements

There are two parts in this tutorial: an emitter part with the sensor, and a receiver part that will be the “hub” of the project. For this reason, you will need two Arduino boards for this tutorial. Yes, two ! You can use any boards for this project, but I suggest to use a small Arduino board connected to the sensor, but at the end you want something small on the sensor side. I used the Arduino Uno R3 board for the “hub”, and a Teensy board connected to the sensor.  I used the Teensy because it was on my desk and it is very tiny, but any small board like the Arduino Micro or Nano would work. Of course, you can use two Arduino Uno boards.

The next important components are the wireless transmission modules. Because I wanted to keep the costs low, I used some cheap RF modules. That lead me to some problems I will talk about later, but at the end they worked fine.

You will also need a PIR motion sensor (or any other sensor you want to connect, but in this project I will show you how to detect motion), some wires and two breadboards for prototyping.

Software Requirements

Of course, you need the Arduino IDE. During my initial tests with the RF modules, I had lots of problems finding the right way to write the code to have a reliable transmission between the two Arduino boards. Compared to other components, it didn’t work out of the box because I received a lot of noise on the receiver side and it was impossible to get back any information from the sensor. Finally, I found the VirtualWire library which helped a lot, so this is the one I will use in the rest of this article. The library uses different techniques like ASK (Amplitude-Shift Keying) to transmit the data reliably.  You can download it from their website. To install the library, just place it in the libraries/ folder of your Arduino folder.

Hardware Configuration

There are two parts to build in this project: the receiver and the transmitter.

Receiver

The receiver, the “hub”, is the simplest part to assemble. You need the “big” Arduino board, and the RF receiver module. On my module there were three pins: VCC, GND, and data. Simply connect the VCC pin the 5V pin of the Arduino board, the GND to the GND of the Arduino board, and the data pin to the pin number 11 of the Arduino board.

Transmitter

For the transmitter that is connected to the sensor, it is also quite simple. First, connect the transmitter. It also has three pins to connect: VCC, GND, and data. Simply connect the VCC pin the main power supply of the Arduino board you are using. Be careful, on the Teensy for example the main power supply of the chip is 3.3V. Then, connect the GND to the GND of the Arduino board, and the data pin to the pin number 12 of the Arduino board.

Finally, connect the PIR sensor. It also has three pins like the radio module. Connect the VCC to the main power supply of your Arduino board. Also be careful at this point: the PIR sensor I used could work without problems at 3.3V, but other requires 5V because of an on-board regulator, so you might have to do some soldering depending on your board and sensor combination. Please refer to the documentation of your PIR sensor to know which voltage you can use. Then, just connect the ground to the ground of the Arduino board, and the output pin to the pin number 7 of your Arduino board.

Testing individual components

We will take care of the radio transmission in the last part of this tutorial, so for now, we will simply test the motion sensor. Most of the PIR sensors simply return a “1” when they detect motion, so on the Arduino it is easy to detect motion using:

sensor_value = digitalRead(sensor_pin);

This is the sketch I used to test the sensor:

const int sensor_pin = 7;

void setup() {
 Serial.begin(9600);
 delay(1000);
}

void loop() {
 // Get sensor value
 sensor_value = digitalRead(sensor_pin);

 // Print on serial
 Serial.println(sensor_value);
 delay(1000);
}

You can just upload this sketch, open the serial monitor and play with the sensor to check if it is working correctly.

Putting it all together

Now that we made sure that the motion sensor is working, we can work on the radio transmission. Let’s deal with the transmitter part first. As I said before, the key in this project is to use to VirtualWire library, or you will run into serious transmission troubles. For this reason, I will always use VirtualWire functions when transmitting or receiving data through the RF modules. As for many of my tutorials, I will first go through the important parts of the code, and then give you the full code for the project. It starts by including the VirtualWire library:

#include <VirtualWire.h>

In the setup function of the Arduino sketch, we have to initialize the transmission and set the transmission rate:

vw_set_tx_pin(transmit_pin);
vw_setup(2000); // Transmission rate

The transmitter can sustain much more than 2000 bauds, but I want to be on the safe side here, and that’s more than enough for our application. Then, we read the value of the PIR sensor with:

sensor_value = digitalRead(sensor_pin);

We can then prepare the message that will be sent through the RF link, and change it if the sensor detected some motion:

// Init message
char msg[3] = {'o','f','f'};

// Change message if motion is detected
if (sensor_value == 1){
   msg[0] = 'o';
   msg[1] = 'n';
   msg[2] = '#';
}

Yes, I could have transmitted just 0 or 1 without any problem, but I wanted to see how reliable was the RF link to transmit some short words, this is why I decided to transmit “on#” or “off”. Finally, it’s time to transmit the message every second (and flash the LED to indicate some transmission):

// Transmit data every second
digitalWrite(led_pin, HIGH); // Flash a light to show transmitting
vw_send((uint8_t *)msg, 3);
vw_wait_tx(); // Wait until the whole message is gone
digitalWrite(led_pin, LOW);
delay(1000);

This is the complete transmitter code:

// Include VirtualWire library
#include <VirtualWire.h>

// Define pins
const int led_pin = 13;
const int transmit_pin = 12;
const int sensor_pin = 7;

int sensor_value;

void setup()
{
   // Init
   vw_set_tx_pin(transmit_pin);
   vw_setup(2000); // Transmission rate
   pinMode(led_pin, OUTPUT);
   pinMode(sensor_pin,INPUT);
}

void loop()
{
   // Get sensor value
   sensor_value = digitalRead(sensor_pin);

   // Init message
   char msg[3] = {'o','f','f'};

   // Change message if motion is detected
   if (sensor_value == 1){
      msg[0] = 'o';
      msg[1] = 'n';
      msg[2] = '#';
   }

   // Transmit data every second
   digitalWrite(led_pin, HIGH); // Flash a light to show transmitting
   vw_send((uint8_t *)msg, 3);
   vw_wait_tx(); // Wait until the whole message is gone
   digitalWrite(led_pin, LOW);
   delay(1000);
}

Now, the receiver. It is actually quite similar to the transmitter code. The setup is slightly different:

// Initialise the IO and ISR
vw_set_rx_pin(receive_pin);
vw_setup(2000); // Transmission rate

// Start the receiver PLL
vw_rx_start();

In the loop of the Arduino sketch, we also have to create the buffer to receive the data:

uint8_t buf[VW_MAX_MESSAGE_LEN];
uint8_t buflen = VW_MAX_MESSAGE_LEN;

Then, we actually have to check if a message was received with:

if (vw_get_message(buf, &buflen))

To finally print the message with:

for (int i = 0; i < buflen; i++)
   {
     Serial.print(char(buf[i]));
     Serial.print(' ');
   }

This last part will go through the received message and print every character, which should be “on#” or “off” in our case. This is the final receiver code:

// Include VirtualWire library
#include <VirtualWire.h>

// Pins definition
const int led_pin = 13;
const int transmit_pin = 12;
const int receive_pin = 11;

void setup()
{
   // Init
   delay(1000);
   Serial.begin(9600); // Debugging only
   Serial.println("setup");

   // Initialise the IO and ISR
   vw_set_rx_pin(receive_pin);
   vw_setup(2000); // Transmission rate

   // Start the receiver PLL
   vw_rx_start();

   // Set LED pin
   pinMode(led_pin, OUTPUT);
}

void loop()
{
   uint8_t buf[VW_MAX_MESSAGE_LEN];
   uint8_t buflen = VW_MAX_MESSAGE_LEN;

   // Check if a message was received
   if (vw_get_message(buf, &buflen))
   {
   // Flash a light to show received good message
   digitalWrite(led_pin, HIGH);
   Serial.print("Got: ");

   // Print message
   for (int i = 0; i < buflen; i++)
   {
     Serial.print(char(buf[i]));
     Serial.print(' ');
   }
   Serial.println();
   digitalWrite(led_pin, LOW);
   }
}

It is now time to test everything ! The first thing to do is to upload the right sketch to the right board. It can be tricky if you have two boards connected to your computer at the same time, so this is what I did. First, connect the transmitter board to your computer and upload the transmitter sketch. Then, disconnect the USB cable, actually put all the transmitter part away from your computer (like in real situation, right ?) and plug the Arduino board to an external power source (for the Uno board, between 7V and 12V. For other boards, refer to the documentation of your board). At this point, the LED of the board should blink every second to indicate that a message was transmitted.

Then, connect the receiver board to your computer and upload the receiver sketch. You should immediately see the LED of the receiver board blinking to indicate that it received a message. Finally, open the serial monitor and this is what you should see:

Create your own wireless motion sensor with Arduino

If you want to see more explanations in video, here is the Youtube video:

From that point, there are many things you can do with this project. You can put the transmitter part wherever you want in your home (however, you might need to insert antennas on the RF module if you have a big home), and power the Arduino board with an external power source. Then, on the receiver side, you can for example implement an alarm mechanism that goes on when motion is detected. Or couple the project to the Arduino GSM shield to send you a SMS whenever something is detected. The possibilities are limitless, so experiment & have fun !

Finally, here is the list of the components that have been used in this tutorial:

And if you enjoyed this article, you can follow us on Twitter and Facebook !