A few months ago, in the dead of Canberra winter, we discovered our flat had a mould problem. Insidious disgusting mould had crept in around our walls. Much scrubbing ensued.
We bought a dehumidifier in order to keep our flat dry and hopefully mould-free. The more advanced model had a humidistat and could automatically maintain a given humidity level. That model wasn't in stock, though. Besides, surely I could build something better (famous last words!)
The Flatdrier project is my overblown personal project to monitor & control our dehumidifier.
The first step was monitoring temperature & humidity. We'd seen signs of mould in a couple of rooms, so I wanted to be able to keep track of several rooms plus outdoors.
The cheapest and easiest solution was this ebay weather station. $43 and it came with 3 remote units:
Photo courtesy of ebay seller marcmart.ukau - fine purveyors of weather stations, DC solenoids, off-brand Rubik's cubes, and men's wool jackets!
The weather station is pretty average quality. With the remote sensors all next to each other the readings vary by 1-2 degrees & 10-20% humidity. However each sensor seems consistent with itself, I think this is accurate enough for my purposes.
Hacking the weather station
The first step was pulling the weather station apart. The remote modules use a 433Mhz transmitter (the blue module in the photo marked "SL-TX583 WWW.HH.COM") to send digital data back to a matching receiver in the base station:
With the data pin patched from a transmitter module into my Arduino, I wrote a quick Arduino sketch (later an MHVLib program) to sniff the signals so I could interpret them.
Turns out the protocol is very simple, with short & long pauses for 0s and 1s. To verify data it doesn't use a checksum, it just repeats the same message multiple times.
The base station had its own thermistor & humidity sensor onboard. I figured this was too good to waste, so I tried to reverse engineer it as well:
Both the thermistor and the humidity sensor are resistive sensors. The resistance varies with temperature & relative humidity, respectively. After "buzzing out" the circuit with my multimeter and sketching it, it seemed that instead of using ADCs the base station was using a comparator and timer to measure resistance.
This method measures the time taken to charge or discharge a capacitor through the sensor it is measuring. The time is proportional to the resistance (more resistance means less current flows to/from the capacitor, so it takes longer to fully charge or discharge.)
I found a good description of this technique on page 10 of TI's publication Economic Measurement Techniques with the Comparator A Module (PDF).
I had a tiny microcontroller board lying around, the TI MSP430 F2013 evaluation board, so I loosely mounted it in the base station to measure the time between charge/discharge of the capacitor.
Unfortunately I didn't notice that the F2013 has no onboard comparator (the next model down does, this one has a high-precision ADC!), so I was stuck using the high impedance digital inputs to detect "high" & "low" instead of specific threshold voltages. I think either the digital high/low thresholds are not consistent enough, or I misunderstood the circuit, because I never managed to take consistent readings.
After a few nights of poking the circuit and being confused, I abandoned the base station. I pulled the 433Mhz receiver module out of the base station, to connect directly to my Arduino.
Not wanting to lose a temperature input completely, I went to ebay and bought a $2 DHT-11 temperature/humidity sensor. This sensor is pretty crummy, the humidity values seem totally wrong (though I think maybe I cooked it during soldering), but the temperature readout provides useful data points.
Once I had all the hardware pieces together, I wrote a C program (plain AVR C) to run on the Arduino and monitor the temperatures.
I wanted to be able to track the temperature & humidity, so I could recall recent changes. I also wanted control - to switch the dehumidifier on and off by comparing the dew point to the temperature.
I also needed to stop the dehumidifier turning on in the middle of the night!
All these tasks could probably be accomplished by a single high-end microcontroller, but at the time I had an Arduino and the tiny MSP430 board. So I decided to make a client/server architecture, using our existing home wireless router (which runs the OpenWRT Linux distribution.)
A Python script on the router runs regularly to poll the latest values from the Arduino. It also makes decisions about when to turn the dehumidifier on and off.
Rather than managing a long-running process, the Python script just gets executed by cron every minute. It runs, takes a new sample from the Arduino, saves it to a CSV file, then sends either an "On" or an "Off" signal to the dehumidifier based on the recent sensor history (filtered to avoid hysterisis and midnight surprises.)
The dehumidifier is switched on and off by a wireless remote control powerpoint (Powertran A0342) that was left over from an older project:
This also communicates on 433Mhz. I already had a Jaycar ZW-3100 transmitter module, so I used this to transmit the on/off signals.
Conveniently I didn't have to reverse engineer the switch protocol, there was an existing Arduino remote switch library and I just translated the "Blokkerswitch" signals into plain AVR C.
Putting it together
The PCB engraver at Make Hack Void made it easy to throw together a custom Arduino shield:
Realistically, a protoboard could have done this pretty easily. But it's fun to use a new toy like the PCB Engraver, and it took less than an hour to make the board!
The PCB routing itself is a bit quick and nasty. For starters, I got the receiver module pinout backwards so it sticks out the side of the PCB! That's since been fixed, but I think the existing board looks a bit like a sailboat!
There's a web page to view the temperature, humidity & the history of the dehumidifier state:
The date range picker control (thanks Dan Grossman!) lets you view any date range:
Here's a demo page, using data from the last week in September. Looking over the history you'll notice some inconsistencies with the dehumidifier coming on and off, this was caused by me tuning the algorithm sensitivity during the week.
To draw the graphs I used the very nice Flot charting framework.
An early version used the d3.js charting functions from NVD3.js, instead of Flot, but the browser rendering times were much slower and there were glitches with the rendering output. I didn't spend much time trying to tune or fix D3, though. D3 is a very powerful framework and I'm sure I could make it work well, but this time I really only needed a simple "cookie cutter solution", something NVD3 explicitly says it avoids.
The project code is all up on github, with a README describing the structure.
It's unlikely anyone else will have this same problem or exact same hardware, but the code is pretty modular so some parts will hopefully come in handy.
The ironic thing about this project is that we got the dehumidifier in early July but I only got the controller up and running in the second week of September, just in time for (hopefully) warmer weather and less condensation problems.
Maybe waiting a few days for the "smart" dehumidifier model to come back into stock wouldn't have been such a bad idea, after all...