We've talked about the relative merits of Arduino and Raspberry Pi before - they each have their strengths. They needn't be an either or choice though - combine them to get the best of both worlds. Home automation is the perfect candidate for this. The home automation market is flooded with expensive consumer systems, incompatible with one another and costly to install. If you have a Raspberry Pi and an Arduino, you can basically achieve the same thing at a fraction of the price, assuming you're willing to put in the time and the effort.

Update: Since this article was written, I've discovered OpenHAB, a free and open source home automation platform that runs on Raspberry Pi and can be integrated with a huge range of off-the-shelf smart home kit as well as Arduino. Check out the video below for a sneak peak, then head on over to our Getting Started with OpenHAB on Raspberry Pi guide to learn more. 

Heimcontrol.js is a Node.js app built to run on Raspberry Pi. Combined with an Arduino and some off-the-shelf remote control sockets, it makes controlling AC appliances easy. You can add temperature sensors, and even control your TV - but we'll be keeping things basic today and extending the project in a later tutorial.

Here's a breakdown of the project:

  • The Raspberry Pi will act as the brains and the gateway of operations - it will run a Node app, tied to a Mongo database, and serve the front-end interface to any web browser.
  • An Arduino, powered from the Pi, will interface between the electronics - radio control power switches, for now.

To do this, you will need:

  • Arduino and a Raspberry Pi
  • Some remote controlled sockets and controller (I used these)
  • Powered USB hub
RC-sockets

Before we begin, here's a demo video from the project creator himself.

Start Afresh

We're going to use Raspian for this project, and I'd strongly suggest starting from a fresh install if you've previously performed other hacks and such. Download the latest Raspian image, copy it to your SD card, and be sure to expand the filesystem and enable SSH. The rest of this guide will assume you've done so, and are connecting over SSH using the default user.

If you haven't done this before, this video explains the process of preparing your SD card in OS X:

And this one for Windows users:

Preparation

The installation process is quite laborious, and derived from the instructions here. Unfortunately, these were outdated or not designed for Raspian, so I've adjusted them heavily below. The codes below can mostly be pasted in blocks - you needn't paste one by one. Since we're compiling a few things on the Pi itself, be warned that this entire process will take a long time. I would say go make yourself a cup of tea - but when I say a "long time", I mean the best part of a day - so 178 cups would be more appropriate.

All commands should be typed into the Terminal, and you may need to press Enter at some points. These first few commands will update the system and install pre-requisites:

        sudo apt-get update 
sudo apt-get upgrade
sudo apt-get install git-core git scons build-essential scons libpcre++-dev xulrunner-dev libboost-dev libboost-program-options-dev libboost-thread-dev libboost-filesystem-dev

Next we need to install Node:

        sudo mkdir /opt/node
