Overview of system components

Have you ever wanted to use your Raspberry Pi as a home automation system, able to gather information over a wireless network from sensors scattered around your house and yard , then use this data to automate actions such as activating lights, control your TV, water your plants etc.  This post will guide you through setting up the basic components of a system. Once you have this basic system setup I am hoping you will read my later posts as a guide to expand your system with more functionality. My posts are not intended to be the best way to accomplish a task, but simply to offer ideas that will spark your imagination. As such I hope you will share your thoughts and ideas through this site.  

Figure 1 shows the basic components of the system, including the hardware, software and how data moves through the system. This post will walk you through the steps to setup this system.

Step 1: Setting Up Raspberry Pi

Installing Node.js

Your Raspberry Pi will be the heart of your home automation system, but first we need to load some software that will make it easy to read/write data from the USB connector and turn the data we receive from our sensors into useful actions (e.g. send SMS text message if a fire alarm sounds). Node.js is a popular software framework for such a job. It is programmed in javascript and executes modules of code based on events. For example, when new data from a sensor is detected at the USB port we can trigger code modules such as ,

  • store the data in a database for trending,
  • send the data to a web page for live update,
  • send data to another sensor to perform an action (e.g. turn lights on)
  • send an SMS message

Installing Node.js is done using the standard apt script, but first we need to add NodeSource as a trusted source in the apt package repository. Type the following command at your Pi terminal. This instruction is for Node version 12 which is what all of the posts on this site are based. If you already have Node.js installed with a different version then most of the posts on this site should still work, but with a little adjustment. I have successfully run much of the code successfully on Node Version 7.

curl -sL https://deb.nodesource.com/setup_12.x | sudo bash –

Next we install the Node.js software by typing the following

sudo apt install -y nodejs

To verify the installation, run the following command which will print the Node.js version. (Note the double hyphen preceding version)

node –version

You should get a response like V12.16.2 .

Create new directory for your Home Automation software

Next you will need to create a directory to hold all of the Node.js files. I called mine myAutomation.

mkdir myAutomation

Installing serialport

One of the benefits of using Node.js is the availability of many rebuilt and tested software packages. One of these is serialport which can be used to provide a simple interface to read and write data to your Pi’s USB port. Instructions on installing serialport can be found at their web site https://serialport.io/docs/guide-installation . I have summarized the key steps below,

First enable the serial port on Raspbian. Type raspi-config in the terminal window, then select Interfacing Options, then Serial. You will then be asked two questions:

  1. Would you like a login shell to be accessible over serial?
  2. Would you like the serial port hardware to be enabled?

You must answer No to question 1 and Yes to question 2. If the login shell is left active, you will experience hangs and or disconnects.

Next install seriaport using the following command,

cd myAutomation

sudo npm install serialport –unsafe-perm –build-from-source

(Note: npm is the package manager for Node.js. When a package is installed it is loaded into a directory called node_modules within the current directory, in this case myAutomation. If node-modules directory does not exist it is created. Take a look in the node_modules directory and you will see lots of packages installed including serialport. The other packages are dependencies and needed by serialport. These were installed automatically with the npm command.)

If you receive some error/warning messages when trying to install serialport not to worry. I received several pages of warnings but everything seamed to work OK when I tested my Node.js application.

That’s it, you are now ready to start writing your first Node.js application.

Writing your node.js application

If you are new to node.js then there is an excellent starter tutorial at https://www.tutorialspoint.com/nodejs/index.htm . The application we will write will simply read text data received from the Pi’s USB port and display it to the screen. Node.js applications are modular, so we will write two programs,

  • serialMonitor.js will be a node.js module that uses the serialport package we just installed to read data from the USB port.
  • main.js will be the main program that we will run from the command line that will use the serialMonitor.js module.

First create a subfolder under your myAutomation folder that we will use to store all of the modules we write. I called my sub-folder ‘myModules . Below is our first module that we will write and store in this subfolder.

myAutomation/myModules/serialMonitor.js

const SerialPort = require("serialport");
const Readline   = require('@serialport/parser-readline');

function mySensorMonitor() {  // constructor function, used in last line of code to create object that is exported.

	this.processMsg = function(msg){ // msg is the line of text read from USB port 
		console.log(msg);	// print message;
		// we will expand this section later to decompose message and initiate actions
	}	
	
};

