Projects / Garden
Smart Plant Monitor
Soil moisture, light and air for one plant — on a rechargeable battery.
Overview
Stick the ET-S10 capacitive probe in the pot and know exactly when to water. Unlike cheap resistive probes it has no exposed copper, so it doesn't corrode in wet soil.
A light sensor tells you whether the plant gets enough sun, and a temperature/humidity sensor watches the air around it. The ESP32 wakes every 15 minutes, takes readings and sleeps again, so a small LiPo lasts for weeks. Recharge it through USB-C.
- Soil moisture from a corrosion-proof capacitive probe
- Light level in lux
- Air temperature and humidity
- USB-C rechargeable, weeks per charge
What you need
ElectroTrical boards
Boards total: AED 118.00
These boards are being manufactured. Open a board's page to see when it's back, or ask us about a kit.
You'll also need
- ESP32-S3 DevKitC-1 (or any ESP32-S3 board) with a USB-C data cable. Not sold by ElectroTrical.
- Qwiic / STEMMA QT cables (JST SH 4-pin) to chain the boards, or jumper wires
- 1S LiPo, 1,000–2,000 mAh with JST-PH connector
- A small splash-proof box for the ESP32 and power boards
Wiring
Wire the first board's header to the ESP32 as shown, then link the other I²C boards with Qwiic cables. Every board carries VIN, GND, SDA and SCL through both Qwiic sockets, so the chain needs no extra wires. Addresses: VEML7700 0x10, SHT41 0x44, FDC1004 0x50.
Power
| From | To | Note |
|---|---|---|
| LiPo JST-PH | ET-P01 battery socket | |
| ET-P01 VBAT | ET-P03 VIN | |
| ET-P01 GND | ET-P03 GND | |
| ET-P03 3V3 | ESP32 3V3 | Unplug the ESP32's USB when running on battery |
| ET-P03 GND | ESP32 GND |
ESP32 → ET-S03 header
| From | To | Note |
|---|---|---|
| ESP32 3V3 | VIN | VIN sets the I²C logic level. Keep it at 3.3 V for the ESP32. |
| ESP32 GND | GND | |
| ESP32 GPIO8 | SDA | |
| ESP32 GPIO9 | SCL |
Qwiic chain
| From | To | Note |
|---|---|---|
| ET-S03 Qwiic | ET-S11 Qwiic | |
| ET-S11 Qwiic | ET-S10 Qwiic | Use a 20–50 cm cable so the probe reaches the pot |
Build it
- 01
Set up the Arduino IDE
Install Arduino IDE 2, add the Espressif ESP32 board package (Boards Manager → “esp32” by Espressif), select “ESP32S3 Dev Module” and turn on USB CDC On Boot so Serial prints over USB. Install the libraries listed above the sketch from Library Manager.
- 02
Calibrate dry and wet
With the sketch running on USB, hold the probe in air and note the capacitance (DRY_PF). Then push it into fully watered soil up to the soil line marked on the board and note that value (WET_PF). Put both numbers into the sketch.
- 03
Insert the probe correctly
Push the stake in up to the soil line only. The electronics head must stay above the soil and out of the water when you water the plant.
- 04
Place the light sensor
Mount the ET-S03 at leaf height, facing the window, not shaded by the box.
- 05
Switch to battery
Unplug USB, connect the LiPo and power stage. The board now wakes every 15 minutes. Charge the battery through the ET-P01's USB-C socket.
Arduino code
Written for the ESP32-S3 DevKitC-1 with the Espressif Arduino core. Install these libraries from the Arduino Library Manager:
- Adafruit VEML7700 Library
- Adafruit SHT4x Library
#include <Wire.h>
#include <Adafruit_VEML7700.h>
#include <Adafruit_SHT4x.h>
// ---- calibrate these two values for your soil (see step 2) ----
const float DRY_PF = 2.0; // probe in air
const float WET_PF = 9.0; // probe in fully watered soil
const int SLEEP_MIN = 15;
Adafruit_VEML7700 veml;
Adafruit_SHT4x sht41;
const uint8_t FDC = 0x50;
void fdcWrite(uint8_t reg, uint16_t val) {
Wire.beginTransmission(FDC);
Wire.write(reg); Wire.write(val >> 8); Wire.write(val & 0xFF);
Wire.endTransmission();
}
uint16_t fdcRead(uint8_t reg) {
Wire.beginTransmission(FDC);
Wire.write(reg);
Wire.endTransmission(false);
Wire.requestFrom(FDC, (uint8_t)2);
return (Wire.read() << 8) | Wire.read();
}
// Single-ended capacitance of CIN1 (moisture electrode), in pF
float readSoilPF() {
fdcWrite(0x08, (0 << 13) | (0b111 << 10)); // MEAS1: CHA = CIN1, CHB disabled, CAPDAC off
fdcWrite(0x0C, (1 << 10) | (1 << 7)); // 100 S/s, start measurement 1
delay(15);
uint32_t raw = ((uint32_t)fdcRead(0x00) << 8) | (fdcRead(0x01) >> 8);
int32_t val = (raw & 0x800000) ? (int32_t)(raw | 0xFF000000) : (int32_t)raw; // 24-bit signed
return val / 524288.0; // 2^19 counts per pF
}
void setup() {
Serial.begin(115200);
delay(200);
Wire.begin(8, 9);
veml.begin();
sht41.begin();
float pf = readSoilPF();
float moisture = constrain((pf - DRY_PF) / (WET_PF - DRY_PF) * 100.0, 0, 100);
float lux = veml.readLux();
sensors_event_t hum, temp;
sht41.getEvent(&hum, &temp);
Serial.printf("Soil %.0f %% (%.2f pF) | %.0f lux | %.1f C | %.0f %%RH\n",
moisture, pf, lux, temp.temperature, hum.relative_humidity);
if (moisture < 30) Serial.println("Time to water!");
esp_sleep_enable_timer_wakeup((uint64_t)SLEEP_MIN * 60 * 1000000ULL);
Serial.flush();
esp_deep_sleep_start();
}
void loop() {}
Troubleshooting
Moisture reads above 100 % or below 0 %
Redo the dry and wet calibration in your own soil. Different potting mixes give different values.
Reading jumps when you touch the cable
Normal for a capacitive probe. Take readings with the box closed and the cable fixed in place.
Readings change after watering then drift
Water takes 10–30 minutes to spread through the pot. Use the reading from an hour after watering.
Take it further
- Send a phone notification when the soil is dry
- Add a small pump on a MOSFET board for automatic watering
- Use one ESP32 with several probes by changing the FDC1004 channel (CIN2–CIN4)
Turning this into a product?
We design custom boards that combine these sensors on one PCB, with firmware and production.