I’m notoriously bad at watering the Christmas tree we bring into our house every year. I diligently water it for the first few days. Then I forget or get busy; a day or two goes by where I don’t water it, and the tree eventually dries out. By the time Christmas comes around, the tree is hanging on for dear life. Plus, even when I remember, getting under the tree is awkward, and I always spill water everywhere. A couple of years ago, I bought a long funnel, thinking that would make things easier, but it ended up being just as annoying and messy as not using one.
Amazon sells both cheap siphoning and expensive pumping tree watering systems. The one I like the most is $100. It’s not necessarily a bad price if it lasts multiple years. However, thinking about how it works, I decided to try building something myself.
I used an Adafruit QT Py ESP32-C3 board, a capacitive moisture sensor, a cheap fountain pump, and a relay to create a self-watering system that wirelessly connects to my existing Home Assistant setup. All for about $20, not including parts and tools I already owned.
I know what you’re thinking…
Do you really need your Christmas tree water pump to wirelessly connect to your home network?
No, absolutely not. But I had an ESP-32 board on hand, and, as you’ll see, ESPHome made it incredibly easy to configure the microcontroller and set up the watering automation.
- Adafruit QT Py ESP32-C3 dev board - $9.95
- Capacitive Moisture Sensor - $7.99 for 5 ($1.60/each)
- 1/2 Inch PVC Clear Vinyl Tubing - $6.88 for 10 feet
- Small Fountain Pump - $8.99
- Controllable Power Relay - $29.95
- 5 Gallon Bucket - $4.99
- 3D Printed QT Py Case - Free
- 3D Printed Moisture Sensor Mount - Free
I already had the QT Py ESP32-C3 and power relay from previous projects, so my total cost was only $22.46.
The relay I’m using has four outlets on it and probably wouldn’t be my first option if I didn’t already have it as I’m only using two of the outlets and only need the one switched outlet.
QT Py ↔ Capacitive Sensor
The capacitive moisture sensor gets power from the QT Py via the 5v and GND pins and sends its analog signal to the A0 pin.
QT Py ↔ Power Relay
The QT Py connects to the relay via its STEMMA QT connector. The connector has four pins, the GND and GPIO 5 pins are used. When the QT Py sends a 3v signal over the GPIO 5 pin, the relay switches the “normally OFF” outlet on.
The QT Py plugs into the “always ON” outlet via a USB C cable and 5v power brick for constant power.
Power Relay ↔ Pump
The pump plugs into the “normally OFF” outlet, which, as the name states, is normally off until a 3v signal provided by the microcontroller is detected, and then it switches on.
I’m going to skip over the instructions on setting up a device with ESPHome as there are a ton of tutorials and the ESPHome docs that cover those steps in great detail. I have ESPHome running as part of my local Home Assitant instance and used that to compile the following config and flash it onto the QT Py.
The config defines two devices. The first is a virtual switch with the id
xmas_tree_pump that sends a 3v signal over the GPIO 5 pin when switched on.
The second device is a sensor with the id
xmas_tree_water_sensor using the
adc or Analog to Digital platform that reads its data from the A0 pin. The time between updates is set to 1 second, and the unit of measurement is changed from volts to percentage.
Filters are applied to refine the incoming data by calculating the median, setting upper and lower limits, and calibrating to a scale, which I will write about below. Documentation for all the sections of the config I used is linked here.
When the value of the sensor drops below
62%, turn on the
xmas_tree_pump switch. Wait until the sensor is either above
10 seconds have passed, then turn the
xmas_tree_pump switch off.
Before completing the filters and automation sections of the config I did some initial testing to determine the voltage values at different water levels on the sensor. As you might have read in the config comments, it measured
2.2v when the sensor was dry and
1.0v when fully submerged in water.
The height of the cylinder of my tree stand is 6.5 inches (16.5 cm). With the components of the moisture sensor above the water line, the measurable area of the sensor is about 2.5 inches (6.35cm) tall. The bottom of the sensor sits about 4 inches (10 cm) above the bottom of the cylinder.
Doing some simple cross-multiplication, I figured out that when the water is at the bottom of the sensor (4 inches from the bottom of the cylinder), the cylinder is 62% full.
And we can map those values to the voltage readings from above.
Those values can be provided to the
calibrate_linear filter in the config. Since the sensor doesn’t reach the bottom of the cylinder, there’s no way of knowing what the water level is if it’s below the sensor, but that shouldn’t matter as the automation starts pumping water once the water level falls below 62%, which is below the bottom of the sensor.
I needed a way to mount the moisture sensor to the tree stand, so I turned to my ever-growing CAD and 3D printing skills. The requirements were simple:
- Keep the electronics above the water line
- Keep the sensor part of the PCB below the water line
- Easily removable
This is what I came up with. The sensor friction fits into the print. I added a dab of hot glue to ensure it stays in place. I had some small magnets lying around, and the tree holder is metal, so it securely grabs the stand. You can download, print, and modify the model yourself on Printables.com.
The other 3D print is a simple case for the QT Py that someone else designed and uploaded to Printables.
The pump goes into the bucket, and the bucket goes into Santa’s toy bag to disguise it under the tree.
I used a zip tie to secure the vinyl tubing around the base of the tree. I also looped the tubing above a branch higher than the bucket’s water level to prevent any siphoning from happening.
At the time of writing, the setup has been running without issue for a few days. As you can see below, the water level slowly drops below the 62% threshold, and the pump turns on, fills up, and then turns off. There haven’t been any spills or overflows yet. I’m happy so far, but it’s still too soon to say if this will work long-term or if spending the $100 on the watering system from Amazon is the way to go.