mySensorMonitor.prototype.openPort = function(usbID, baud) {

	var parentThis = this;	// create reference for this back to parent mySensorMonitor object	
		
	const port   = new SerialPort('/dev/tty' + usbID, {baudRate: baud, autoOpen:false, });	
	const parser = port.pipe(new Readline({delimiter: '\n'})); 

		port.open(function(err){
			if(err){
				return console.log('Error opening USB port: ', err.message); 		
			}
			else{
				console.log("\n Serial port /dev/tty" + usbID + " opened \n" );
				// read data and process the message
				parser.on('data', function(data){  
					parentThis.processMsg(data);	// note we use 'parentThis' instead of 'this', as 'this' points to the 'port' object.
				});
			}		
		});

}

module.exports = new mySensorMonitor();  // create object and export

A brief description of this program is as follows,

  • Lines 1-2 load the serial port package modules that we installed previously. These modules are used in lines 17 and 18 to create two new objects ‘port’ and ‘parser’. ‘port’ sets up a communication channel to one of the Pi’s USB ports. ‘parser’ is an object that reads and buffers data received from ‘port’. When a new line character (‘\n’) is read ‘parser’ emits a ‘data’ event’. This event is captured and processed by line 27 using the syntax ‘parser.on(eventName,function)’.
  • Lines 4-11 create a constructor function which is later used to create an object that is exported in line 35. The constructor function has one private method processMsg(msg) which is called at line 28 each time a new line of text is received through the USB port. The line of text is passed as argument msg. For now this method simply prints the text to the screen using the console.log command. But we will later expand this to add functionality e.g. store sensor data to a database, send SMS alerts etc.
  • Lines 13-33 create a public method ‘openPort’. This method is called in line 3 of the main.js program described below to open up a USB port and start scanning for messages. Because the Pi has several USB ports we have to identify the specific port that the Arduino gateway is plugged into. When you connect your Arduino to a PI’s USB port a special file called a socket is created in the Pi’s /dev directory. e.g. /dev/ttyUSB0. If you run the command below before and after connecting your Arduino you can identify the name of this file. In my case the file is /dev/ttyUSB0, and as such in the main.js program shown below I pass “USB0” as a parameter to the openPort method along with the baud rate 115220 which matches the value I set in the Arduino gateway described later.

ls -l /dev/ttyUSB*

myAutomation/main.js

This is the main node’js program that needs to me saved in the myAutomation directory. It is very simple at this stage. Line 1 loads the serialModule.js module we wrote above. Line 3 then calls its public method ‘openPort’ to start scanning the USB port for new data.

var mySensorMonitor = require("./myModules/serialMonitor");

mySensorMonitor.openPort('USB0',115200);

The main.js program can by run from a RaspberryPi command window using the following command. If you run it now you will get an error message as there is nothing connected to the USB0 port. In the next sections we will build our Arduino gateway and connect it to the Pi.

node main.js

Step 2: Setting up the Arduino Gateway

The Arduino gateway will be the hub for your new wireless network, reading/writting to all of the sensors and passing the sensor messages to/from your Raspberry Pi Controller.