wget http://nodejs.org/dist/v0.10.2/node-v0.10.2-linux-arm-pi.tar.gz
tar xvzf node-v0.10.2-linux-arm-pi.tar.gz
sudo cp -r node-v0.10.2-linux-arm-pi/* /opt/node
sudo ln -s /opt/node/bin/node /usr/local/bin/node
sudo ln -s /opt/node/bin/npm /usr/local/bin/npm

Add a PATH variable to your profile so that the OS knows where Node is located. Use the nano text editor as follows:

        sudo nano /etc/profile

Locate the line that says export PATH and replace it with:

        NODE_JS_HOME="/opt/node"
PATH="$PATH:$NODE_JS_HOME/bin"
export PATH

Hit Ctrl-X to exit, and Y to save.

You may need to log out and in again for the path changes to take effect, but you can test with the command:

        which node

If you don't get any output pointing to the Node binary, something went wrong.

Mongo

The next job is to install Mongo. Mongo is a document-based No-SQL database increasingly used by web apps. Unfortunately, this will take forever to install as we have to compile it. While running the following commands you'll get a lot of errors like:

        {standard input}:13085: Warning: swp{b} use is deprecated for this architecture

Don't worry about these. So, run these commands to install Mongo:

        git clone git://github.com/RickP/mongopi.git
cd mongopi
scons
sudo scons --prefix=/opt/mongo install
scons -c

When that's finished, we need a little more setup first to fix permission issues and make sure it's running on startup.

        sudo useradd mongodb
sudo mkdir /data/dbb
sudo chown $USER /data/db
cd /etc/init.d
sudo wget -O mongodb https://gist.github.com/ni-c/fd4df404bda6e87fb718/raw/36d45897cd943fbd6d071c096eb4b71b37d0fcbb/mongodb.sh
sudo chmod +x mongodb
sudo update-rc.d mongodb defaults
mongod

This last command will launch the Mongo server, and you'll need to open a new Terminal to continue with the other commands. I'm not entirely confident of this step, so if anyone can correct this in the comments on how to have mongod launching automatically on start up, it would be much appreciated. For now, it works, just not elegantly.

        sudo shutdown -r now
    

Finally, it's time to install the Heimcontrol.js Node application.

        cd ~pi
git clone git://github.com/ni-c/heimcontrol.js.git
cd heimcontrol.js
npm install

You can start running the app by typing

        
node heimcontrol.js

At this point, you should be able to access the control interface with http://localhost:8080 from the Pi, or replace localhost with the IP address if you're accessing it from a different computer (and you could also set up port forwarding to access it from anywhere in the world), so I'd encourage you to poke around and check all is working with the database before attaching the Arduino.

Hardware

Eventually I'd like a hardwired relay, but for now I'll be using the safer option of radio-controlled switches.

I've used some reasonably cheap £20 sets from Maplin which come with 3 sockets, and opened up the remote control so I could interface directly with the 433 MHz chip inside. I found the instructions for this here.

rc-controller-hack

You can also purchase individual 433 MHz transmitters ready for use on eBay or from hobby electronics suppliers. All you need to is connect the VCC to 5 V on the Arduino, the GNDs, and a single control pin - remember which one you used. (Schematic by Willi Thiel)

arduino-rcswitch

The plugin works by sending "tristate codes", but these will vary by manufacturer. Refer to the RCSwitch documentation to find your exact codes. This wiki guide may help also.

Communication with the Arduino is done using a Node library called duino. Stop the Heimcontrol app if it's running and install the Arduino bridge using the following command.

        npm install duino

The Arduino must have this code uploaded - I suggest you copy and paste to install this from a different computer. It's essentially a listener program that responds to serial commands from the Pi, but there's nothing to stop you extending it with your own features.

rc-settings

With the web app launched, go to the Settings menu > Arduino.

heimcontrol-menu-settings

From there you can add a new item, choosing RCSwitch method, the pin of your transmitter, and the tristate address code. Remember to save, then head back to the main screen screen for your new button.

rcswitch-setting

Bugs:

After many hours of debugging the code, I found single digit pin numbers weren't working - make sure your transmitter is placed on pin 10 to be sure.

I also found that the Arduino plugin was hardcoded with incorrect final bits for the tristate codes my receivers needed. A little explanation first: tristate codes consist of 3 bytes of information. The first determines us the network number (1-4), and the second provides the transceiver address (again, 1-4, producing a maximum of 16 addressable sockets). The final byte consists of two bits of padding, plus 2 bits for on/off. Unfortunately, the final byte is hardcoded in to the Arduino plugin - and in my case, the on/off code was incorrect.

I had to manually edit the plugins/arduino/index.js to use the correct codes. If you're using the same remote control sockets as I am, change lines 80 onwards to:

        // Send RC code
if (item.value) {
  return that.pins[item.pin].triState(item.code + "FFFF");//change from FF0F
} else {
  return that.pins[item.pin].triState(item.code + "FFF0");//change from FF00
}

Here's a demo video of everything working:

I'm going to leave it here at this point, but sensor readings and IR remotes are also supported. I'll probably revisit these at a later date with some more enhancements. If this has all been a little too complex for you, perhaps check out these beginner-friendly Arduino projects.