Initial firmware for ESP32-S3 six-channel soil moisture node
Implements ESP32_Soil_Moisture_Node_PRD.md on the VCC-GND Studio
YD-ESP32-S3 (ESP32-S3-WROOM-1) using Arduino via PlatformIO, publishing
to Home Assistant over MQTT with auto-discovery.
Two power profiles behind a compile-time switch (PRD 4):
-e mains always on, publishes every 60s
-e battery RTC wake, sample, publish, deep sleep 15min
PRD mitigations:
- All six probes on ADC1 (GPIO4-9); ADC2 is unusable while Wi-Fi is up.
- analogReadMilliVolts() for eFuse ADC calibration rather than raw counts.
- 16 samples per probe, sorted, 10% trimmed from each end, averaged.
- Per-probe two-point calibration; HW-390 output is inverted (dry reads
high), and an inverted config is rejected rather than silently producing
a backwards curve.
- MAC-derived node ID so identical binaries never collide on topics.
Design decisions that diverge from a literal reading of the PRD:
- Out-of-range probes publish null (HA "unknown") instead of clamping to
0%/100%. A cut Cat5 pair reads ~0mV, which clamps to a believable "very
dry" and would drive irrigation on wrong data.
- The battery profile uses expire_after rather than an availability topic;
a sleeping node is offline most of the time and would sit greyed out.
- AWAKE_BUDGET_MS forces deep sleep if a wake cycle overruns, covering
failure modes the per-step network timeouts miss (DHCP never issued,
CONNACK never sent) that would otherwise flatten the cell.
- docs/WIRING.md notes the 18650 cannot feed the probes directly: the
XC6206 LDO needs ~3.4V headroom, so a boost converter is required on the
switched side of the MOSFET.
Both profiles compile clean under -Wall. Not yet run on hardware; pin map,
MOSFET circuit and calibration defaults are unverified against a board.
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
commit
ad9c457ea7
24 files changed
+2178
No files matched your search
@@ -0,0 +1,78 @@
|
||||
# Product Requirements Document (PRD)
|
||||
**Project:** Scalable ESP32 Soil Moisture Monitoring Node
|
||||
**Target Audience:** AI Engineering Agents (Firmware, Hardware Design, Home Assistant Integration)
|
||||
|
||||
## 1. System Overview
|
||||
A modular, distributed soil moisture monitoring system designed to interface up to six HW-390 (v2.0) capacitive soil moisture sensors per local microcontroller node. The system utilizes Cat5 cabling for consolidated power distribution and analog signal collection. Data is gathered by an ESP32-class microcontroller and broadcasted over Wi-Fi for ingestion, recording, and automation by a Home Assistant server. The architecture supports multi-node deployments with conflict-free network identification and accommodates both continuous (mains) and remote (solar/battery) power profiles.
|
||||
|
||||
## 2. Hardware Architecture & Wiring Specifications
|
||||
|
||||
### 2.1 Microcontroller Unit (MCU)
|
||||
* **Supported Platforms:** ESP32-S3 (Primary), ESP32-C3, ESP32-S2, or standard ESP32.
|
||||
* **Requirements:** Must have at least 6 accessible ADC (Analog-to-Digital Converter) channels capable of reading 0-3.3V, Wi-Fi capabilities, and deep-sleep support for battery operations.
|
||||
|
||||
### 2.2 Cabling & Breakout
|
||||
* **Cable Type:** Standard 24 AWG solid-core Cat5/Cat5e cable.
|
||||
* **Pinout/Pairing Strategy:**
|
||||
* **Pair 1 (e.g., Orange/Orange-White):** `5V VCC` and `Shared GND`. (Crucial to keep power and ground on the same twisted pair to minimize loop area).
|
||||
* **Pair 2, 3, 4 (e.g., Green, Blue, Brown pairs):** Assigned to `Analog Signal 1` through `Analog Signal 6`.
|
||||
* **Termination:** Cat5 cable terminates at an RJ45 receiver/breakout board at the MCU enclosure.
|
||||
|
||||
### 2.3 Sensor Wiring & Protection (HW-390 v2.0)
|
||||
* **Power:** Sensors are supplied with 5V over the Cat5 cable. The HW-390 v2.0 onboard XC6206 LDO regulates this to a clean 3.3V locally at the sensor.
|
||||
* **Environmental Protection:** The upper PCB of all HW-390 sensors (components, exposed edges, and spliced connections) MUST be sealed with marine epoxy or conformal coating to prevent rapid outdoor degradation. Only the capacitive prongs remain unsealed.
|
||||
|
||||
## 3. Required Mitigations: Pitfalls & Solutions
|
||||
|
||||
To ensure system stability, subsequent AI agents designing the PCB/breadboard layout and firmware must implement the following solutions.
|
||||
|
||||
### 3.1 Hardware Mitigation: Signal Integrity & EMI
|
||||
* **Issue:** Cat5 is unshielded and tightly twisted, causing capacitive coupling (crosstalk) and EMI susceptibility for DC analog signals.
|
||||
* **Solution (Mandatory Hardware):** Implement an RC Low-Pass Filter on the RJ45 receiver board for every analog input line before it reaches the ESP32 ADC pin.
|
||||
* *Component Values:* 10kΩ inline resistor, 0.1µF to 1µF ceramic capacitor bridging the ADC pin to GND.
|
||||
|
||||
### 3.2 Hardware Mitigation: Ground Bounce
|
||||
* **Issue:** Six sensors sharing one Cat5 GND wire can cause the ground potential to float, altering analog readings.
|
||||
* **Solution:** All spliced connections on the sensor end must be soldered/heat-shrunk or secured with high-retention Wago connectors. Limit total sensor draw to ~30mA (5mA per sensor).
|
||||
|
||||
### 3.3 Software Mitigation: ESP32 ADC Non-Linearity & Signal Smoothing
|
||||
* **Issue:** ESP32 ADCs are non-linear, especially at extreme voltage ranges, and sandy/fast-draining soil creates rapid micro-fluctuations in moisture distribution.
|
||||
* **Solution (Mandatory Firmware):**
|
||||
* Employ the ESP32 hardware ADC calibration API.
|
||||
* **Oversampling:** The firmware must take an array of 10-20 readings per sensor per cycle, discard the highest and lowest 10% (outliers), and average the remaining values.
|
||||
* **Calibration:** Implement a two-point software calibration curve (Air = 0%, Water = 100%) to map the raw ADC integers to a percentage value.
|
||||
|
||||
## 4. Power Profiles & Management
|
||||
|
||||
The system must support two power topologies, determinable at compilation or runtime configuration:
|
||||
|
||||
### 4.1 Continuous Power (Mains)
|
||||
* Supplied via 5V USB or dedicated 5V buck converter.
|
||||
* MCU remains active, broadcasting updates at a set interval (e.g., every 60 seconds).
|
||||
|
||||
### 4.2 Solar / Battery Power (Remote Nodes)
|
||||
* **Hardware:** Integrates a LiPo/Li-Ion battery (e.g., 18650 cell) and a solar charge controller (e.g., TP4056 with protection circuitry) paired with a 5V/6V solar panel. (Highly compatible with automated solar drip irrigation setups).
|
||||
* **Firmware Deep Sleep:**
|
||||
1. Wake up based on RTC timer (e.g., every 15-30 minutes).
|
||||
2. Power on sensors (via a GPIO-controlled MOSFET switching the 5V line to save idle current).
|
||||
3. Stabilize (wait 500ms).
|
||||
4. Oversample, average, and map ADC readings.
|
||||
5. Connect to Wi-Fi, publish MQTT/ESPHome payload.
|
||||
6. Return to deep sleep.
|
||||
|
||||
## 5. Network Architecture & Home Assistant Integration
|
||||
|
||||
### 5.1 Multi-Node Identification (Conflict Prevention)
|
||||
* **Unique Addressing:** Firmware must dynamically generate a unique Node ID based on the ESP32's internal MAC address (e.g., `soil-node-A1B2C3`).
|
||||
* **Data Tagging:** All broadcasted data payloads must be tagged with this Node ID.
|
||||
|
||||
### 5.2 Communication Protocol
|
||||
* **Recommended Framework:** ESPHome is the primary recommended framework for seamless, native Home Assistant integration via the ESPHome API.
|
||||
* **Alternative:** Standard MQTT (via PubSubClient or similar). If using MQTT, the firmware must publish Home Assistant MQTT Auto-Discovery configuration payloads on startup so nodes populate automatically in the HA dashboard without manual YAML configuration.
|
||||
|
||||
### 5.3 Data Payload Requirements
|
||||
The node must expose the following entities to Home Assistant per cycle:
|
||||
* `sensor.node_[ID]_moisture_1` through `6` (Value: 0-100%, Unit: %, Device Class: Moisture)
|
||||
* `sensor.node_[ID]_battery_level` (If using solar profile, mapped from battery voltage via voltage divider)
|
||||
* `sensor.node_[ID]_wifi_signal` (RSSI)
|
||||
* `sensor.node_[ID]_uptime` (or last seen timestamp)
|
||||
Reference in new issue
Block a user