We will be using an open source framework called mySensors (https://www.mysensors.org) to build our home automation network. The framework provides a library of C++ code that can be included into your Arduino programs giving you easy access to read and write messages between sensors and the controller. For example the following line of code running in an Arduino sensor sends the value of a variable ‘temperature’ to the Gateway.

send(msgTemp.set(temperature, 1));

There is a wealth of information on the mySensors website that I would encourage you to read. The framework is very flexible, able to run in different configurations. For our case we will be using low cost components to create our wireless netwok. This includes,

  • Arduino Nano’s will be used for each sensor and the Gateway. Nano’s provide a good balance between cost (Approx. $5 /each) and performance.
  • nRF24L01 wirless tranceivers. These 2.2 GHz wirless modules cost just $12 for a pack of 10 and will connect each Arduino sensor with the Arduino Gateway.

Downloading the mySensors Arduino library

MySensors is an open source hardware and software community focusing on do-it-yourself home automation and Internet of Things, (https://www.mysensors.org/). The library can be easily added to your Arduino IDE using the Library Manager, and once installed you will be able to send data between Arduino over a wireless network.

Note: If you have not programmed an Arduino before then you will need to install the Arduino IDE (Integrated Development Engine) on your computer. This IDE is based on the C++ language but has many features that make it easier for those new to the language. The IDE takes care of compiling your program and transferring to the Arduino micro controller. It also has a useful text console that can be used to display status of variables from the code executing in the Arduino. Instructions on installing the IDE can be found on the Arduino web set https://www.arduino.cc/en/Guide/Windows.

First open the library manager than can be found in the IDE under the Sketch menu (see below)

Open the Arduino Library Manager
Menu

Use the search feature of the library manager to find the mysensors library, then select the version and click the Install button. In the image below you will see that I have version 2.1.1 already installed, and thus have the option to select a newer version and upgrade. Upgrading versions can be complicated, so once you select a version I would suggest sticking to it. For all of the project blogs on this site I used version 2.1.1 which provides all the functionality you will need. I have also had no issues with stability/bugs, and have been using it for approx 2 years.

Building your Arduino Nano Gateway Hardware

What you will need:

  • Arduino Nano: Available through most on-line electronic sites. I purchased mine via Amazon from supplier Elegoo, at a cost of $20 for three.
  • nRF24L01 Wirless Tranciever: You can purchase these modules from many on-line retailers, just type nrf24l01 into your search engine. Prices vary greatly, and according to reviews so does the quality of what you’ll get, so I’d advise checking the reviews before you buy. I purchased 10 of these modules on Amazon for $13 from supplier Makefire and have had good success so far.
  • DIY wire47 uF Electrolytic capacitor, Wire, Soldering Iron: These are consumables that you will need throughout all of the projects described on this site. I use DuPont Cables for prototyping and 26AWG wire for projects from supplier Strive-day that I purchased through Amazon. Its a nice assortment of colors, great for DIY electronic projects.

The mySensors library allows for several options of wireless hardware. I will be focusing on the nRF24L01 wirless module. This is a small, low cost wireless module that sends/receives data using via a 2.4 GHz wireless signal. If you are interested in the details then feel free to review the modules data sheet, but for our purposes all of the complexity has already been figured out by the good folks who wrote the mySensors library. What you will need to know is how to wire it up to your Arduino microcontroller which is shown below. Note the placement of a 47 uF electrolytic capacitor soldered directly across the +ve and GND pins of the NRF24L01. The reason for this is to prevent voltage dips when the transmitter is configured to max power settings described below. Make sure you solder the -ve lead of the capacitor to the GND pin on the NRF24L01. The NRF24L01 uses SPI (Serial Peripheral Interface) communications protocol to communicate with the Arduino. Again you don’t need to understand this as the mySensors library takes care of it. If you want to learn more checkout this article on the Sperkfun website.

NRF24L01 wiring with Arduino Nano

Arduino Gateway Program

Next we need to load the mySensors program into the gateway. Using your Arduino IDE copy and past the code below.

// Enable serial gateway and set the baud rate
#define MY_GATEWAY_SERIAL
#define MY_BAUD_RATE 115200

// Enable debug prints to serial monitor
#define MY_DEBUG

// Enable and select radio type attached
#define MY_RADIO_NRF24

//Set the channel frequence
#define MY_RF24_CHANNEL 50

// Set the power level for the radio. This afects how far the wireless signal will travels. 
// Select one of 4 levels RF24_PA_MIN, RF24_PA_LOW, RF24_PA_HIGH, RF24_PA_MAX 
#define MY_RF24_PA_LEVEL RF24_PA_MAX

#include <MySensors.h>

void setup() {}

void presentation() {}

void loop() {}

There is only one executable line of code in this program #include <MySensors.h> which loads the MySensors library. All of the preceding lines configure your gateway parameters as described in the table below. Once you have downloaded the above program into your Arduino open up the Arduino IDE Serial Monitor and you should see the messages below. (Make sure you set the baud rate in the Serial Monitor to ‘115200 baud’ so that it matches the MY_BAUD_RATE parameter in your Arduino program. Don’t worry about what these messages mean for now, we will describe them later.

MY_GATEWAY_SERIAL
MY_BAUD_RATE
By defining MY_GATEWAY_SERIAL we tell the MySensors program that this is a Gateway device that will use the USB conection to communicate with the RaspberryPi.
The baud rate MY_BAUD_RATE parameter is then set to 115200, the communication speed we will use for the USB connection. This needs to match the USB communication speed that we also configure in the RaspberryPi.
MY_DEBUGBy defining MY_DEBUG we will get print out of all system messages to the USB which is helpful for troubleshooting.
MY_RADIO_NRF24
MY_RF24_CHANNEL
MY_RF24_PA_LEVEL
By defining MY_RADIO_NRF24 we tell the mySensors program that we are using a NRF24L01 wireless module.
The following two parameters then configure the module. (See below for a more in depth description of these key parameters)
mySensors Gateway Configuration Parameters

MY_RF24_PA_LEVEL

The NRF24L01 can be configures with 4 different power levels. I typically use the maximum setting RF24_PA_MAX as this gives the furthest communication range between the gateway and the sensors. However this setting requires the highest current to be pulled from the Arduino 3.3V pin when the NRF24L01 is transmitting . Experience shows that reliable wireless communications are only achieved if a 47uF electrolytic capacitor is soldered directly across the 3.3V and ground pins of the NRF24L01. The capacitor ensures the 3.3V supply doesn’t dip when the wireless module temporarily pulls too much current from the Arduino.

MY_RF24_CHANNEL

The NRF24L01 uses the standard 2.4 GHz wireless communications that is used by home wireless routers and networks. This wireless frequency can get heavily congested if you and your neighbors use a lot of wireless devices. To manage this the authorities such as FCC in the USA define a range of frequencies (channels) that your wireless router can be configured to operate on. The howtogeek.com web site has a great article that explains the wireless frequencies and how these relate to how you configure your home wifi router to select one of 13 channel options. It is important to understand this as you want to make sure the frequency you select for your NRF24L01 wirless home automation network will not interfere with other networks.

I would recommend you download an app onto your smartphone that is able to scan the 2.4 GHz channels in your home. Below is a screen shot from an app called NetSpot which I run on my Android phone, the output is shown below.

wireless scanner

Router wifi channels 1 thru 13 are set at increments of 0.005 GHz. However the NRF24L01 can be configured to operate at any frequency from 2.400 to 2.525 by setting the MY_RF24_CHANNEL parameter within the range 0 – 125. The table below shows the relationship. As the scanner shows channel 9 is not being used I set MY_RF24_CHANNEL to 50. Note that its worth running the scanner app several times throughout the day as wifi use is not static.

Wifi ChannelFrequency (GHz)MY_RF24_CHANNEL
12.41212
22.41717
32.42222
42.42727
52.43232
62.43737
72.44242
82.44747
92.45252
102.45757
112.46262
122.46767
132.47272

Rather than writing the #define MY_RF24_CHANNEL 50 statement in your program you can omit this and modify the myConfig.h file instead. myConfig.h sets the default properties for many variables in the MySensor library and the file can be found in your MySensors folder in your Arduino libraries folder. A description of all of these variables is on the MySensors web site. Defining MY_RF24_CHANNEL in the myConfig.h file ensures that not only your gateway but all subsequent sensors that you program use the same channel number. This is important as a gateway can only communicate on one channel and will not be able to see sensors that are configured using a different channel setting.

Step 3: Connecting your Gateway and RaspberryPi

The final step is now to connect your gateway with your RaspberryPi and run your node.js program which will display messages received from the Arduino gateway. Below is a picture of my setup.

gateway connected to raspberrypi

When I run the application with the command node main.js below is the text I see printed on the Pi’s terminal window.

These are system messages being generated when the gateway starts up. The mySensors web site has a page that describes how to interpret these messages https://www.mysensors.org/build/debug. If the messages you get are different from these, with error or fail messages then you will need to do some detective work to figure out what went wrong. From my experiences most of my errors are traced back to the Arduino not communicating properly with the NRF24L01 wireless transceiver. e.g. wired up incorrectly or a faulty NRF24L01 module. Below is an example of the error messages when the 3.3V power cable between the Arduino and the NRF24L01 is disconnected. The mySensors software shows 3 attempts to establish communications withe the NRF24L01 transceiver.

That’s it. You now have the basic components of your wireless automation system setup, but as yet it doesn’t achieve a lot! Next I suggest checking out the ‘Setting up a Basic Sensor” tutorial that will describe how an Arduino sensor sends and receives data with the Pi via the gateway. Further tutorials will add more functionality to your Node.js application e.g. setting up a web server and building HTML graphics to display your sensor data.

Leave a Reply

Your email address will not be published. Required fields are marked *