Not the first person to do one of these, I’m sure, but I wanted to play around with the Pi Pico W. Using parts and code I adapted from plant_io, I made an IoT enabled self-watering smart plant with some additions and improvements:
Water level sensor to monitor the tank water level. Managed to port the C code from the Grove I2C sensor to MicroPython, and I’m using a Grove to Qwiic cable to plug the water sensor directly into the Piicodev port on the shim.
The onboard LED blinks while watering
Battery level monitoring
Online dashboard to remotely monitor the plant’s status and display some statistics
Gets the local time from the network, and only waters (if needed) during the the day (7AM to 6PM).
Upper and lower limits for the soil moisture level
Notifications on my phone if the water tank or batteries are getting low
Checks in on the plant every two hours as per the setting on the Nano power timer.
Nice plant I selected from Bunnings
There will probably be some bugs to iron out, but I’ll keep a close eye on it over the next few weeks.
@Mark285907 I’m using Home Assistant. There’s a REST API I can make post requests to that updates values for sensor entities. Home Assistant takes care of the rest (pun intended).
Update: The Pi Pico W seemed to have drained my batteries overnight.
I have everything in a try: / finally: block, with the power cycling command in finally:. So it should turn off even if something goes wrong in the main part of the code.
I suspect connecting to WiFi and making requests every two hours takes some juice. I’m going to power if off the microUSB port.
Sounds like you’re already doing a lot right with the try/finally structure and timed check-ins. For further power optimisation, as Mark suggested, you could try disabling Wi-Fi overnight or only enabling it during scheduled check-ins. When Wi-Fi is active, the Pico W can draw anywhere between 70–100 mA during idle connection, and up to 150–200 mA during active transfers like HTTP requests
Another option is using deep sleep on the Pico W. Just a heads-up though, I believe calling machine.deepsleep() triggers a full reset when the device wakes. That means any variables or state stored in RAM are lost, unless you’ve saved them to flash (e.g. in a JSON file). If you go down that path, you’ll need to structure your code so it can re-evaluate everything (like time of day, moisture levels, etc) from scratch on boot.
Looking forward to hearing how it performs once it gets its first automatic watering!
Great to hear you’re already storing persistent variables in a JSON file, that’s the way to go!
Apologies, I missed that you’re already power cycling the Pico W using the Nano Timer HAT.
To put it simply:
Power cycling with the Nano Timer fully shuts down the Pico, so zero power is drawn while it’s off.
Deep sleep (machine.deepsleep()) puts the Pico into a very low-power mode but it still draws a small amount of current. Deep sleep is useful if you want the Pico to manage its own sleep cycles internally without external hardware.
Since you’ve got the timer working well, that’s probably the most battery-friendly approach for your use case.
Deepsleep is a MicroPython mode that sometimes doesn’t work well on every port of MicroPython. There were some issues with the RP2040 port, where it couldn’t get to the claimed spec.
Unsure with RP2350 (used for Pico 2W); quick Googling suggests it is working for some and not for others depending on the config. Would be interesting to experiment with.
The Nano power timer is unique in the way it can isolate all power (not just the MCU) including sensors and other components that don’t have a low power setting. Used properly, it’s basically an inline switch between the battery and the entire circuit.
I believe that one can be set for 2 hour intervals. If you had a power meter, like the Otii Arc, you could measure the energy used to wake up, connect to wifi, do stuff and then shutdown.
Divide the battery capacity by that figure, and you have the number of times it could perform that task before the batteries went flat. Multiply that by 2, and that’s how many hours your project should last.
I reckon you could extend the life to tens of months by only connecting to WiFi once a day or on the watering event (but still doing a check every 2 hours for water level, configuring the wifi radio to be electrically disabled - not just unused).
All that said, I’d expect a couple of AA’s to last a good while if only checking in once every 2 hours using the Nano timer. Given you have the internet, you could also measure the battery voltage using a step-down resistor network and send you an email when your batteries are getting low. Or kick off an IFTTT to create a Trello/Jira card, if that’s your vibe.
Nice project and really nice touches on it all to make it look professional (also nice pot).
Just throwing in some info about sleep modes, @Gramo is correct in that the RP family doesn’t support the sleep states in MicroPython very well right now. We tested it on the Otii Arc (a super accurate power analysis tool), and found that using “lightsleep”, it still consumed about 2ma of power. We couldn’t get the “deepsleep” mode working (which should have less power draw).
For comparison, the power time uses about 40 nA of power when it is in its sleep mode. Even powering on every 2 hours and performing some tasks over WiFi, it should last more than a night. Some projects I’ve done using a similar setup can last weeks if not months on a set of AA batteries - maybe check your code? If not, like you have done, USB wall power also works.
Again, very nice project and nice plant selection!