Building Wireless Low Power Sensors for Raspberry Pi Home Automation

Intro

I always wanted to build some kind of home automation system. Especially collecting data from various sensors and graphing that data soothes the inner nerd. But most of the commercial systems you can buy were always lacking some feature and/or are mind bogglingly expensive. Plus, if you don’t have to break out the soldering iron, where is the fun in that?
For a start, I thought about a few wireless temperature and humidity sensors. Of course the obligatory raspberry pi should be used to collect that data, store and present it somehow. The usual approach here is having a home automation controller software on the pi that is interfacing with the sensors and actuators around the house using some kind of wireless transport. Therefore the sensors being wireless and battery powered need to be very low power, so I won’t have to change batteries all the time. To prevent people from running into the same problems as I did, I documented the project as a starting point for anyone interested in getting started quickly.

So here is a short summary of what I put together:

Hardware

  • A bunch of Arduino Pro Mini clones. The 3.3V version
  • DHT22 temperature and humidity sensors
  • NRF24l01+ 2.4 GHz Transceivers

Software

  • MySensors: A library specifically designed to run sensor nodes using the NRF24101 transceivers.
  • Pimatic: A home automation software package for the raspberry pi. It features tons of plugins for all the extensions you can think of and of course, offers a plugin to communicate with a mysensors serial gateway.

Before diving in, just a bit of vocabulary: When talking about Nodes, the sensors transmitting their measurements are meant. Nodes transmit their data to a Gateway. It collects the data from all sensors around the house and provides it to a Controller (via serial, ethernet, or MQTT, etc.). The controller (a.k.a. the raspberry pi) usually runs some sort of home automation software to collect the data, and issues commands to actuator nodes via the gateway. So if i.e. your zombie sensor measures increased zombie density in your garden, the information is sent to the gateway, picked up by the controller and a rule on it could send a command back to nodes controlling the door locks, telling them to lock (as if that would save you).

MySensors

Building the Sensors

The sensor nodes comprise a 3.3V Arduino Pro Mini Clone, the DHT22 sensor and of course the NRF24101+ transceiver module. Connecting the radio to the transceiver is explained in the build section. You can leave the IRQ Pin (Pin 2) out, as it is currently not used. Some sketches even use Pin 2 for sensors. The example code for the node can be found here. This is from a newly created repo, where examples were moved that required external libraries. Since the DHT library used in this sketch is modified, make sure to also download the DHT library from the same repo.

Using the MySensors library these nodes will try to communicate with a gateway node. The gateway manages the sensor and actuator nodes. For example, if a node first enters the network it is assigned a node id from the gateway. In case of the temperature sensors it also sends a set of config parameters to the nodes, indicating, wheter they should send their readings in F or C.

There are many interface options available for the gateway, but since the serial gateway is the one that is supported by most controller software and the only one supported by pimatic, I chose it over the others.
The gateway is a very simple sketch that you also don’t have to write yourself. It can be found in the example repository as well.

img_2019
Breadboard prototype of a sensor node. This will later be replaced with a pro mini and be much smaller

The current version of MySensors is 2.0.0, which was just recently released. If you plan to use one of the examples, don’t get them from the website, as these are still for version 1.5.x. Get the example code from the github repo of MySensors directly, as they are already converted to 2.0.0. Some of the examples use modified versions of sensor libraries (like the DHT library). Make sure to also download them as well.

Testing Communication

All nodes can put out debug info via the serial interface. The serial gateway has to do this by default, as this is the output the controller parses to get the data. If you used the example sensor sketch it should be enabled as well, otherwise simply add a #define MY_DEBUG to your file.

If you run into any problems, check the troubleshooting guide. Most problems with radio communication can be fixed by placing a capacitor of at least 47µF between the transceivers power supply pins.

If range is an issue for you, you can also set up repeater nodes. There are also NRF24101+ modules with a proper 2.4 GHz antenna mounted on the board. They can be driven with a higher amplifier setting.

Low Power Optimization

The ultimate goal was not to run the test contraption depicted above but have a Pro Mini board powered by 2 AA batteries. They are available in 3.3 and 5V versions. By clocking down the MCU, the 3.3V version can be used down to 1.8V without the need for a regulator.

maxfrequency
The Pro Mini 3.3V version comes clocked at 8Mhz. Lowering the clock speed to 1Mhz will allow to drive the board with 1.8V min and reduce power consumption even further. To do that you need to burn some fuses on the mcu.

avrdude -c usbtiny -p m328p -U lfuse:w:0x62:m    # switch to 1Mhz internal oscillator
avrdude -c usbtiny -p m328p -U efuse:w:0x07:m    # disable brown-out protection

Another big impact on power consumption is caused by the on board regulator and the led. Running a sensor node for a year without a battery change is only possible because it is sleeping most of the time. The regulator on the pro mini board draws about 2-3 mAh when idle. There are special micropower regulators that have quiescent currents down to 2µA, but since the board is directly powered by the batteries, a regulator is not needed. At least for the MCU itself.

img_2027
Before desoldering Power LED and regulator
img_2028
After desoldering LED and regulator

I measured the current draw before the modifications and afterwards.

Before After
8MHz (MCU only) 6.20 mAh 4.30 mAh
1 MHz (MCU only) 2.40 mAh 0.80 mAh

This shows a significant improvement. Lets see how far I can get with just 2 AA batteries.

However, not all components can work with the low voltage of 2 AA batteries. The DHT22 temperature and humidty sensor requires at least 3.3V to work. An external regulator was needed. I found a couple of chinese no name 3.3V boost converters for voltages down to ~0.9V. Of course they didn’t have a datasheet, so I didn’t know, what their quiescent current draw would be. Luckily these sport an enable input, so they can be switched off and are only turned on for a few seconds prior to the sensor reading, so the DHT22 can settle (It needs at least 2s before polling the one-wire bus).

