Video icon 64
Learn to code with practical video courses from Tuts+. Start your free trial today.
Advertisement

Building a Wireless Sensor Network in Your Home

by

This tutorial will teach you how to create a network of cost effective, wireless sensor modules.  Many of the ready-made wireless modules can be too expensive for use in multiple sensor units.  While Wi-Fi and Zigbee modules are popular and easy to use, their cost can make their use in an array of sensors impractical.  There are, however, low cost RF modules without all of the expensive features that will work just fine these purposes.  The Arduino platform can use low end radio modules to communicate easily and reliably.  

Once the hardware is assembled, you will leverage the Raspberry Pi platform to post the data to Xively's Internet of Things service where you can track the values over time and trigger on threshold conditions.

Gather the Components and Tools

This project will include three parts, two transmitter units and one receiver unit.  The transmitters are made up of an Arduino board, sensor, and RF transmitter.  The receiver unit is composed of an Arduino board, an RF receiver, a logic level converter, and a Raspberry Pi. 

There is a wide range of Arduino compatible boards that can be used for this project.  The minimum requirement for the board for this project is two digital GPIO pins and one analog pin.  Select an Arduino compatible board that matches the cost and simplicity needs for this project.  

In this tutorial I've used a set of Arduino Nano boards that fit well in a breadboard and are simple to program, However, the 5V versions of the Arduino pro mini or Trinket will also work well and at a much lower price point.  These however require a little more experience to program and use.  Choose wisely.


Receiver 

Transmitters (two units)

Tools

  • PC/Mac with Arduino programming IDE installed
  • USB cable for programming Arduino boards
  • USB Keyboard and Mouse.  Either combined or with a hub so both can be used with a single USB port.
  • The source package associated with this tutorial on your programming workstation

Assemble Transmitters

The transmitters themselves are relatively simple circuits.  Only one pin is used to retrieve the information from the temperature and humidity sensor and one pin is used to send that data to the RF transmitter.  The breadboard diagram is shown below.

The 9V power supply will attach to the barrel connector making the bottom rails 9V.  The power regulator in the Arduino will produce 5V that is safe to use for the radio and sensors, the top power rail of the diagram.

The sensor comes with a 10k ohm resistor that connects the data pin to power as a pull up resistor while another wire connects it to GPIO D3.  

Be careful to follow the setup below and make sure you double check the datasheet for the sensor and RF module to ensure that the components are positioned in the breadboard properly and the power, ground, and signal pins are connected to the right pins.  The fritzing diagram is included in the source package for more detail.

Transmitter diagram

The antenna is an important part of the board because the RF module does not have a built in antenna.  I used a 6-inch female to male jumper wire plugged into the breadboard and it worked well enough to allow reception from all parts of my home and a little bit outside.  As noted in the diagram, 6.5-inch is optimal for this antenna if you need additional range.

A note about RF use.  There are different laws and rules about use of frequencies in different countries.  Please ensure you are in compliance with these rules before broadcasting.  That being said, the signals from these modules are barely powerful enough to pass outside of your home. In perfect conditions, though, these modules can broadcast up to 500 feet.

Download Libraries for Components

The transmitter uses two libraries that are not bundled with the Arduino IDE.  Download the libraries as described below and uncompressed them into your sketch directory in a subdirectory named Libraries.

  • Download the VirtualWire source package for this tutorial and unzip the wirelesstransmitter sketch folder into your Arduino sketch folder
  • In the wirelesstransmitter folder create a folder named Libraries
  • Download the latest version of the VirtualWire code, 1.23 as of this writing, from the project page
  • Extract the VirtualWire folder into the wirelesstransmitter/Libraries/ folder so you have another subfolder named VirtualWire
  • Download the DHT sensor library from its project github page
  • Extract the DHT folder into the Libraries folder as well. You should now have the two required library folders DHT and VirtualWire in your wirelesstransmitter/Libraries folder.

Program the Arduino Board

This tutorial assumes you have some experience with Arduino and how to program them using the Arduino IDE.  If you do not, there are very good instructions at the official Arduino site.

  • Open the wirelesstransmitter sketch from the source archive in the Arduino IDE and save a copy locally
  • Ensure the Arduino is NOT connect to power via the barrel connector
  • Connect the board to your programming workstaiton station with an appropriate USB cable
  • Set the board type to your selected Arduino board under the Tools > Board menu
  • Set the serial port to the port detected when you connected the Arduino board under the Tools > Port menu
  • Ensure that the MYID define is set to 1 and the TRANSPIN and DHTPIN are properly set to the pins connected to the RF transmitter module and DHT sensor respectively. If you built your board per the diagram above this should all be set already.  See the code example below.  
  • Ensure that the UNIT is set properly for your preference Fahrenheit or Celsius
