RPIWeather: Adding off-the-shelf wireless sensors

So, the last couple of years I have been developing and using my own home-built wireless thermometer/hygrometer system called RPIWeather (which is open source). Then the other day I discovered that the previous owners of our house (my in-laws) had left a few items outside. To be more precise, they left a couple of wireless thermometer sensors from old weather stations. The weather stations are long gone by now and, needless to say, the batteries were quite dead. But that doesn’t mean the devices themselves don’t work. Hmm.. It might even be possible to add these into my own system. I always like a good challenge…

Let’s have a look…

Three wireless thermometers

Three wireless thermometers

The devices all looked a bit gnarly, but after a bit of clean-up I powered them on one by one and had a look using my RTL-SDR receiver. All three devices worked and transmitted on 433MHz. Yay! But as my RPIWeather base station only supported the nRF24L01 2.4GHz transceivers, I had to make and add a new 433MHz receiver to it.

Setting up a prototype receiver

At first I toyed with the idea of simply adding an RTL USB-dongle to my Raspberry Pi and simply use GNU Radio (or some other SDR framework) to receive the signals. But that seemed a bit overkill. And I’m not even sure a first generation Raspberry Pi is powerful enough for this to work properly. Fortunately, the usual Chinese Ebay sellers offer a few different generic 433MHZ ASK/OOK receiver modules.

RXB12

RXB12

I ended up choosing one called RXB12 which features a Synoxo SYN470R IC. It’s reasonably sensitive across the 433MHz spectrum, but doesn’t offer any I/O besides a continuous stream of binary data (which is just random noise most of the time).

The rest of the prototype was an Arduino Uno, but any old Arduino will do.

The protocols

In parallel with my prototype Arduino setup, I also hooked up my logic analyzer (a cheap Cypress-based Saleae Logic clone) to eavesdrop on the serial data stream from the radio chip.

OBH

OBH unit

OBH unit

The protocol appears to be the one known as “Oregon Scientific V1”, which is a somewhat old protocol exclusively used for temperature-only sensors.

Signal sample

Signal sample

Europe Supplies Ltd. TX3

TX3 unit

TX3 unit

Once you realize that this is identical to a LaCrosse TX3, you are done. This is a very popular sensor and its protocol is quite well known. It is unfortunately not the TX3-TH variety that also reports relative humidity, but at this price (free) I’ll take it.

Signal Sample

Signal Sample

Unbranded unit

Unbranded unit

Unbranded unit

The protocol used by this unit is a bit different. At first glance it looks like identical short bursts until one looks at the intervals between the bursts. Short intervals mean 0 and long intervals mean 1. The unit sends 36 bits 7 times. My Google-fu didn’t find a lot of information about this one, but apparently the protocol seems to be very similar to the ones used by other unbranded china-devices. The so-called checksum used by this device is somewhere between useless and batshit insane.. Have a look in the code for the dirty details.

Signal sample

Signal sample

Bonus: Weber Style wireless BBQ thermometer (Model AW129)

Weber AW129

Weber AW129

Interestingly enough, this is just a rebranded Oregon Scientific unit that (unsurprisingly) uses the so-called “Oregon Scientific V2” protocol. To ensure data integrity, the signal is sent twice and each instance includes both a nibble checksum and a byte CRC8.

Signal sample

Signal sample

Having a wireless BBQ thermometer with data logging is actually very useful when doing slow-food like pulled pork where the smoker has to be monitored regularly over a period of several hours. It’s suddenly very easy to pick up on small changes in the rate of temperature increase inside the meat. This enables very fine-grained control of the air vents in the smoker as well as an indication if more coal or water is needed. Finally, it allows me to accurately predict several hours in advance when the meat will be done.

Pulled pork

Pulled pork

I have no idea why a relatively nice wireless thermometer like this one is shipped with such a crappy receiver. Main problems include:

  • There is no way of setting user-defined temperature alarms. The unit is shipped with a small number of factory presets depending on the type of meat and doneness, but the selection is extremely limited.
  • The transmitter sends quite accurate readings with a resolution of 0.1 degrees Celcius, but the receiver unit just rounds this number to the nearest integer. This may be OK for most use-cases, but it’s very annoying for me when I want to keep a close watch on things.
  • Sound alarms cannot be changed/muted.

But at least I’m happy that I can make my own receiver this way. 🙂

Porting to the ATtiny84 and adding 433MHz capability to RPIWeather

I had a few DIP ATtiny84s left over from the prototype phase of my own sensor nodes. Using one of these I was able to make a sufficiently compact module that listens for these known data packets on 433MHz and then forwards them to my Raspberry Pi using its internal UART RX pin. For this to work, I had to stop Linux from using the internal UART pins for a serial console interface. But it was a small price to pay, I think.

433MHz receiver

433MHz receiver

Originally, RPIWeather was designed exclusively with my own sensor nodes in mind. It actually triggered a bit of much needed refactoring to add this new capability to the code. Now the script starts a thread for the InfluxDB sender as well as a thread for each data source. These threads run totally independently and are only communicating through a concurrent queue object. At this point in time, RPIWeather supports three data sources which are connected to the Raspberry Pi in three different ways:

  1. My own 2.4GHz sensor nodes. The receiver is connected to the internal SPI pins.
  2. The above-mentioned 433MHz thermometer sensors. The receiver is connected to the internal UART RX pin.
  3. A Bosch BMP180 barometric sensor for measuring atmospheric pressure. It is connected to the internal I2C pins.

