To measure the power consumption of my house I’m using a Wattcher. The Wattcher consists of two parts: A sender module and a Display. The communication between the two modules is wireless.
Currently I only use the sender, which I hooked up to a Raspberry Pi to get a much more accurate measurement and a historic log. So to keep in line with the whole sustainability concept of the Wattcher, I went looking for a way to reuse the display unit for a different purpose.
The main part of the Wattcher display is a 7-Segment display array that can display numbers between 0 and 10000. It also has a button to configure it and to request some calculated values.
Of course I wanted to know what was inside of the device so I tried opening it. This is rather hard because the two half’s are connected by pins that are glued. So my casing didn’t survive completely undamaged.
Inside there is a PIC microcontroller with a nRF905 RF module connected to it. The programming pin’s of the PIC are actually connected to some pad on which a connector can be soldered. Connecting my programmer showed that the chip is read protected.
The easiest way to change the behaviour of the display would be to just reprogram the PIC microcontroller. But because the device is protected against reading the code memory, this would mean I will never be able to use the module in its original function again. So I looked for a less destructive approach.
The way the display is normally controlled is through RF, using the nRF905 chip. There are good data sheets available for the nRF905, and modules containing this chip can be bought very cheap on Ebay. So I decided to ordered some to play with.
After receiving the modules I hooked one up to my Raspberry PI and quickly found out that they where no good in controlling the Wattcher display. The Wattchers documentation states a carrier frequency of 868.4 MHz is used. However the modules I bought on Ebay have an antenna matching network that is specific to the 433 Mhz band. Luckily they weren’t completely useless. Because by having full control over one of these chips allowed me to write a frame receiver and decoder using software defined radio.
According to the Datasheet GFSK modulation with a +/- 50 kHz deviation. The bit rate is 100 Kbit/s. Using these parameters I made very simple GnuRadio project with just a GFSK demodulator in it that writes to file/FIFO. I thought this would be a bit to simplistic, but the output file actually showed signs of a manchester encoded signal.
Next I converted the output bit stream to a VCD file for analyse in GTKWave. The bit stream outputted by GnuRadio has only one bit per byte, while my VCD file generator expects 8-bit per byte. For this I wrote a extra tool to pack the input stream. A voila, through the magic of shell pipes, I had a VCD file.
Using GTKWave and the documentation, I was able to determine the frame structure that the nRF905 module uses. The frames have the following structure:
+----------+------------+-------------+------------+ | Preamble | Address | Payload | CRC | | (10-bit) | (1-4 Byte) | (1-32 byte) | (0-2 byte) | +----------+------------+-------------+------------+
- Preamble: The Preamble consist of a 10-bit value of 0x3f5. The preamble is also manchester encoded
- Address: The address of the target node(s). Depending on the configuration can be 1, 2, 3 or 4 bytes
- Payload: the payload data. Length depends on the configuration of the chip
- CRC: The CRC calculated over the Address and Payload fields. This can be 16-bit, 8-bit or absent depending on the configuration. The 16-bit CRC is a CRC16-CCITT with start value of 0xffff. The 8-bit CRC I haven’t analysed.
All bits, including the preamble, are Manchester encoded. There is no inter-frame gap. So if the auto-retransmit function is used you’ll end up with one long bit stream. Interesting thing is that there seams to be no bit stuffing used. So if there is a value of 0x3f5 somewhere in the address, payload or CRC fields, there is noway to distinguish this from the preamble.
With this information I wrote a little tool to decode the nRF905 frames from the output of the GFSK demodulator. The decoder automatically tries to detect the frame length and CRC settings in use. The source can be found here.
As it normally goes, only after having figured this all out, I found out that there was already someone who did the same. See http://www.embeddedrelated.com/showarticle/548.php.
Using the nRF905 frame capturing I was able to analyse the protocol used by the Wattcher.
The Wattcher display and sender communicate in a Master-Slave fashion, where the display only sends a frame after receiving one from the sender. This is probably done because the sender is battery powered. Because the sender now only has to keep it’s receiver enabled for a very short time after having send a frame. The rest of the time it can completely power down the RF unit.
The Wattcher’s use the following nRF905 configuration:
The payload of a packet send by the Wattcher sender contains the following information:
| 40 10 20 4a | aa 00 | ab | 00 | 00 75 96 | 00 0a | 00 00 00 | | Wattcher | |Vbat| | 19-bit | Disp. | | | Virt. Addr. | | | | Counter | Value | |
The nRF905 payload starts with a 32-bit ‘virtual’ address that couples a Sender module to a Display module. Then there are two fixed bytes. The 7th byte is a battery indicator, changing this causes a replace battery message to be displayed on the Wattcher display. Then there is a 19-bit counter which increases about 1’s per millisecond. It starts at 0 after sending a frame and is stopped when the sender receives a reply from the display unit. After this there is the value that will be displayed on the display.
When the display receives a frame from the sender it replies with the following message:
| 40 10 20 4a | a6 | 02 58 | 00 00 00 00 00 00 00 00 00 | | Wattcher | | Cval | | | Virt. Addr. | | | |
Again this starts with the Wattcher couple’s unique address. Apart from that the only useful information is the ‘C’ value as configured on the Display unit. The Sender uses this value to calculate the value to display from the amount of impulses registered by it’s sensor.
A Wattcher Display and a Sender are paired together by the 32-bit virtual address at the start of each frame. The Wattcher allows creating a new pairing by long pressing the red button on the Display and the Sender. When this is done the units will enter a sync mode.
In sync mode another nRF905 address, 0xc12cc21c, is used to distinguish the traffic from the normal traffic. Other than that nothing is changed to the nRF905 settings.
The sender will determine a new random virtual address for the pair. This is send in a frame with the following structure:
| c1 3a 11 4a | 1c | 00 00 00 00 00 00 00 00 00 00 00 | |New Wattcher | | | | Virt. Addr. | | |
The Display with answer with the following frame:
| c1 3a 11 4a | 2c | 00 00 00 00 00 00 00 00 00 00 00 | |New Wattcher | | | | Virt. Addr. | | |
Taking Over Control!
So now I can receive the traffic, but I wanted to control the Display unit!
As I mentioned above the nRF905 module I got from eBay was no good, because it’s matching network seemed to kill the RF signals in the 868 MHz band. I came to this conclusion because the Nordic nAN900-04 application note for the nRF905 describes a different matching network for the 868 MHz band then for the 433 MHz band.
A closer look at my module and the circuit diagrams of the application note showed that the matching network for the different bands only really differ in the values of the components. So I got the idea to just replace the components.
Although this does sound simple, it proved to be rather challenging. Mainly because: A) The components are rather small SMD component. and B) The values of the components are of such a small order that any parasitic capacitance introduced by bad soldering will have a relative large effect.
First attempt proved to be a failure. After sending one frame the sender would continue to oscillate until the module was completely powered down. Yeah, I’ve got a jamming device;).
The second attempt proved more successful. I’m now able to send working frames when using the module is ‘auto-retransmit’ mode for 10 Millisecond. That’s good enough for my purpose.
But even though I was able to send frames and receive them with my SDR setup. I wasn’t able to control the Wattcher display. This was caused by the nRF905 module being tuned at a offset of about 100 kHz of the requested frequency. When I started looking into replacing the crystal for a better one, I found that the Cl value of 12 pF specified in the reference design was actually very hard to get. I assumed that the makers of this cheap module would also have run into this problem and just used some common crystal. While using a crystal with another Cl, they apparently didn’t update the values of the C1 and C2 capacitors. This would explain the fixed tuning offset.
Guessing the Cl was actually the much more common value of 16 pF. I calculated, using the formula in the datasheet, that the capacitors should be 33 pF. And so I finally took over:
Doing Something Useful
Ok, now I can display a number… but what shall I do with this tremendous power. As it happens I was already playing around with a DHT22 Temperature/Humidity sensor. So I wrote some code to combine all of this on a Raspberry Pi. And now I have an exclusive, designer, temperature display!
The picture above shows my setup. Note the crappy soldered SMD components between the antenna and the nRF905, which is the replaced matching network
The source code of all tools I used is available on github: nrf905_stuff and generic radio stuff