#define MYID 1      //the ID number of this board.  Change this for each board you flash.
                    //The ID will be transmitted with the data so you can tell which device is transmitting
#define TRANSPIN 3  //what pin to transmit on
#define DHTPIN 4     // what pin the DHT is connected to
#define UNIT 0      // 0 for Fahrenheit and 1 for Celsius

The MYID define is a numeric ID that the transmitter uses to uniquely identify itself.  Because you will have multiple transmitters in different locations it is important to have a unique ID for each one.  This number will be used again when you setup the receiver script.

  • Verify the code by pressing Control-R to ensure the libraries are included and compiled properly.
  • Push the code to the board by clicking the Upload button on the tool bar. 
  • Open the Serial Monitor windows by pressing Control-Shift-M

The Serial Monitor window resets the Arduino so you should see a line of code on the screen that looks something like:

Humidity: 44.00 %    Temperature: 60.80 *F
Sending Message: ID:1:TS:23143:TF:60.79:RH:44.00

The message is composed of Name:Value pairs that the receiver will handle.  The transmitter will read and broadcast its signal on a long random interval.  The sensors don't change very much or frequently, so broadcasting more often than once every minute adds no value.  The random wait time is to allow multiple sensors to coexist.  

Even if there is doubling and the signal from both transmitters is lost, the random interval will ensure that their next broadcasts will not overlap.  The random seed for this interval is set from an analogRead on an unused analog  port which will return random values to ensure no two transmitters are on the same pattern.  

The example code generating the output above is set to use Fahrenheit.  You can see the TF:60.79 identifier in the message string indicating that my lab is indeed just a hair under 61 degrees.  However the relative humidity RH:44.00 is a comfortable 44%.  One might infer from the cool damp environment that my lab is in my basement.  One might be right.

The transmitters are set to wait 2 to 5 minutes between broadcasts by default.  If you wish to speed this up for debugging purposes then modify the delay() value at the end of the sketch to be more like 5000 (ms).  It is highly recommended that you change this back and re-upload the code to your transmitters when you are ready for full time use.

  • Build the second transmitter board
  • Modify the transmitter sketch so that the MYID define is set to 2 
  • Upload the code to the second board
  • Open the Serial Monitor windows by pressing Control-Shift-M and verify that the output looks like the first transmitter board with the exception that the transmitted message starts with ID:2

Build the Receiver Board

The receiver board will be responsible for receiving the broadcast message on its RF Receiver component and sending that message over serial wires to the Raspberry Pi.  The Arduino board is used to receive the signal for a couple very important reasons.  The VirtualWire code uses the real time nature of the Arduino to manage modulating and demodulating the signal.  

This means that the receiving unit needs to be operating at the same frequency.  In addition, there is little room for jitter on the receiving processor, to which the Raspberry Pi is prone, due to its preemptive, non real-time operating system. Comparing the costs of an Arduino Pro Mini plus the RF receiver module to that of a Zigbee module that could talk directly to the Raspberry Pi revealed that using an external Arduino was still quite economical.

Build the receiver board per the Fritzing diagram below.

Receiver Diagram

At this point do NOT attach the 5V and ground leads from the Pi to the breadboard. Keep the jumper wires handy, but you don't want to power the Arduino from both the USB port and the Raspberry Pi.

Note that the logic level converter in the materials list above is not exactly the same as the one in the Fritzing library, but the pin outs are well labeled, just in different places.  Please make certain that the correct wires are connected to the correct pins on the actual logic level converter.  

This component is required in order to convert the 5V Arduino serial signal to a 3.3V Raspberry Pi serial signal and not damage the Pi.  See the image below for additional help.

Actual Logic Level Converter Wiring

Note that the RX and TX wires cross through the logic level converter so that the TX from the Arduino goes into the RX of the Pi.  The next steps involve setting up the Pi, you'll return to program the Arduino later.

Setup the Raspberry Pi

There are several guides to purchasing and installing an OS on your Raspberry Pi. Install the latest Raspbian operating system. The following steps describe connecting the peripherals to the Pi and configuring.

