A small autonomous garden waterer. A soil moisture sensor sits in the pot. When the soil dries out, the system runs a pump for a few seconds to water the plant. A solar panel charges the battery during the day. The whole thing runs unattended.
Standard project on paper. The interesting part is how it actually works.
The original problem. An Arduino Uno cannot drive a 6V DC pump directly. The Uno's digital output pins can sink about 40mA at 5V. A cheap submersible pump pulls 200 to 500mA at 6V. Connect them and you'll either kill the pin or get nothing.
The right solution is a relay module or a transistor switch. I didn't know that at the time.
What I figured out instead, in Class 7, was that the pump came with an inline manual ON/OFF button. So I rigged up a servo motor whose arm physically presses the button when the Arduino tells it to. Soil reads dry, Arduino swings the servo, servo arm taps the button, pump turns on. A few seconds later the Arduino swings the servo again to press the button again, pump turns off.
It is mechanically absurd and electrically wrong. It also works. The button is rated for a million presses. The servo can do 50 a day for years before wearing out. The whole system has been running for the duration it needed to run.
I'm leaving the hack in the code because that's the actual project. A relay-based version is in the "what I'd do differently now" section, where it belongs.
The system has three layers.
Power. A 6V solar panel charges a 3.7V Li-ion 18650 cell through a TP4056 charge controller, which also handles overcharge and overdischarge protection. The Arduino runs from the battery via the VIN pin. The pump runs from the battery directly when its button is pressed.
Logic. The Arduino reads the soil moisture sensor on A0 once per minute. The YL-69 returns higher values for drier soil. When it crosses a threshold, the Arduino triggers the pump for 4 seconds, then waits for the soil to recover before checking again.
Actuator. Instead of switching the pump electrically, the Arduino moves a servo motor whose arm presses the pump's manual button. The servo is small enough to power off the Arduino's 5V rail directly.
if (soil_dry && !pump_running) {
press_pump_button(); // servo presses, pump turns on
pump_running = true;
record_start_time();
}
if (pump_running && elapsed_time > 4_seconds) {
press_pump_button(); // servo presses again, pump turns off
pump_running = false;
}That's the whole logic. There's no clever scheduling, no PID controller, no model of how plants need water. A 12-year-old wrote it with a goal of "make the plant get water when soil is dry, then stop, then check again later." For a single houseplant in a pot, that's enough.
The code does have a few things worth pointing out.
5-sample smoothing on the moisture reading. The YL-69 is genuinely noisy. Single samples can swing 50+ counts. Averaging 5 samples over 1 second cleans this up enough that the threshold check doesn't false-trigger.
Hysteresis. The dry threshold (600) is higher than the wet threshold (450) so the system doesn't oscillate at the boundary.
Once-per-minute checking. No reason to read the sensor at 50Hz. The plant doesn't dry out that fast. Slower checking saves power, which matters when you're running off a small battery.
| Component | Role | Cost (₹) |
|---|---|---|
| Arduino Uno | Microcontroller | 400 |
| YL-69 / FC-28 | Soil moisture sensor | 80 |
| SG90 servo motor | Mechanical actuator (presses pump button) | 150 |
| 6V DC submersible pump (with inline button) | The actual watering | 200 |
| 6V solar panel (~1W) | Power source | 250 |
| TP4056 charge controller module | Solar charging + battery protection | 60 |
| 18650 Li-ion battery (3.7V, 2000mAh) | Energy storage | 250 |
| 18650 holder + wires | 100 | |
| Small mounting frame (cardboard, tape, 3D-printed mount) | Servo arm holder | 50 |
Total: ~₹1,540.
The single most expensive component was the solar panel. The pump was second. Everything else was cheap.
- Open
solar_waterer.inoin the Arduino IDE - Install the
Servolibrary (built into Arduino IDE, just include it) - Upload to an Uno
- Wire it up per the diagram
- Plug the Arduino into the battery via VIN
- Put the moisture sensor in the soil, let the system check moisture every minute
- Open Serial Monitor at 9600 baud to watch live moisture readings (optional, debug only)
This was a Class 7 project. Looking back four years later, the changes I'd make:
- Replace the servo with a relay or a MOSFET. This is the engineering-correct way to switch a pump from a microcontroller. A 5V relay module costs ₹50 and removes both the servo and the dependency on the pump having a manual button. The reason the servo hack exists is that I didn't know about relays in Class 7. I do now.
- Capacitive soil moisture sensor instead of YL-69. The YL-69 corrodes within weeks because passing current through wet soil literally electrolyzes the probes. A capacitive sensor (₹150) doesn't have this problem and lasts indefinitely.
- Sleep the Arduino between checks. Currently the loop spins 24/7 even though it only does work once per minute. Putting the Uno into sleep mode between checks would extend battery life by 10x or more.
- Calibration step. Right now the dry threshold (600) is hardcoded. Real soil varies a lot. A 5-second calibration on first boot ("press the button when the soil is dry, press again when it's just been watered") would adapt to whatever soil is in the pot.
- Watchdog timer. If the code hangs, the system stops watering. A watchdog that auto-resets the Arduino every minute would make this more reliable for unattended deployment.
The biggest takeaway from this project, looking back, was that engineering constraints often have multiple solutions and the right one isn't always the one you find first. Using a servo to press a button is hilariously inefficient compared to a relay. But it works, it taught me about mechanical actuation, and figuring it out as a Class 7 student was more useful than copy-pasting a relay tutorial would have been.
I think about that whenever I hit a wall on a project now. Is there another way to do this? Even a stupid way?
MIT. Fork it, replace the servo with a relay, deploy it on your balcony.