Imported from otaka44/watage-tsuchimiru-robot (
code/AGENTS.md). Install upstream withnpx skills add otaka44/watage-tsuchimiru-robot --skill code. Copyright stays with the author.
AGENTS.md
Project
Battery-powered capacitive soil-moisture indicator/controller using:
- M5Stack Stamp-S3Bat
- PlatformIO
- Arduino framework
- ESP32-S3 built-in capacitive touch peripheral
- M5PM1 power management and controllable
EXT_5V_OUT - Positional servo
- selectable M5PM1 timed shutdown or ESP32-S3 Deep Sleep between measurements
Primary design goals
- Low battery consumption.
- Reliable soil-moisture state detection rather than absolute moisture percentage.
- Prefer measurement quality over short active time.
- Keep firmware small and easy to understand.
- Do not use Wi-Fi, Bluetooth, BLE, ESP-NOW, or any RF feature.
- Servo must only be powered when movement is required.
- Wake roughly once per minute, measure carefully, act if necessary, then return to the selected low-power state.
Hardware assumptions
- Board: M5Stack Stamp-S3Bat, ESP32-S3-PICO-1-N8R8
- Flash: 8 MB
- PSRAM: 8 MB Octal
- Intended supply: 3.7 V lithium battery input
- Moisture electrode: Stamp pad G1 / ESP32-S3 GPIO1 / TOUCH1
- Touch electrode series resistor: about 510 ohm near the touch input
- Servo signal: Stamp pad G2 / ESP32-S3 GPIO2
- Servo power: Stamp-S3Bat
EXT_5V_OUT, controlled by M5PM1 GPIO1 /5VOUT_EN - M5PM1 internal I2C: GPIO48=SDA, GPIO47=SCL, address 0x6E
- Stamp-S3Bat and servo GND must be common.
EXT_5V_OUToperation is not guaranteed when powered through the 3V3 input; use the intended battery input for battery testing.- The public specifications do not state a guaranteed maximum
EXT_5V_OUTload current. Verify the selected servo's running/stall current and measure the 5 V rail under load before accepting this power path.
GPIO3 is an ESP32-S3 strapping pin and is not used for the permanent sensor or servo connection.
Firmware behavior
Production flow:
- Wake from the selected timer strategy.
- Initialize M5PM1 and explicitly ensure
EXT_5V_OUTis OFF. - Initialize/configure capacitive touch measurement.
- Allow settling/warm-up.
- Take many measurements.
- Use robust filtering (currently a 10% trimmed mean; median and spread are also useful diagnostics).
- Classify DRY/WET using calibrated references and hysteresis.
- Move servo only on a state transition, except once when no stored state exists.
- Remove PWM signal and make the signal pin high impedance before/when cutting servo power.
- Enter M5PM1 timed shutdown or ESP32-S3 Deep Sleep for about 60 seconds.
DRY/WET state is retained in RTC memory for ESP32-S3 Deep Sleep. M5PM1 timed shutdown removes ESP32 power, so that strategy stores state in NVS only on the initial classification or an actual state transition. Never write flash once per minute.
The sleep strategy is selected in src/config.h. M5PM1 timed shutdown is the current default for hardware evaluation; compare both strategies with measured standby current before treating it as final.
Touch measurement strategy
The ESP32-S3 touch peripheral measures time for a configured number of charge/discharge cycles.
Important:
- Do not optimize primarily for shortest active time.
- It is acceptable to spend hundreds of milliseconds, or more if measurements justify it.
- Tune the hardware measurement cycle count based on measured separation and noise.
- Start around a hardware-measurement duration near the Espressif guidance (~1 ms), then test longer settings.
- Do not assume a larger raw number is automatically better.
- Compare signal separation against noise/spread.
- Collect enough independent samples to reject outliers and environmental noise.
- Keep a sensor-test mode that prints raw statistics.
Before changing low-level touch APIs, verify the API against the exact Arduino-ESP32 / ESP-IDF version selected by PlatformIO. ESP32 and ESP32-S3 touch peripherals differ; do not copy old ESP32 examples blindly.
RF policy
Wireless is intentionally absent.
- Do not initialize Wi-Fi.
- Do not initialize Bluetooth/BLE.
- Do not add RF libraries unless explicitly requested.
- Low-power operation must use either M5PM1 timed shutdown or ESP32-S3 Deep Sleep between periodic measurements.
Environments
platformio.ini contains two environments:
sensor_test: diagnostic/calibration firmwareproduction: low-power production behavior
Useful commands:
pio run -e sensor_test
pio run -e sensor_test -t upload
pio device monitor -b 115200
pio run -e production
pio run -e production -t upload
Calibration workflow
- Run
sensor_test. - Test the sensor in its actual mechanical installation.
- Record DRY data over repeated measurements.
- Record WET data over repeated measurements.
- Compare candidate touch-cycle settings using:
- DRY/WET separation
- median
- trimmed mean
- p10-p90 spread
- repeatability over time
- Choose a setting with good separation-to-noise ratio.
- Put measured DRY/WET references in
src/config.h. - Test production hysteresis around the transition region.
Do not invent calibration numbers.
Coding style
- Prefer simple, explicit embedded code.
- Avoid unnecessary abstractions and dependencies.
- Keep hardware constants in
src/config.h. - Add comments only where hardware behavior or a non-obvious tradeoff needs explanation.
- Avoid dynamically allocated containers in the measurement path when a fixed-size buffer works.
- Fail safe: if calibration is invalid or sensor data is clearly invalid, do not actuate the servo unexpectedly.
- Preserve the ability to inspect raw sensor statistics during development.
Validation expectations
For firmware changes, at minimum:
pio run -e sensor_testpio run -e production
When hardware is attached, also validate:
- serial output in
sensor_test - measured touch stability
EXT_5V_OUTtruly turns offEXT_5V_OUTvoltage during servo movement and peak/stall-like load- ESP32-S3 reset/brownout behavior during servo movement
- no back-powering through servo signal
- current consumption during both M5PM1 timed shutdown and ESP32-S3 Deep Sleep
- current consumption during touch measurement
- current consumption and voltage sag during servo movement
Do not claim a hardware behavior was verified unless it was actually measured on the physical device.
Git workflow
- Keep completed project changes traceable through Git commits.
- Commit only after the relevant builds/checks pass.
- Use focused commits and messages that state the purpose of the change.
- Write commit messages in Japanese.
- Do not mix unrelated user changes into a task commit.