A word on logic levels: Since the microcontroller and the radio are powered by the batteries directly, their logic levels match. However, the DHT22 needs at least 3.3V, so a logic level conversion is needed. Hooking everything up to the boost converter is another option, meaning everything would be on a proper 3.3V level. But since you can’t turn the converter off in this configuration, the idle current draw of the device would just be too high.

img_2024
Cheapo 3.3V boost converters

Assemble Everything

Putting everything together, this is the simple block diagram of a sensor node:

dhtsensor
For the logic level convesion, a simple FET based level shifter is used, e.G. using the BSS138 MOSFETs. It converts the DHT22 one-wire bus to the lower logic level of the microcontroller and vice versa. Plus, the pin usually needs a pullup resistor anyway which the shifter provides by design. This Phillips application note explains level shifting using FETs pretty well. Also it is used for pulling the enable pin of the boost converter low. It’s usually pulled up to 3.3V by the converter, again, bad level for the battery powered MCU. When this pin is pulled low, the unit switches off.

Such a simple shifter won’t be able to handle high speed i²c connections, but is able to cope with the one-wire bus transmissions just fine.

Security

If your neighbor happens to also use MySensors, you can change the channel configuration by adding #define BASE_RADIO_ID ((uint64_t)0xA8A8E1FC00LL) to your code, so the two networks don’t interfere with each other.

But what if someone would try to control your actuators? First of all, commands need to be authenticated, i.e. the messages need to be signed, like in any other application that needs authenticity and integrity. This prevents an attacker from forging commands (integrity). Using a pre-shared key to compute the hashes will provide authenticity.

But there is always the risk of replay attacks: Recording the command to open your door lock and replaying it later. This can be mitigated by using a random nonce as a challenge requested from the node you want to transmit to and incorporating it into your hash. Even messages with the same content will have a different signature now, thus preventing replay attacks.

MySensors implemented this and works with a single pre shared key that you flash onto all of your nodes. Alternatively it is written to an external authentication chip, the ATSHA204A, a simple 3 pin chip (VCC, GND and SDA) providing eeprom storage for keys and an implementation of sha256 in hardware, which keeps the used flash on the MCU down.

The only thing not implemented is encryption of the air interface. Sensor values and commands could be sniffed. By using signed messages it is however unlikely that an attacker can forge a command. The only possible attack (as the network is unencrypted) is that an attacker could sniff the message sent back with the nonce incorporated and somehow block the receiving node from getting that message. In theory this would allow an attacker to replay that command at a later point in time. However, the MySensors implementation mitigates this by timing the nonces. If a node that issued the nonce didn’t receive an answer in a certain amount of time, that nonce is invalidated.

This was just a quick summary. Yes, there is security and it is probably better than everything you’d expect from some commercially availbale sensors. Here is an excellent writeup that people without any knowledge in security should be able to understand. Here they also make the point against including encryption of the air interface in MySensors: Proper encryption is hard to get right, and the controllers used have very limited flash capacity to deal with it. Rather, the transceiver chips should handle this. There are even a few out now that do exactly that. IMO, signing the messages is probably enough for now. However, the MySensors website could emphasize the importance of the security features in the documentation more and suggest radios with built-in encryption features.

Just be sure to at least include message signing if you plan on using these nodes to control your garage door opener.

I ordered a few ATSHA204A, but for now my network runs unsigned messages. As I only use sensors its not much of a concern. Also I’m running out of flash space on the Pro Mini boards, so using the ATSHA software implementation is not an option.

Raspberry Setup

The Raspberry Pi is the Controller in my setup. In order to gather the data from the sensor network I used a serial bridge in MySensors terms, which is basically just another node in the network that acts as a gateway. The serial output of the node you usually use to debug your sensors contains the sensor readings from the network. If hooked up to the Pi’s serial GPIO Pins that stream can simply be accessed via a serial device for further processing.

The serial Port on the current Raspberry Pi 3 is on Pins 8/10. With the current Raspbian you have to first add enable_uart=1 to the cmdline in /boot/config.txt. After a reboot /dev/ttyS0 becomes available. You need to disable getty on /dev/ttyS0 using systemctl mask serial-getty@ttyAMA0.service. Otherwise, it will interfere with communication between your gateway and the Pi.
When set up properly, the serial interface can be checked for data using terminal software such as picocom or minicom (seriously, use picocom).

Since the Raspberry’s IO pins operate at 3.3V the gateway can be hooked up directly. If you were to use a 5V Arduino board, you would need to build a level shifter circuit between the two.

Pimatic Installation and Configuration

Pimatic ist the Home Automation server of choice if you need lots of interfaces. There are plugins for nearly every possible sensor/actuator system. Even Apples Homekit is supported via a plugin.

There is an easy to follow installation manual on their website. Its basically install and go. With one exception: The current Raspbian does not ship with node 4 out of the box. After installing it is located in /usr/local/bin and the init script of pimatic needs to be changed:

# /etc/init.d/pimatic

PATH=/usr/local/bin

if [ "$1" = "start" ] || [ "$1" = "stop" ] || [ "$1" = "restart" ] || [ "$1" = "status" ]
 then
 pimatic.js $1
 exit "$?"
 else
 echo "Usage: service pimatic {start|stop|status|restart}" >&2
 exit 3
 fi

 

To connect the serial gateway attached to the pi to the pimatic installation you need to install the mysensors plugin. Just follow the install directions from the github repo page. One last thing to note: The sensor starting id and the given id of the sensor in the plugin configuration need to match, otherwise the sensor data will just be ignored.