Tip: If you need to know more about flashing an SD Card, for your Raspberry Pi, just refer to our tutorials: How to Flash an SD Card for Raspberry Pi and How to Install NOOBS on a Raspberry Pi With a Mac.

  • Insert the USB Wi-Fi adapter into the top USB port on the Pi
  • Connect the USB hub to the bottom USB port on the Pi
  • Connect the mouse and keyboard to the USB hub
  • Connect the HDMI Monitor
  • Insert the SD Card
  • Connect the power supply
  • Perform first time setup configuration leaving the default option to boot to a graphical desktop
  • After the Pi reboots to a desktop follow these instructions on how to use the GUI tool to configure your wifi network.
  • Open a terminal window by double-clicking on the LXTerminal icon.
  • Execute the command sudo raspi-config
  • Select the Enable Boot to Desktop/Scratch > Console Text console, requiring login option
  • Select the Advanced Options > SSH to enable network command line access
  • Select Finish and allow the Pi to reboot to the text console
  • Make note of the IP address the Pi reports when it boots. This will be used to SSH to the Pi in later steps.  The steps below for configuring the Pi are easier done from an SSH session to the Pi.

Configure Raspberry Pi

The Raspberry Pi uses its serial port by default as a serial console.  The device is named ttyAMA0.  When it boots it dumps boot messages to this device and sets up a login session on it.  In order to use it for receiving data from the Arduino you will need to disable the serial console and session.

  • Edit the inittab file that controls text login session with the command below.  It's always recommended to make a backup of the original file before editing just in case something goes wrong.
sudo pico /etc/inittab
  • Locate the lines at the bottom of the file that refer to the device ttyAMA0 and add a # to the start of the line that includes this device name.  It should look like the lines below when you are done
#Spawn a getty on Raspberry Pi serial line
#T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100
  • Edit the /boot/cmdline.txt with the command below.  Don't forget to make a backup copy just in case.
sudo pico /boot/cmdline.txt
  • Remove the arguments that reference ttyAMA0.  They part you want to remove looks something like this: console=ttyAMA0,115200 kgdboc=ttyAMA0,115200
  • Save the file and reboot the Pi

Install Python Script and Prerequisites

The python script that will complete the receiver will perform several functions.

  1. Read from the serial port
  2. Parse the input and ensure it is sane
  3. Interpret the serial data
  4. Post the data to Xively into the appropriate feed

In order to perform these functions you will need to install the prerequisite modules to install the serial libraries and Xively communications.  

  • Login to the Pi and execute the commands below to install them.
sudo apt-get install python-serial python-setuptools
sudo easy_install pip
sudo pip install --pre xively-python
mkdir ~/scripts

  • Copy the script wirelessnetwork.py from the source package for this tutorial into the scripts directory you just created.  You can do that by copying and pasting the contents or by scping the script to the Pi.
  • Ensure the script is executable with the command
chmod u+x wirelessnetwork.py

The next several steps will take you through setting up Internet of Things accounts that allow you to record and react to the data your device is recording.

Setup Your Xively Account for the Pi

Xively is a service that collects data from things. You can setup and register your thing or Raspberry Pi with Xively and data can be pushed from your Pi to the cloud for tracking and triggering.

  • Go to xively.com and register for a free account
  • Click on the Get Started button
  • Scroll to the bottom of the page and choose Sign Up for a free Developer Account
  • Fill out the appropriate account information and validate your account
  • Authenticate as your new account as needed
  • Select Web Tools > Develop to go to your new developer page
  • Click on the big + Add Device box to add your Raspberry Pi
  • Fill out the Device Name: WirelessNetwork, Device Description: Environmental Monitor, choose Private Device unless you wish to share your salt level with the world.
  • Click Add Device. After the device is created you will be presented with the device screen with keys and information about the device.
  • Record the Feed ID and API Key from the device page. The Feed ID is in small font near the top of the page and the API Key is in large font on the right side of the page.  You will need these to finalize the wirelessnetwork.py script you downloaded in the previous section.

Configure the Python Script

In order to post data to Xively the wirelessnetwork.py script needs to have the Feed ID and API Keys that you recorded above.  Edit the script using pico or your favorite editing tool (no vi vs emacs wars here, please).  See the sample snippet from the top of wirelessnetwork.py script for an example of where you would insert the variables.  Also note you can toggle the output of the script off by switching the DEBUG variable to 0.

#some defines for Xively 
FEED_ID = "FEED ID HERE"  #enter your feed ID number here
API_KEY = "API KEY HERE"  #set your API key here
# initialize api client
api = xively.XivelyAPIClient(API_KEY)

