Added MQTT
This commit is contained in:
371
README.md
371
README.md
@ -1,232 +1,249 @@
|
||||
# ESP32-S3 WiFi OTA Template
|
||||
# ESP32-S3 Plant Watering System
|
||||
|
||||
A reusable template for ESP32-S3 projects featuring WiFi connectivity and Over-The-Air (OTA) firmware updates. This project is designed for the SparkFun ESP32-S3 Thing Plus but can be adapted for other ESP32-S3 boards.
|
||||
An automated plant watering system built with ESP32-S3, featuring MQTT communication, OTA updates, and remote monitoring/control capabilities.
|
||||
|
||||
## Features
|
||||
## Current Project Status
|
||||
|
||||
- 🌐 **WiFi Manager** - Automatic connection with credential storage in NVS
|
||||
- 🔄 **OTA Updates** - Web-based firmware updates with drag-and-drop interface
|
||||
- 💡 **RGB LED Control** - WS2812 driver for visual feedback (GPIO 46)
|
||||
- 🔧 **Docker-based Development** - No local ESP-IDF installation required
|
||||
- 📦 **Modular Design** - Easy to extend with additional features
|
||||
### ✅ 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
|
||||
|
||||
## Hardware Requirements
|
||||
### 🚧 In Progress
|
||||
- Motor control (TB6612FNG driver)
|
||||
- Moisture sensor reading
|
||||
- Automation logic
|
||||
|
||||
- SparkFun ESP32-S3 Thing Plus (or compatible ESP32-S3 board)
|
||||
- USB-C cable (data capable, not charge-only)
|
||||
- 2.4GHz WiFi network
|
||||
### 📋 TODO
|
||||
- Web dashboard
|
||||
- Home Assistant integration
|
||||
- Multiple zone support
|
||||
|
||||
## Project Structure
|
||||
## 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)
|
||||
```
|
||||
.
|
||||
├── main/
|
||||
│ ├── main.c # Main application
|
||||
│ ├── wifi_manager.c/h # WiFi connection management
|
||||
│ ├── ota_server.c/h # OTA update server
|
||||
│ ├── led_strip.c/h # RGB LED driver
|
||||
│ ├── CMakeLists.txt # Component configuration
|
||||
| └── Kconfig.projbuild # To store wifi ssid and pass
|
||||
├── partitions.csv # Flash partition table (4MB)
|
||||
├── sdkconfig # Project configuration (auto-generated)
|
||||
├── .gitignore # Git ignore rules
|
||||
└── README.md # This file
|
||||
CONFIG_WIFI_SSID="Your_SSID"
|
||||
CONFIG_WIFI_PASSWORD="Your_Password"
|
||||
```
|
||||
|
||||
## Quick Start
|
||||
### MQTT Settings (menuconfig)
|
||||
```
|
||||
CONFIG_MQTT_BROKER_URL="mqtt://192.168.1.100:1883"
|
||||
CONFIG_MQTT_USERNAME="plantwater"
|
||||
CONFIG_MQTT_PASSWORD="your_password"
|
||||
```
|
||||
|
||||
### 1. Prerequisites
|
||||
### 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)
|
||||
```
|
||||
|
||||
- Docker installed on your system
|
||||
- Git for version control
|
||||
- Terminal/command line access
|
||||
## Building and Flashing
|
||||
|
||||
### 2. Clone and Configure
|
||||
### Using Docker (Recommended)
|
||||
|
||||
#### Configure the project
|
||||
```bash
|
||||
# Clone the repository (or create new project)
|
||||
git clone <your-repo-url>
|
||||
cd esp32-s3-template
|
||||
|
||||
# Create the file main/Kconfig.projbuild
|
||||
touch main/Kconfig.projbuild
|
||||
```
|
||||
Fill it in with the following:
|
||||
```
|
||||
menu "Wi-Fi Configuration"
|
||||
|
||||
config WIFI_SSID
|
||||
string "WiFi SSID"
|
||||
default ""
|
||||
help
|
||||
The SSID of the WiFi network.
|
||||
|
||||
config WIFI_PASSWORD
|
||||
string "WiFi Password"
|
||||
default ""
|
||||
help
|
||||
The password of the WiFi network.
|
||||
|
||||
endmenu
|
||||
```
|
||||
Then fill in your SSID and Password
|
||||
|
||||
A new project can be started with:
|
||||
```bash
|
||||
docker run --user $(id -u):$(id -g) --rm -v $PWD:/project -w /project -it espressif/idf:latest idf.py create-project <project-name>
|
||||
docker run --user $(id -u):$(id -g) --rm -v $PWD:/project -w /project -it espressif/idf:latest idf.py menuconfig
|
||||
```
|
||||
|
||||
### 3. Build the Project
|
||||
|
||||
#### Build
|
||||
```bash
|
||||
docker run --user $(id -u):$(id -g) --rm -v $PWD:/project -w /project -it espressif/idf:latest idf.py build
|
||||
```
|
||||
|
||||
### 4. Flash to Device
|
||||
|
||||
#### 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
|
||||
```
|
||||
|
||||
> **Note**: Your device might appear as `/dev/ttyUSB0` or another port. Check with `ls /dev/tty*` after connecting.
|
||||
|
||||
### 5. Monitor Serial Output
|
||||
|
||||
#### 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
|
||||
```
|
||||
|
||||
Press `Ctrl+]` to exit the monitor.
|
||||
|
||||
## Using OTA Updates
|
||||
|
||||
1. **Connect to WiFi** - The device will automatically connect using stored credentials
|
||||
2. **Find IP Address** - Check serial monitor for "Got IP: xxx.xxx.xxx.xxx"
|
||||
3. **Open Web Interface** - Navigate to `http://<device-ip>/` in your browser
|
||||
4. **Upload Firmware**:
|
||||
- Build new version: Update `APP_VERSION` in main.c
|
||||
- Run build command again
|
||||
- Upload `build/<project-name>.bin` via web interface
|
||||
- Device will automatically restart with new firmware
|
||||
|
||||
### Testing OTA Updates
|
||||
|
||||
Try these modifications to test OTA:
|
||||
|
||||
```c
|
||||
// Version 2.0.0 - Faster blinking
|
||||
#define APP_VERSION "2.0.0"
|
||||
#define BLINK_DELAY_MS 200 // Was 500
|
||||
|
||||
// Version 3.0.0 - Different colors
|
||||
static const color_t colors[] = {
|
||||
{255, 128, 0, "Orange"},
|
||||
{128, 0, 255, "Purple"},
|
||||
{255, 192, 203, "Pink"},
|
||||
};
|
||||
#### 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
|
||||
```
|
||||
|
||||
## API Usage
|
||||
Note: Replace `/dev/ttyACM0` with your actual device port (could be `/dev/ttyUSB0`, `/dev/ttyACM1`, etc.)
|
||||
|
||||
### WiFi Manager
|
||||
### Using Local ESP-IDF Installation
|
||||
|
||||
```c
|
||||
// Set new credentials
|
||||
wifi_manager_set_credentials("NewSSID", "NewPassword");
|
||||
```bash
|
||||
# Configure the project
|
||||
idf.py menuconfig
|
||||
|
||||
// Check connection status
|
||||
if (wifi_manager_is_connected()) {
|
||||
// Connected
|
||||
}
|
||||
# Build
|
||||
idf.py build
|
||||
|
||||
// Clear stored credentials
|
||||
wifi_manager_clear_credentials();
|
||||
# Flash via USB
|
||||
idf.py -p /dev/ttyUSB0 flash monitor
|
||||
```
|
||||
|
||||
### OTA Server
|
||||
### 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
|
||||
|
||||
```c
|
||||
// Set version string
|
||||
ota_server_set_version("2.0.0");
|
||||
## Testing with MQTT
|
||||
|
||||
// Register progress callback
|
||||
ota_server_register_progress_callback(my_progress_handler);
|
||||
### 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
|
||||
```
|
||||
|
||||
### LED Control
|
||||
### 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"
|
||||
|
||||
```c
|
||||
// Set LED color
|
||||
led_strip_set_pixel(strip, 0, 255, 0, 0); // Red
|
||||
led_strip_refresh(strip);
|
||||
# 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 off
|
||||
led_strip_clear(strip);
|
||||
# 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
|
||||
|
||||
### Build Issues
|
||||
- Ensure Docker is running and you have internet connection
|
||||
- Clean build: `idf.py fullclean` before building
|
||||
|
||||
### Flash Issues
|
||||
- Check USB cable is data-capable (not charge-only)
|
||||
- Try different USB port
|
||||
- Verify device path (`/dev/ttyACM0`, `/dev/ttyUSB0`, etc.)
|
||||
- May need to add user to `dialout` group: `sudo usermod -a -G dialout $USER`
|
||||
### 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 2.4GHz network (ESP32 doesn't support 5GHz)
|
||||
- Check for special characters in SSID/password
|
||||
- Look for trailing spaces in SSID
|
||||
- Monitor serial output for specific error codes
|
||||
- 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 Issues
|
||||
- Ensure device has sufficient free space (check web interface)
|
||||
- Verify binary file size fits in OTA partition (1.25MB max)
|
||||
- Check same network connectivity between computer and ESP32
|
||||
### 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
|
||||
|
||||
## Memory Layout
|
||||
## Next Development Steps
|
||||
|
||||
| Partition | Type | Size | Purpose |
|
||||
|-----------|---------|---------|-------------------|
|
||||
| nvs | data | 16KB | WiFi credentials |
|
||||
| otadata | data | 8KB | OTA selection |
|
||||
| phy_init | data | 4KB | PHY calibration |
|
||||
| factory | app | 1.25MB | Factory firmware |
|
||||
| ota_0 | app | 1.25MB | OTA partition 1 |
|
||||
| ota_1 | app | 1.25MB | OTA partition 2 |
|
||||
1. **Motor Control Module**
|
||||
- PWM speed control
|
||||
- Safety timeouts
|
||||
- Current monitoring
|
||||
|
||||
## Security Considerations
|
||||
2. **Moisture Sensor Module**
|
||||
- ADC calibration
|
||||
- Averaging/filtering
|
||||
- Percentage conversion
|
||||
|
||||
For production deployments:
|
||||
- Add authentication to OTA web interface
|
||||
- Use HTTPS for OTA updates
|
||||
- Implement firmware signature verification
|
||||
- Store WiFi credentials securely
|
||||
- Consider encrypted flash storage
|
||||
3. **Automation Logic**
|
||||
- Threshold-based watering
|
||||
- Time-based schedules
|
||||
- Prevent overwatering
|
||||
|
||||
## Extending the Template
|
||||
|
||||
This template provides core functionality. Add your application-specific features:
|
||||
|
||||
1. **Remove LED code** if not using RGB LED
|
||||
2. **Add sensors** - I2C/SPI initialization in main.c
|
||||
3. **Add MQTT** - Build on WiFi manager callbacks
|
||||
4. **Add web API** - Extend OTA server with custom endpoints
|
||||
5. **Add BLE** - ESP32-S3 supports dual-mode
|
||||
|
||||
## License
|
||||
|
||||
[Your License Here]
|
||||
|
||||
## Acknowledgments
|
||||
|
||||
- Built with ESP-IDF v6.0
|
||||
- Designed for SparkFun ESP32-S3 Thing Plus
|
||||
- RGB LED driver uses RMT peripheral
|
||||
|
||||
---
|
||||
|
||||
For more information about ESP-IDF: https://docs.espressif.com/
|
||||
4. **Enhanced Features**
|
||||
- Web dashboard
|
||||
- Historical data logging
|
||||
- Multi-zone support
|
||||
- Weather API integration
|
||||
Reference in New Issue
Block a user