Files
soilMoistureSystem/platformio.ini
T
mattandClaude ad9c457ea7 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>
2026-08-14 13:38:41 -07:00

53 lines
1.7 KiB
INI

; ESP32-S3 6-channel soil moisture node
; Board: VCC-GND Studio YD-ESP32-S3 (ESP32-S3-DevKitC-1 clone, ESP32-S3-WROOM-1)
;
; Two power profiles, selected by which environment you build:
; pio run -e mains -t upload ; always-on, 5V USB / buck
; pio run -e battery -t upload ; 18650 + TP4056 + solar, deep sleep
[platformio]
default_envs = mains
[env]
platform = espressif32@^6.5.0
board = esp32-s3-devkitc-1
framework = arduino
; YD-ESP32-S3 ships in several flash/PSRAM variants (N8, N8R2, N8R8, N16R8).
; These flags target the common N16R8 (16MB flash, 8MB octal PSRAM).
; For an N8 board with no PSRAM, drop the two BOARD_HAS_PSRAM/OPI lines
; and set board_upload.flash_size / board_build.partitions accordingly.
board_build.flash_mode = qio
board_build.partitions = default_16MB.csv
board_upload.flash_size = 16MB
monitor_speed = 115200
monitor_filters = esp32_exception_decoder, time
lib_deps =
knolleary/PubSubClient@^2.8
bblanchon/ArduinoJson@^7.0.4
build_flags =
-DARDUINO_USB_MODE=1
-DARDUINO_USB_CDC_ON_BOOT=1
-DBOARD_HAS_PSRAM
-DCORE_DEBUG_LEVEL=3
-Wall
; ---------------------------------------------------------------------------
; Continuous power: MCU stays awake, publishes on a fixed interval.
; ---------------------------------------------------------------------------
[env:mains]
build_flags =
${env.build_flags}
-DPOWER_PROFILE_MAINS
; ---------------------------------------------------------------------------
; Solar / battery: RTC-timer wake, sample, publish, deep sleep.
; ---------------------------------------------------------------------------
[env:battery]
build_flags =
${env.build_flags}
-DPOWER_PROFILE_BATTERY