#Create mapping from transmitter ID number to names. This could be a DB some day
DEV={'1':'Bedroom', '2':'Basement'}

DEBUG = True

While you are editing the script make sure to edit the DEV variable.  This variable is a name mapping for the IDs that the sensor modules will be sending.  In this example when the sensor module with ID 1 sends a message, the script will post to a Xively channel with the friendly name Bedroom instead of ID1.  In the same way, the sensor module with ID 2 will be reported into the channel Basement.

Program the Receiver Arduino

The Raspberry Pi is now ready to receive data using the wirelessnetwork.py script.  The Arduino needs to be programmed with the wirelessreceiver sketch.

  • Open the wirelessreceiver sketch from the source package and save a copy locally
  • Copy the VirtualWire library from the wirelesstransmitter/Library directory to the Library directory under the new wirelessreceiver directory
  • Attach the receiver Arduino receiver to your programming workstation and ensure the port and board type are set correctly.
  • Ensure that the RXPIN define is set to the pin number that is connected to the RF receiver module.  If it is built per the diagram the sketch should be fine without changes.
  • Verify and upload the the sketch to the Arduino
  • Open the Serial Monitor windows by pressing Control-Shift-M.  If the transmitters are not running you will not see out put.
  • Plug one of the transmitter modules into power using the 9V wall adapter and the barrel connector on the breadboard.  You should now see the messages that are being received on the Arduino.  It will look something like the data below.
ID:1:TS:23143:TF:60.79:RH:44.00
ID:1:TS:24532:TF:60.79:RH:44.00
ID:1:TS:29324:TF:60.79:RH:44.00
  • Unplug the USB cable from the Arduino
  • Attach the ground and power jumpers from the Raspberry Pi

Test the Receiver Script

Now that you have the Arduino receiving data from a sensor module you can test the script on the Pi to ensure it is properly reading the data and posting it to Xively.  Open an SSH or terminal session to the Pi for the following steps.

  • Activate the second wireless transmitter by plugging it in with the second 9V adapter
  • Execute the wirelessnetwork.py script from the /home/pi/scripts directory with the following commands
cd /home/pi/scripts/
./wirelessnetwork.py
  • Review the output in the console and on the Xively website.  
 
Received input: ID:1:TS:154075:TF:73.39:RH:39.00
Processing data for: Bedroom
Posting temp fahrenheit for Bedroom
Creating datastream
Updating Xively feed with value: 73.39
Posting relative humidity for Bedroom
Found existing datastream
Updating Xively feed with value: 39.00

Received input: ID:2:TS:522:TF:60.79:RH:44.00
Processing data for: Basement
Posting temp fahrenheit for Basement
Creating datastream
Updating Xively feed with value: 60.79
Posting relative humidity for Basement
Found existing datastream
Updating Xively feed with value: 44.00

The script will create feeds for humidity and temperature the first time it runs.  The example above shows the script receiving the messages, parsing them and posting them to Xively successfully.  Use Control-C to exit the script before proceeding to the next step.

Switch to the browser windows where you created your Xively account and device.  The new datastreams and some information about them should be available and look something like the image below.

Xively Channel Updated

Set the Script to Launch on Boot

Because the Raspberry Pi is going to be run headless the script should be set to start automatically when the unit is powered.

  • Add the following line to the /etc/rc.local file. Use your favorite editor, but make sure to sudo the edit command as /etc/rc.local is a root owned file.  The script itself can run as the user pi rather than as root.
sudo -u pi /home/pi/scripts/wirelessnetwork.py &
  • Reboot the Pi
  • Login to the Pi after it has rebooted and verify that the script is running with the following command.
ps ax |grep wirelessnetwork

The output should look something like the excerpt below.

22000 pts/1 S+ 0:02 /usr/bin/python /home/pi/scripts/wirelessnetwork.py

Summary

Congratulations!  You have worked through quite a lengthy tutorial and built a very flexible and expandable wireless network of sensors.  You have exercised a variety of skills such as building Arduino based breadboard circuits, connecting an Arduino to a Raspberry Pi, sending and receiving serial data safely between the Arduino and Pi, and sending you sensor data to Xively's Internet of Things service.

There is a lot of potential for expansion or further experimentation with this project.  You could choose to build additional sensor modules or add sensors to the existing modules. The format of the radio message is a simple key:value pair and the python script has comments on how to add different data types.  Try building a permanent home or housing for the transmitters.  There is a lot of fun potential of where to take this project.

Advertisement