Show me the code!

All code and schematics can, as usual, be found on GitHub.

Happy Hacking! 🙂

RPIWeather: My wireless monitoring system

Some of the first posts on this blog were about how to interact with the famous nRF24L01 2.4GHz radio chipset from both an Arduino and a Raspberry Pi. Well.. Much have happened in the mean time, but at least I have managed to put together something using what I learned back then. I decided to make a wireless monitoring system for environmental data in and around our house with at least one sensor node in each room as well as a couple of sensors outside. It is called RPIWeather and you can get all the code and documentation by clicking the name. This post is just meant as a short summary.

RPIWeather consists of a bunch of wireless sensor nodes, a base station that collects the data packets, a database server, and one or more frontends. My goal has been to collect data at 5 minute intervals and keep it indefinitely for analysis, comparison, and visualization. This creates some demands for power efficiency and reliability, which I find interesting.

The sensor nodes

My first prototype was based around an Arduino and some proto-board and is described here, here, and here. It looked like this:

Arduino with nRF24L01 and DHT22

Arduino with nRF24L01 and DHT22

To keep things simple, clean, and small, I decided to ditch the Arduino platform and code in straight avr-libc for the ATtiny84 chip from Atmel. So I made another prototype, but this time with an ATtiny84 instead.

Partial prototype without the DHT22 sensor

Partial prototype without the DHT22 sensor

Little by little a schematic emerged. Besides the radio, the sensor and the MCU, I also needed some sort of power supply. As the sensor nodes are to be distributed throughout the house, this implied battery power, but it couldn’t just be any old battery. The thing is that the radio chip can only tolerate up to 3.6v and the DHT22 sensor can only operate down to ~3v, which leaves a narrow band of usable voltages. A traditional voltage regulator would have burned though the batteries quite quickly, so I had to put in a switching boost converter. This way 2 AA NiMH batteries can deliver a reasonably stable 3.3v supply voltage for the circuit. Pro tip: when buying NiMH batteries, do yourself a favor and use the low self-discharge kind like Eneloop. In this use-case they will go for several months between charges.

Schematic for the sensor nodes

Schematic for the sensor nodes

With the schematic in place, I made a PCB layout and sent it to ITEAD for manufacturing. Here are a couple of pictures showing various stages of assembly. The funny shape of the boards was needed to make them fit snugly into some cool boxes from New Age Enclosures.

Sensor node PCBs

Sensor node PCBs

The first 10 finished boards

The first 10 finished boards

Inside a single sensor node

Inside a single sensor node

A single sensor node

A single sensor node

The back of a sensor node

The back of a sensor node

The 10 first sensor nodes

The 10 first sensor nodes

In addition to the DHT22 sensors, I have also made firmware for collecting data from a wind vane and a rain gauge. But I haven’t deployed any of that yet. Maybe next spring…

All in all the main results for the sensors are:

  • They work! I have tested concurrent operation of 10 units without major problems.
  • Firmware optimized for ATtiny84 @ 1 MHz (8MHz crystal with the CKDV8 fuse set)
  • Temperature and humidity measurement using a DHT22 sensor
  • Wind speed and wind direction measurement using a La Crosse TX23 anemometer
  • Rainfall measurement using a WS-2300-16 rain gauge
  • Wireless operation using the very popular nRF24L01+ 2.4 GHz radio chip
  • Very compact CRC32 implementation
  • Battery powered operation using a very efficient 3.3v DC/DC converter
  • Power management by sleeping the CPU and turning off unneeded hardware
  • Battery voltage measurement included in data packet
  • Typical battery draw while sleeping has been measured to around 17uA
  • Total firmware size from 3.0 kiB to 3.5 kiB (depending on sensor type)

The base station

I use a Raspberry Pi as base station. To make it more appliance-like than a typical Raspbian installation, I have instead installed a variant of Tiny Core Linux called piCore. This is basically a very small Linux distribution that loads all programs into memory on boot and leaves the SD card alone after this. This eliminates the usual risk of corrupting the file system when doing a power-cycle.

On the base station I have installed a small python script that continually polls the nRF24L01 radio using the Raspberry Pi’s built-in SPI interface pins. When a data packet arrives, it is buffered (in case of network problems) and forwarded to the database.

The database

With my limited data requirements, I could probably use any old database out there without issues. However, given the nature of the data, it was natural to select a so-called timeseries database. For this project I chose InfluxDB, which was very, very easy to set up on my Ubuntu-based file server. It automatically exposes a simple HTTP interface for storing and querying data, which is just what I need for this project.

The frontend(s)

Well, I’m not quite there yet… So far the only frontend is the admin interface that is built in to InfluxDB. Not very user friendly (not to mention the Wife Acceptance Factor)! The next step now is to make some sort of nice frontend for this. I have several ideas floating around my head:

  • An intranet website. The easiest way.
  • An Android widget. Both the wife and I have Android smartphones.
  • Dedicated hardware devices. This would be a great use-case for my new ESP8266 wifi modules and some 84×48 Nokia LCDs I have lying around.

Stay tuned…