2025-07-17 20:41:25 -06:00
2025-07-17 20:41:25 -06:00
2025-07-17 17:47:13 -06:00
2025-07-17 17:47:13 -06:00
2025-07-17 17:47:13 -06:00
2025-07-17 20:41:25 -06:00

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

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

  1. Connect to the same network as the ESP32
  2. Navigate to http://<ESP32_IP>/
  3. Upload the build/PlantWater.bin file
  4. 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:

  1. On boot: Connects to WiFi, then MQTT broker
  2. Status: Publishes "online" to plant_watering/status
  3. Sensors: Publishes simulated moisture readings every 10 seconds
  4. Commands: Responds to pump on/off commands
  5. Feedback: Publishes pump state changes to state topics
  6. 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:

  1. Change in menuconfig
  2. Add temporary force-update code
  3. Build and OTA update
  4. 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>/test to verify server

Next Development Steps

  1. Motor Control Module

    • PWM speed control
    • Safety timeouts
    • Current monitoring
  2. Moisture Sensor Module

    • ADC calibration
    • Averaging/filtering
    • Percentage conversion
  3. Automation Logic

    • Threshold-based watering
    • Time-based schedules
    • Prevent overwatering
  4. Enhanced Features

    • Web dashboard
    • Historical data logging
    • Multi-zone support
    • Weather API integration
Description
No description provided
Readme 138 KiB
Languages
C 99.5%
CMake 0.5%