18e40415143eb0b8880663f766a1dbcbfdff23f0
ESP32-S3 Plant Watering System
An automated plant watering system built with ESP32-S3, featuring MQTT communication, OTA updates, and remote monitoring/control capabilities.
Current Project Status
✅ Completed Features
- WiFi Manager: Auto-connect with NVS credential storage
- OTA Updates: Web-based firmware updates via HTTP server
- MQTT Client: Full MQTT integration with NVS credential storage
- Auto-reconnection
- Last Will and Testament (LWT)
- Command subscription
- Sensor data publishing
🚧 In Progress
- Motor control (TB6612FNG driver)
- Moisture sensor reading
- Automation logic
📋 TODO
- Web dashboard
- Home Assistant integration
- Multiple zone support
Hardware
- MCU: ESP32-S3-MINI-1
- Motor Driver: TB6612FNG (for 2 water pumps)
- Sensors: 2x Capacitive soil moisture sensors
- Power: 12V supply for pumps, 3.3V for logic
Software Architecture
MQTT Topics
| Topic | Direction | Description | Example |
|---|---|---|---|
plant_watering/status |
Publish | System online/offline status | "online" |
plant_watering/moisture/1 |
Publish | Moisture sensor 1 reading (%) | "45" |
plant_watering/moisture/2 |
Publish | Moisture sensor 2 reading (%) | "62" |
plant_watering/pump/1/set |
Subscribe | Pump 1 control command | "on"/"off" |
plant_watering/pump/2/set |
Subscribe | Pump 2 control command | "on"/"off" |
plant_watering/pump/1/state |
Publish | Pump 1 current state | "on"/"off" |
plant_watering/pump/2/state |
Publish | Pump 2 current state | "on"/"off" |
plant_watering/config |
Subscribe | Configuration updates | JSON config |
Configuration
WiFi Settings (menuconfig)
CONFIG_WIFI_SSID="Your_SSID"
CONFIG_WIFI_PASSWORD="Your_Password"
MQTT Settings (menuconfig)
CONFIG_MQTT_BROKER_URL="mqtt://192.168.1.100:1883"
CONFIG_MQTT_USERNAME="plantwater"
CONFIG_MQTT_PASSWORD="your_password"
Plant Watering Settings (menuconfig)
CONFIG_MOISTURE_THRESHOLD_LOW=30 # Start watering below this %
CONFIG_MOISTURE_THRESHOLD_HIGH=70 # Stop watering at this %
CONFIG_WATERING_MAX_DURATION_MS=30000 # Max pump runtime (30s)
CONFIG_WATERING_MIN_INTERVAL_MS=300000 # Min time between watering (5min)
Building and Flashing
Using Docker (Recommended)
Configure the project
docker run --user $(id -u):$(id -g) --rm -v $PWD:/project -w /project -it espressif/idf:latest idf.py menuconfig
Build
docker run --user $(id -u):$(id -g) --rm -v $PWD:/project -w /project -it espressif/idf:latest idf.py build
Flash via USB
docker run --privileged --rm -v $PWD:/project -w /project --device=/dev/ttyACM0 -it espressif/idf:latest idf.py flash -p /dev/ttyACM0
Monitor serial output
docker run --privileged --rm -v $PWD:/project -w /project --device=/dev/ttyACM0 -it espressif/idf:latest idf.py monitor -p /dev/ttyACM0
Flash and monitor in one command
docker run --privileged --rm -v $PWD:/project -w /project --device=/dev/ttyACM0 -it espressif/idf:latest idf.py flash monitor -p /dev/ttyACM0
Note: Replace /dev/ttyACM0 with your actual device port (could be /dev/ttyUSB0, /dev/ttyACM1, etc.)
Using Local ESP-IDF Installation
# Configure the project
idf.py menuconfig
# Build
idf.py build
# Flash via USB
idf.py -p /dev/ttyUSB0 flash monitor
OTA Updates
- Connect to the same network as the ESP32
- Navigate to
http://<ESP32_IP>/ - Upload the
build/PlantWater.binfile - Device will automatically restart with new firmware
Testing with MQTT
Monitor All Topics
# Using Docker
docker run -it --rm --network mqtt-broker_mqtt-network eclipse-mosquitto:2.0.22 \
mosquitto_sub -h mosquitto -u monitor -P password -t "plant_watering/#" -v
# Using local mosquitto
mosquitto_sub -h 192.168.1.100 -u monitor -P password -t "plant_watering/#" -v
Control Pumps
# Turn Pump 1 ON
docker run -it --rm --network mqtt-broker_mqtt-network eclipse-mosquitto:2.0.22 \
mosquitto_pub -h mosquitto -u home-server -P password -t "plant_watering/pump/1/set" -m "on"
# Turn Pump 1 OFF
docker run -it --rm --network mqtt-broker_mqtt-network eclipse-mosquitto:2.0.22 \
mosquitto_pub -h mosquitto -u home-server -P password -t "plant_watering/pump/1/set" -m "off"
# Turn Pump 2 ON
docker run -it --rm --network mqtt-broker_mqtt-network eclipse-mosquitto:2.0.22 \
mosquitto_pub -h mosquitto -u home-server -P password -t "plant_watering/pump/2/set" -m "on"
# Turn Pump 2 OFF
docker run -it --rm --network mqtt-broker_mqtt-network eclipse-mosquitto:2.0.22 \
mosquitto_pub -h mosquitto -u home-server -P password -t "plant_watering/pump/2/set" -m "off"
Local mosquitto commands (if installed)
# Subscribe to all topics
mosquitto_sub -h 192.168.1.100 -u monitor -P password -t "plant_watering/#" -v
# Control pumps
mosquitto_pub -h 192.168.1.100 -u home-server -P password -t "plant_watering/pump/1/set" -m "on"
mosquitto_pub -h 192.168.1.100 -u home-server -P password -t "plant_watering/pump/1/set" -m "off"
Current Behavior
When the system is running:
- On boot: Connects to WiFi, then MQTT broker
- Status: Publishes "online" to
plant_watering/status - Sensors: Publishes simulated moisture readings every 10 seconds
- Commands: Responds to pump on/off commands
- Feedback: Publishes pump state changes to state topics
- Disconnect: LWT publishes "offline" to status topic
Project Structure
main/
├── CMakeLists.txt # Build configuration
├── Kconfig.projbuild # menuconfig options
├── main.c # Main application
├── wifi_manager.c/h # WiFi connection management
├── ota_server.c/h # OTA update server
├── plant_mqtt.c/h # MQTT client implementation
├── led_strip.c/h # RGB LED control (from template)
├── motor_control.c/h # (TODO) Pump motor control
└── moisture_sensor.c/h # (TODO) Sensor reading
Credential Management
Both WiFi and MQTT credentials are stored in NVS (Non-Volatile Storage):
- First boot: Uses menuconfig defaults and saves to NVS
- Subsequent boots: Loads from NVS
- OTA updates: Preserves NVS (credentials survive updates)
To update credentials after deployment:
- Change in menuconfig
- Add temporary force-update code
- Build and OTA update
- Remove temporary code and update again
Or erase flash completely: idf.py erase-flash
Version History
- v2.0.0-mqtt: Added MQTT client with NVS storage
- v1.0.1: Initial OTA-enabled template
- v1.0.0: Basic LED blink example
Troubleshooting
MQTT Connection Issues
- Check broker is running:
docker ps - Verify credentials match broker configuration
- Ensure ESP32 and broker are on same network
- Check firewall rules for port 1883
WiFi Connection Issues
- Verify SSID has no trailing spaces
- Check password is correct
- Ensure 2.4GHz network (ESP32 doesn't support 5GHz)
- Try erasing flash and reflashing
OTA Update Issues
- Ensure device is connected to network
- Check partition table has OTA partitions
- Verify firmware size fits in OTA partition
- Try accessing
http://<ESP32_IP>/testto verify server
Next Development Steps
-
Motor Control Module
- PWM speed control
- Safety timeouts
- Current monitoring
-
Moisture Sensor Module
- ADC calibration
- Averaging/filtering
- Percentage conversion
-
Automation Logic
- Threshold-based watering
- Time-based schedules
- Prevent overwatering
-
Enhanced Features
- Web dashboard
- Historical data logging
- Multi-zone support
- Weather API integration
Description
Languages
C
99.5%
CMake
0.5%