| « Recent updates to the dehumidifier monitoring system | Updated to the latest version of the blog software » |
Measuring the water level in a dehumidifier's tank
When Mark Walling created his Twittering dehumidifier, I decided to kick things up a notch by monitoring the actual level of the water. This is actually a fairly simple thing to do, electronically, but it still took me awhile to actually get a sufficiently-rounded tuit.
I finally decided to get a Mouser order placed to get the parts a week or two back, and got them mid-week. I got about thirty 0.1µF ceramic capacitors (Mouser P/N 539-CK06104K) and, since I’d need a resistor or two, about 500 resistors (split between 100Ω, 1KΩ, and 1MΩ). I’ll have some extras, for sure…
The Hardware
I cut off a nice hank of the solid-core green wire, left over from my backyard 3.5MHz antenna, and started construction.
![]() |
It went pretty well. I didn’t use anything beyond twisting the leads to secure the caps to the wire, and the wire itself provided all the structure it needed (that crap is solid). After soldering, testing, and loading a capacitance meter sketch into my Arduino, it was time for the dunkeltest!
![]() |
The data coming out was good. I did notice that it wasn’t linear: for every additional capacitor immersed, the detected capacitance doubled. I’m going to ignore this for now, but to keep the data useful, I’ll probably put a log function in the log function so I can… oh, hell, you know the meme.
I also got a couple phototransistors to monitor the Bucket Full light, to “auto-calibrate” the meter. However, it turns out I got SMD phototransistors, which are a little too small for me to be hand-soldering at this juncture. So, I suppose I’ll just do the calibration by hand.
The final installation looks hacked together, but, well, that’s how we roll. You can see a collection of photographs in the gallery.
The Software
As mentioned above, I’m using a very slightly modified capacitance metering sketch on the Arduino to measure the capacitance. I’m having the Blue Blinking LED go high during the discharge cycle, so I can tell “at a glance” how full the dehumidifier is. In short, the slower the blink rate, the longer it is taking to go through the loop, the longer it is taking to reach 3.15V, the higher the capacitance, the more full the tank. This sketch repeatedly tests the capacitance and spits it out to the serial port:
Code:
>>> import serial | |
>>> ser = serial.Serial('/dev/ttyUSB0', 9600) | |
>>> ser.flush() | |
>>> ser.readline() | |
'S \xf90 mS 0 nanoFarads\r\n' | |
>>> ser.readline() | |
'14 mS 14 nanoFarads\r\n' | |
>>> ser.readline() | |
'14 mS 14 nanoFarads\r\n' | |
>>> ser.readline() | |
'12 mS 12 nanoFarads\r\n' | |
>>> ser.readline() | |
'12 mS 12 nanoFarads\r\n' | |
>>> ser.readline() | |
'14 mS 14 nanoFarads\r\n' | |
>>> ser.close() |
I then catch this with a few modifications to my world-famous munin-dehumid-status plugin, which was originally designed for Mark’s Twittering dehumidifier, but I kept it open enough for future use in more esoteric situations… like this.
Code:
def get_fullness_via_capacitance(name): | |
"""determines the fullness of a dehumidifier by getting the capacitance | |
via serial, then judging how full it really is""" | |
loopstart = time.time() | |
ser = serial.Serial(__dehumidifiers__[name]['serial'], 9600) | |
ser.flush() | |
results = [] | |
for test in range(0, 11): | |
_ok = False | |
while not _ok: | |
if time.time() > loopstart+10: | |
_ok = True | |
break | |
stuff = ser.readline().split() | |
if len(stuff) == 4: | |
(elapsedtime, elapsedtimeunit, cap, capunit) = stuff | |
if capunit == 'microFarads': | |
results.append(int(cap) * 1e-6) | |
_ok = True | |
elif capunit == 'nanoFarads': | |
results.append(int(cap) * 1e-9) | |
_ok = True | |
ser.close() | |
if len(results) > 5: | |
capacitance = sorted(results)[int(len(results)/2)] | |
else: | |
return None | |
| |
if capacitance < __dehumidifiers__[name]['emptycapacitance']: | |
return 0 | |
elif capacitance > __dehumidifiers__[name]['fullcapacitance']: | |
return 100 | |
else: | |
capmax = (__dehumidifiers__[name]['fullcapacitance'] - | |
__dehumidifiers__[name]['emptycapacitance']) | |
capcur = capacitance - __dehumidifiers__[name]['emptycapacitance'] | |
cappct = (capcur / capmax) * 100 | |
return int(cappct) |
![]() |
Unfortunately, it wasn’t all pickles and sunshine:
serial.serialutil.SerialException: could not open port /dev/ttyUSB0: [Errno 5] Input/output error: '/dev/ttyUSB0'
After a few runs, I was getting I/O errors on /dev/ttyUSB0. Worse, nothing I could do would fix them, short of rebooting my whole computer! Nuts. I did some poking around and eventually came across Launchpad bug 376128 against the ftdi_sio driver. Crap. If you’re a regular follower of my life, you know it’s always the little mistakes that get me, and the fix for this bug is no exception:
Code:
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c | |
index ef6cfa5..c70a8f6 100644 | |
--- a/drivers/usb/serial/ftdi_sio.c | |
+++ b/drivers/usb/serial/ftdi_sio.c | |
@@ -2030,7 +2030,7 @@ static void ftdi_process_read(struct work_struct *work) | |
spin_unlock_irqrestore(&priv->rx_lock, flags); | |
dbg("%s - deferring remainder until unthrottled", | |
__func__); | |
- return; | |
+ goto out; | |
} | |
spin_unlock_irqrestore(&priv->rx_lock, flags); | |
/* if the port is closed stop trying to read */ |
I tried using a backported Karmic kernel, but that did not go well. No, not at all. You see, my Nvidia video chipset is now “legacy", and… ugh. Serenity now…
I installed, patched, and compiled the Ubuntuized kernel source on my Linode, which was awesome and fun, and then stuck the fixed ftdi_sio.ko in /lib/modules/2.6.28-15-generic/updates/ on my workstation. depmod -a, modprobe -r ftdi_sio, and modprobe ftdi_sio, and life is approximately good.
This is now fixed in Ubuntu kernel image versions >= 2.6.28-15.50, available via the jaunty-proposed repository. If you have this I/O error problem with your FTDI device, give this a spin!
To Do
I’d like to clean up the wiring and coding for this, of course. However, we’ll see how it goes in a little while once we get a few tanks through it. This does have applications beyond dehumidifier tanks, though… consider a sump pump pit, or a rain barrel, or even a rain gauge! I don’t have great concerns about “mixing electricity and water” like this, since it’s “only” 5 volts, but I probably wouldn’t use it for things where humans might be in contact (sinks, swimming pools, etc). That said, I don’t think it would be a problem with proper care.
If you have any questions or suggestions, feel free to let me know!
p.s. twitter feed is in the works
Updates to this article: Followup article on 2009 August 29, edit to mention jaunty-proposed kernel on 2009 September 3, mentioning @hoopydehumid Twitter feed on 2009 September 13
3 comments
On Aug 25, James Sweet wrote "Calling all Maine residents".
Thanks for the kudos, and thanks for asking!


