December 5, 2011

Christmas-tree water-level alert

Update 12/11/11: A fix to the program--- changed to capSenseRaw() instead of capSense(). The problem with capSense() is that it auto-adjusts the output for touch sensing, rather than absolute capacitive measurement. capSense() reports whatever capacitance it observed the first time as zero from then on. This means that if the water level is high when the Arduino is turned on, high will be interpreted as dry... And it's not very convenient to make sure the sensor is outside the tree-stand whenever you first turn the lights on! Kinda misses the point of this whole exercise if you have to take the sensor out, dry it off, turn the lights on, put it back... But using capSenseRaw() takes care of the problem.

One other note: the sensor has to be very waterproof! The 4 coats of polyurathane were marginal: I've since added a thin coat of silicon RTV and it works much better. If water touches the electrode strips, it shorts out the capacitor and the sensing function returns -2, which leads to erroneous reports of low water level.

-- --- ----- ------- ----------- -------------

About a year ago I made a Christmas-tree water-level sensor that didn't hold up well. Here's a link, but don't make that one. It had a flashing LED, then an audible alarm, to let you know that the water was either low or gone. But why use an LED? As "Joe" suggested in his comment last year, the tree has a lot of lights on it already and why not flash them instead?

Good idea, Joe. Thanks!

The functional problem with last year's model is that the copper traces used for the water-level sensor corroded quickly, and the device was useless in less than a week. The fix I came up with this year is to use a capacitive measurement of water level instead of a conductive measurement. This method (and the necessary CapSense library) is described on the Arduino Playground wiki as an idea for a proximity sensor. Since water has a very high dielectric constant, the presence or absence of water significantly changes the capacitance of a pair of copper traces. Measuring the capacitance of those traces then gives you a measurement of water level while keeping the traces isolated from the water.

Here's my sensor. It's just a strip of strip-type protoboard. (It's 4 traces wide, but I'm only using 2 traces.) It's been covered with 4 coats of spray-on clear polyurethane, so it is (one hopes) completely waterproof. There are two neodymium magnets glued to the back so I can mount it to the inside of the Christmas-tree stand. I forgot to put something in the picture for scale, sorry: it's 9cm long.
With this improved sensor, I can now use the CapSense library to measure water level without worrying about corrosion of the copper traces. And I probably should have stopped there, but Joe's suggestion just seemed to good to pass up. So here's the schematic for the rest of it:
Everything inside the dashed lines is built into a small box. The box has a plug receptacle on the top, into which are plugged the tree's lights. Power to that receptacle is switched by a relay, controlled by an Arduino Pro Mini. (The Pro Mini and relay are powered by a 9V wall-wart transformer, also mounted inside the box.)

If the Arduino detects a "good" water level, it leaves the relay alone and the lights plugged into the receptacle stay on continuously. When the water level drops to "fair", the Arduino cuts the lights briefly once every 5 seconds. When the water level drops below that, the Arduino flashes the lights once a second. Here's the box: I wrapped it in shiny paper to help it "blend in" under the tree.
Here's the code. The values of "fair" and "good" will depend on the exact geometry of your sensor and sensor cable. Uncomment the serial lines in that code and see what values are coming back from the Arduino to determine what levels are appropriate for your setup.

A note for the Arduino-haters: Yes, this could be done with an ATtiny85. Here's why I decided to use a whole Arduino this time:
  1. You need fairly precise timing to measure capacitance repeatably with the CapSense library. That means you need an external crystal rather than the microcontroller's internal oscillator.
  2. The 12A relay I used needed 9V to activate. (My local Radio Shack didn't have a 5V relay that could switch more than 1A.) An ATtiny needs 5V at most, so I would need a voltage regulation circuit.
  3. I needed to know the values coming out of the CapSense routines so as to be able to set the cutoffs for "good" and "fair" in the final program. That meant I needed a serial link back to the computer for the setup process.
  4. Put all this together and hey, it's an Arduino. The Arduino is built already, and I have to write an exam this week also.
But yeah, it'd be cheaper and more elegant if I just used an ATtiny85. :-)

Update: Since I have the memory available, I tweaked the program a bit. Instead of a fast blink when the tree gets dry, it now blinks "water... water... water..." in Morse code.


  1. Nice job, I love the Morse code alert. I wonder if you could simply measure the capacitance of the whole cast iron stand and ditch the dedicated sensor?

  2. Hook it to a pump instead of a led = Auto water

  3. I've been searching for this for about a year and finally found it again.

    Do you have to use copper (have plenty of aluminium tape and if you have a plastic tree stand would it work outside the water glued to the side of the container?

    1. Copper is not required, any conductor would work.

      Taping electrodes to the outside of a plastic stand just might work! That's an interesting idea, be sure to post here to let us know if it worked. Most plastics have a relatively high dielectric constant, so depending on the thickness of the stand there might not be much effect from the water... but it's certainly worth a try.

    2. Well I just used two strips of Aluminum foil and it worked fine. I'll try the strips outside the stand once everything pulled won from the attic.

  4. OK as a little test I pressed the sensor to the outside of the plastic cup I was using for a test and at first it worked exactly as in the cup but then I realized that the sensor was still wet and I was reading the water still on the sensor.

    So back in the water. Will the tree effect the reading? If I strap this to the trunk. will it read the trunk and not the water.

    I may have to consult my one son. I think he had to learn capacitance theory as part of the engineering physics program he is in. I think he has no knowledge of how to hook them up in a circuit just how they work at a theoretical level.

  5. It may be helpful to understand HOW the capacitive sensor works... water is highly polarizable, so its presence in an electric field lowers the field and thus the voltage between the electrodes. The net effect is that to reach the same voltage as before requires a higher charge, and since Q/V = C the capacitance is higher when water is present.

    That's about a week and a half of physics lecture in two sentences, so cut to the good part: the capacitance depends on the water level. More water -> higher value of C measured by the arduino.

    If your sensor is on the outside of the tree's water bowl, then the tree won't affect it much as there's probably a couple inches of water between the electrodes and the tree. The water will dominate the effect. I wouldn't strap the electrodes to the tree, though: the dielectric constant of the tree is uncertain, and variable, and will generally confuse things.

    Keep in mind, while you're testing this, that the measurement is measuring C not "water". Your hands will change C also, even by just being near the sensor. If you "press the sensor to the outside of the cup" with your hands, the sensor is going to read all over the map depending on where your hands are.

    If you want to discuss this more off-blog, my email is I'd be happy to help you get this working.

  6. Great work! I have been looking to do something like this and your page has really helped.

    BTW Don't waste your time trying to appease the moronic Arduino haters. They aren't worth your time.