# 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 ```bash docker run --user $(id -u):$(id -g) --rm -v $PWD:/project -w /project -it espressif/idf:latest idf.py menuconfig ``` #### Build ```bash docker run --user $(id -u):$(id -g) --rm -v $PWD:/project -w /project -it espressif/idf:latest idf.py build ``` #### Flash via USB ```bash 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 ```bash 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 ```bash 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 ```bash # 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:///` 3. Upload the `build/PlantWater.bin` file 4. Device will automatically restart with new firmware ## Testing with MQTT ### Monitor All Topics ```bash # 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 ```bash # 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) ```bash # 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:///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