J Steven Perry | Updated March 29, 2018 - Published March 28, 2018
IoT hardware is great, but without software to bend it to your will, it’s not of much use. In Part 1, I showed you how to set up the IoT hardware for our home automation system. In Part 2, I’ll show you the software that I used to build the home automation system: how it works, how to set it up, build it, and how to run it to control the 433-MHz devices that you set up in Part 1.
When you’re finished with Part 2, you won’t have a complete, working home automation system yet, but you will definitely see it begin to take shape. In short, Part 2 is where the hardware devices from Part 1 meet the software that controls them.
Directories are like spare bedrooms: they are easily cluttered. To prevent this clutter as you work through the rest of this series, create a directory somewhere on your computer, and store all of the code for this tutorial in that directory.
For example, I’ll go to the home directory on my Mac, then create a directory called HomeAutomation, immediately subordinate to the home directory. Then, before I work with the IoT software, I go to that directory, like this:
The HomeAutomation directory will be the root folder for all of the source code that I’ll show you in this tutorial. Unless I tell you otherwise, any unqualified directory references will be relative to the HomeAutomation directory.
In Part 1, you set up your Raspberry Pi and all of your 433-MHz hardware. In Part 2 (this part), you will set up the software components that communicate with the 433-MHz hardware. The software components listed above form a software stack that looks like this:
At the bottom of the software stack is the 433-Mhz hardware that communicates through the Pi’s General-Purpose Input/Output (GPIO) pins to the software that is running on the Pi. At the top of the software stack is the application code, which makes calls into the middle stack, which is made up of these three components (from the bottom up):
I’ll introduce the IoT application code in Part 3, so don’t worry about it for now.
For Part 2, I want to focus on the middle of the stack from , which is composed of the components listed above. I’ll describe each of these components in detail throughout the remainder of this tutorial series.
The purpose of is to show you the overall architecture of the home automation solution that you’ll be building so you can see how the different components fit together as I introduce them here in Part 2.
By the time you’re finished with this part of the tutorial, you will know all about WiringPi, how to build it, and how to run the gpio utility.
You’ll also learn about rc-switch, which 433Utils uses to talk with WiringPi, and how to run 433Utils to talk with the receiver module that you set up in Part 1 to capture encoded signals from 433-MHz remote controls.
Finally, you’ll learn how to control IoT devices that use the 433 MHz band by sending encoded signals — identical to those signals that you captured with the receiver — through the transmitter you set up in Part 1.
WiringPi is a C-language open source library written by Gordon Henderson that is used to access the GPIO pins on the Raspberry Pi.
I’ll show you how to download the source code and build WiringPi on your Raspberry Pi.
WiringPi also includes a command-line utility called gpio that you can use to manipulate the signals to and from the pins on the Pi. I’ll show you how to use gpio later in the tutorial to make a simple LED circuit blink.
To set up WiringPi, you need to download it build it. In the video below, I’ll show you how to download and build both WiringPi and 433Utils.
After you watch the video, make sure to work through the sections that follow to download and build Wiring Pi on your Raspberry Pi.
Open a Terminal on your Pi, go to the ~/HomeAutomation folder, and enter the following command:
git clone git://git.drogon.net/wiringPi
You should see output like this:
$ git clone git://git.drogon.net/wiringPi
Cloning into 'WiringPi'...
remote: Counting objects: 1151, done.
remote: Total 1151 (delta 0), reused 0 (delta 0), pack‑reused 1151
Receiving objects: 100% (1151/1151), 674.92 KiB | 1.63 MiB/s, done.
Resolving deltas: 100% (804/804), done.
Now you have the source code for WiringPi on your computer, and you’re ready to build it from source.
Go to the HomeAutomation/wiringPi directory and run the build:
Actually, WiringPi (and gpio) is included with Raspbian Stretch, so it’s not strictly necessary to build it from source. That said, I enjoy building utilities from source whenever possible because it gives me a sense of freedom and ownership (and it’s fun).
The build is super fast (it takes around 10 – 15 seconds on my Raspberry Pi 3). When it runs, there are a couple of things that happen that you should know about.
A symbolic link is created in /usr/local/bin that links to the gpio program that was just built. Since /usr/local/bin is ahead of /usr/bin in the PATH environment variable (in the Stretch installation on my Pi, anyway), this is the version of the gpio utility that will run if you type gpio at the command line.
Should that matter? Most of the time, probably not. I just wanted you to be aware that WiringPi’s build was doing this.
433Utils is a set of C++ programs that interact with hardware devices that use the 433 MHz band, and ASK/OOK encoding (see Part 1 for a thorough discussion of ASK/OOK).
As you can see from , 433Utils is called by your application to interact with the 433-MHz IoT devices. 433Utils, in turn, calls a lower-level library called rc-switch.
rc-switch calls the WiringPi library, which then communicates with the device through the Pi’s GPIO pins.
WiringPi provides the low-level interface to the Pi, and thus the most control. However, this control comes at a price. The code is not very noob-friendly. rc-switch sits atop WiringPi and makes using it much easier. And, last but not least, 433Utils sits atop rc-switch and allows communication with your 433-MHz devices with just a few function calls.
The ease of use that you enjoy from 433Utils also comes at a price: you don’t have as much control. But this is okay because you need only a few features of WiringPi and using the libraries in this manner provides the simplest possible interface.
Open a Terminal on your Pi, go to the ~/HomeAutomation folder, and enter the following command: git clone
--recursive https://github.com/jstevenperry/433Utils.git. You should see output like this:
$ git clone ‑‑recursive https://github.com/jstevenperry/433Utils.git
Cloning into '433Utils'...
remote: Counting objects: 225, done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 225 (delta 0), reused 1 (delta 0), pack‑reused 223
Receiving objects: 100% (225/225), 46.04 KiB | 799.00 KiB/s, done.
Resolving deltas: 100% (98/98), done.
Submodule 'rc‑switch' (https://github.com/sui77/rc‑switch.git) registered for path 'rc‑switch'
Cloning into '/Users/sperry/home/development/projects/HomeAutomation/433Utils/rc‑switch'...
remote: Counting objects: 663, done.
remote: Total 663 (delta 0), reused 0 (delta 0), pack‑reused 663
Receiving objects: 100% (663/663), 160.83 KiB | 1.59 MiB/s, done.
Resolving deltas: 100% (354/354), done.
Submodule path 'rc‑switch': checked out 'a9da9c36820b02fc5613dfe2437e1187bcf5b402'
433Utils includes utilities for other single board computer systems like Arduino, in addition to the Raspberry Pi. In this tutorial, you will work with only the Raspberry Pi utilities, which are located in the RPi_utils directory.
Now that you have the source code for 433Utils and rc-switch on your computer, you’re ready to build 433Utils from source.
Go to the 433Utils/RPi_utils directory and run the make command. The output looks like this:
g++ ‑DRPI ‑c ‑o ../rc‑switch/RCSwitch.o ../rc‑switch/RCSwitch.cpp
g++ ‑DRPI ‑c ‑o send.o send.cpp
g++ ‑DRPI ../rc‑switch/RCSwitch.o send.o ‑o send ‑lwiringPi
g++ ‑DRPI ‑c ‑o codesend.o codesend.cpp
g++ ‑DRPI ../rc‑switch/RCSwitch.o codesend.o ‑o codesend ‑lwiringPi
g++ ‑DRPI ‑c ‑o RFSniffer.o RFSniffer.cpp
g++ ‑DRPI ../rc‑switch/RCSwitch.o RFSniffer.o ‑o RFSniffer ‑lwiringPi
The make utility runs the GNU C++ compiler (g++) and builds three programs: send, codesend, and RFSniffer. You will use only the last two in this tutorial.
The build takes only a few seconds, and when it’s finished, you’re ready to run the RFSniffer program.
An entire tutorial series could be dedicated to the gpio utility. It does so many different things that I cannot come close to describing it in the limited space I have here. Instead, check out this page written by the author himself. Also, make sure to read the manpage (type man gpio at the command line of your Pi).
In this tutorial, I just want to introduce you to the gpio utility and get you used to running it when you’re working with software that you’re writing for, and running on, the Pi. To do that, I’ll show you two options, which you supply as arguments to the gpio program when you run it from the command line:
The first argument —readall— tells gpio to read all of the GPIO pins and report their state. The output looks like this:
$ gpio readall
| BCM | wPi | Name | Mode | V | Physical | V | Mode | Name | wPi | BCM |
| | | 3.3v | | | 1 || 2 | | | 5v | | |
| 2 | 8 | SDA.1 | IN | 1 | 3 || 4 | | | 5v | | |
| 3 | 9 | SCL.1 | IN | 1 | 5 || 6 | | | 0v | | |
| 4 | 7 | GPIO. 7 | IN | 1 | 7 || 8 | 0 | IN | TxD | 15 | 14 |
| | | 0v | | | 9 || 10 | 1 | IN | RxD | 16 | 15 |
| 17 | 0 | GPIO. 0 | IN | 0 | 11 || 12 | 0 | IN | GPIO. 1 | 1 | 18 |
| 27 | 2 | GPIO. 2 | IN | 0 | 13 || 14 | | | 0v | | |
| 22 | 3 | GPIO. 3 | IN | 0 | 15 || 16 | 0 | IN | GPIO. 4 | 4 | 23 |
| | | 3.3v | | | 17 || 18 | 0 | IN | GPIO. 5 | 5 | 24 |
| 10 | 12 | MOSI | IN | 0 | 19 || 20 | | | 0v | | |
| 9 | 13 | MISO | IN | 0 | 21 || 22 | 0 | IN | GPIO. 6 | 6 | 25 |
| 11 | 14 | SCLK | IN | 0 | 23 || 24 | 1 | IN | CE0 | 10 | 8 |
| | | 0v | | | 25 || 26 | 1 | IN | CE1 | 11 | 7 |
| 0 | 30 | SDA.0 | IN | 1 | 27 || 28 | 1 | IN | SCL.0 | 31 | 1 |
| 5 | 21 | GPIO.21 | IN | 1 | 29 || 30 | | | 0v | | |
| 6 | 22 | GPIO.22 | IN | 1 | 31 || 32 | 0 | IN | GPIO.26 | 26 | 12 |
| 13 | 23 | GPIO.23 | IN | 0 | 33 || 34 | | | 0v | | |
| 19 | 24 | GPIO.24 | IN | 0 | 35 || 36 | 0 | IN | GPIO.27 | 27 | 16 |
| 26 | 25 | GPIO.25 | IN | 0 | 37 || 38 | 0 | IN | GPIO.28 | 28 | 20 |
| | | 0v | | | 39 || 40 | 0 | IN | GPIO.29 | 29 | 21 |
| BCM | wPi | Name | Mode | V | Physical | V | Mode | Name | wPi | BCM |
There is a lot going on here, and I won’t be able to cover it all, so I’ll hit the high points. Notice the headings, starting in the upper left corner.
BCM corresponds to the pin number on the internal pin number on the Broadcomm BCM2837 SoC (system-on-a-chip). By the way, the BCM pin is also the pin as marked on the expansion board you set up in Part 1.
wPi refers to the WiringPi pin number and is the pin number that you’ll reference in all of the software that uses WiringPi for this project, and it also corresponds to the GPIO pin number.
Name is just a helpful description. For example, “5v” indicates that pin provides +5V output, “0V” is ground, and “GPIO.21” indicates that the pin is GPIO pin number 21.
Mode indicates whether the pin is currently set to receive input (IN) from outside the Pi or to send output (OUT) from the Pi to the outside.
V tells you whether the pin is High (1) or Low (0).
Physical refers to the actual physical pin that you see when you look at the Pi’s GPIO header pins. The physical numbering starts at 1 with the pin closest to the micro SD slot. Odd-numbered pins are on the same 20-pin header row (ditto for even-numbered pins). Pin 40 is near the USB ports and on the opposite header row as pin 1.
Got all that? If you’re new to the Raspberry Pi, it might take a little while to get comfortable with these concepts. In addition to Gordon’s great gpio reference, and the gpio manpage, check out this simple guide to Raspberry Pi 3’s pin layout or this Wikipedia article.
For now, just follow along with me, and I’ll walk you through it. I’ve got you covered, don’t worry!
Remember the LED circuit from the video in Part 1? I’m going to show you how to wire it to the Pi and use the gpio blink command to make the LED blink. below shows the breadboarded circuit that I’ll demonstrate.
If you feel confident in your breadboarding skills, feel free to follow along with me.
The only difference between this circuit and the one from the video in Part 1 is that the circuit is powered from BCM pin #25 instead of the positive rail.
I’m going to supply gpio with the blink argument, which alternates between HI (1) and LO (0), which makes the LED turn on (1) and off (0). blink also takes an argument, which is the GPIO pin number to blink on and off.
Open two Terminal windows on the Pi (or two separate SSH sessions). In one, enter this command:
gpio blink 6
This command tells gpio to blink wiringPi (wPi) pin 6 (BCM #25) on and off. The interval is around 1 second per cycle (1/2 second ON, 1/2 second OFF, and so forth), and it will repeat until I press Ctrl+c.
In the other Terminal window, run this command:
watch ‑n 0.5 'gpio readall'
This command will execute the gpio readall command every 0.5 seconds and display the output, which will let you see the Mode switch to OUT and the V go from 0 – 1 and back again after you run the gpio blink command.
If you have followed along and the LED is ON when you pressed Ctrl+c, type gpio toggle 6, and it will toggle wPi pin 6 from ON to OFF (and vice versa).
gpio toggle 6
How cool is that? Trust me, gpio is a very handy utility!
To stop it, I’ll type Ctrl+c in the window where the gpio blink command is running to stop the program.
Check out this video, where I take you on a tour of the gpio utility.
RFSniffer lets you capture the signals that are sent by the RF Outlet’s remote control. The sequence goes like this:
First, start the RFSniffer program in a Terminal window. The program displays a startup sequence that tells you that it has started and entered its “sniffing” loop:
pi@raspberrypi:~/HomeAutomation/433Utils/RPi_utils $ ./RFSniffer
Starting sniffer loop...
Now press the remote control’s “on” button. The remote will send a signal, which is captured by RFSniffer, and displayed in the Terminal window. Then, press the “off” button to capture that signal. The output looks like this:
pi@raspberrypi:~/HomeAutomation/433Utils/RPi_utils $ ./RFSniffer
Starting sniffer loop...
First, check your connections to make sure that you’re using the right holes on the breadboard (I speak from experience). If that doesn’t work, swap out receiver modules. These parts are generally well-made, but still cheap, and occasionally you will get a bad one (which is why I recommended in Part 1 that you get the 6 pack).
It’s also possible (albeit unlikely) that there is a bad socket on your breadboard. Move jumper wires one at-a-time to different sockets to see whether that corrects the problem. Make sure that you’ve connected the 5V and GND jumper wires from the Pi to the breadboard rails, and that the rails are connected properly to each other. Failing that, get out your multimeter and verify that power is making it to the Vcc pin on the receiver module.
Wait. I pressed the “on” button, then the “off” button. I would expect only two lines of output, right?
Not exactly. A couple of different things might be happening. First, 433-MHz devices (and in particular ASK encoding) are notoriously noisy, so lots of remote controls will send the same signal multiple times, even though I only pressed the button once (and quickly). Another possibility is that what I think of as “quickly” in machine time is a very long time indeed, so I might have held the remote button a bit long, which caused the transmitter inside the remote to send the signal multiple times.
At any rate, notice that there are only two unique Value numbers: 1119539 and 1119548, which correspond to on and off, respectively, and they are the decimal representations of the binary encoded values.
The second number is the delay (in microseconds) between on and off values (pulses), as well as the length of a pulse, called the pulse length. As you can see, in one case the delay is 173 and the other cases it is 174. Hardware timings are very precise, so the value shown might not always be exactly the same, but for any particular remote, the values will be very close. Just pick one and stick with it. I’ll use 174 microseconds as the delay for the transmitter demo in the next section.
Write both sets of numbers down that you get from RFSniffer (they will be different for your RF outlets) because you’re going to need them in the next section.
The last number is the length (in bits) of the encoded signal, 24 in this case. As I said, the Value shown above is the decimal representation of the 24-bit binary value sent by the remote, which is 00010001010100110011, and 00010001010100111100, respectively.
One of the programs that was built when you ran make in the 433Utils/RPi_utils directory earlier is called codesend, and it is used to send encoded signals through the 433-MHz transmitter module.
Now that you’ve captured the encoding for your RF outlet, you can use codesend to instruct the transmitter module to send that code to the outlet.
Plug the RF outlet into a wall socket, and plug a device (such as a lamp or radio) into the outlet to give you immediate visual or auditory feedback when the outlet goes from on to off, and vice versa.
Go to a Terminal window on the Pi and run the codesend program. It takes two arguments:
To instruct my RF outlet to turn on and then off, I’ll run codesend like this:
pi@raspberrypi:~/HomeAutomation/433Utils/RPi_utils $ ./codesend 1119539 174
sending code1119539 pi@raspberrypi:~/HomeAutomation/433Utils/RPi_utils $ ./codesend 1119548 174
sending code1119548 pi@raspberrypi:~/HomeAutomation/433Utils/RPi_utils $
And voila! The device plugged into the RF outlet turns on and off. In my case, that’s a lamp.
That’s a lot to absorb. How about a video? In the video below, I’ll show you everything that I just described. So press play and enjoy!
In this part, you learned how to set up and build the system software that controls the IoT hardware that you set up in Part 1.
Don’t stop now! Jump on in to Part 3, where you write the IoT apps that make your home automation system complete!
April 11, 2019
March 19, 2019
June 14, 2019
Back to top