ESP32-S3 self-watering pot
A capacitive soil probe in the pot and a small 12 V pump in a water tank: when the soil gets dry the pump waters it, and stops when the soil is moist again. A float switch in the tank stops the pump before it runs dry and lights the red LED: time to refill. It runs on its own, without the computer or the internet.
The program
Chip BASIC: every line is one instruction you can read and change. The compiler checks it at every release of the site.
REM Vaso che si annaffia
REM @part terra = soil
REM @part tanica = float
REM @part interruttore = mosfet
REM @part pompa = pump on=interruttore
10 LET secco = 30 : REM @cfg secco 5..60 Annaffia sotto (%)
20 IF terra.MOISTURE < secco AND tanica THEN pompa ON
30 IF terra.MOISTURE >= secco + 15 OR tanica = 0 THEN pompa OFF
40 IF tanica = 0 THEN LED red, on
50 IF tanica THEN LED red, off
60 WAIT 1s
70 GOTO 20What you should see: with moist soil the pump is off; below 30% moisture it starts, and stops at 45%. With the tank empty the pump never starts and the red LED is on. In the simulator move the soil slider down and click the float to empty the tank.
▶ Open it in the IDEIn the simulator you see the logic run right away, with no hardware. The simulator does not check the wires: you check those on the board, and the IDE's wiring check walks you through it.
The parts
The compiler finds the parts in the program. Each has its own page with a test program to run before you build the whole thing.
- LED (with resistors: 220 Ω, or 470 Ω on the UNO R4)
- Soil moisture probeGoes into the pot's soil and tells how wet it is, from 0 % (dry) to 100 % (wet).
- Float switchA float in the tank: 1 while the water lifts it to its level.
- MOSFET driverA switch a board pin turns on and off, for a 12 V pump, fan or valve.
- 12 V pumpA small submersible pump that moves water, to water a plant or fill a pot.
How to wire it to the ESP32-S3
- + red → ESP32-S3: GPIO4Through a 220 Ω resistor
- − → ESP32-S3: GNDCommon ground: this link is mandatory.
- SIG → ESP32-S3: GPIO2The pin tells the switch when to close: the load's current goes through the switch, never through the board.
- GND → ESP32-S3: GNDCommon ground: this link is mandatory.
- AOUT → ESP32-S3: GPIO9
- VCC → ESP32-S3: 3V3
- GND → ESP32-S3: GNDCommon ground: this link is mandatory.
- Signal → ESP32-S3: GPIO1Internal pull-up: pressed reads as 1
- GND → ESP32-S3: GNDCommon ground: this link is mandatory.
- pompa: + → interruttore: V+
- pompa: − → interruttore: OUT−
- 12 V supply: − → interruttore: GNDCommon ground: this link is mandatory.
- 12 V supply: + → interruttore: V+Connect the supply last, after checking every wire.
If it does not work
- The lights: the program runs but nothing happens
- The LED is the wrong way round, or the series resistor is missing. The long leg goes on the board pin's side, the short one towards GND, with the resistor in between (220 Ω, or 470 Ω on the UNO R4).
What you can change
The threshold is the `secco` setting on line 10 (a slider in the IDE): a cactus wants less, a basil more. Water in short bursts: the water takes time to reach the probe. Ask the assistant to send the moisture to the phone once a minute, or to water only in the morning.
Which boards it works on
- ESP32-S3 Freenove: yes
- Nordic nRF54LM20 DK: yes
- Arduino UNO R4 WiFi: yes