Commit Graph
2 Commits
Author SHA1 Message Date
mattandClaude 9c1c3fe1e8 Add YD-ESP32-S3 support, boot diagnostics, and hang guards
Board is now selected by `default_envs` in platformio.ini rather than being
hardcoded. Both boards stay supported and both targets build.

- src/board_pins.h holds one block per board plus an ledSet() abstraction, so
  main.cpp has no board-specific code. The C6's active-low LED and the S3's
  WS2812 RGB go through the same call, and the C6 antenna-switch lines are
  behind #if HAS_RF_SWITCH.
- YD-ESP32-S3 env targets esp32-s3-devkitc1-n16r8 (verified against the actual
  part: ESP32-S3 rev v0.2, 16MB quad flash, 8MB octal PSRAM, CH343 bridge).
  Serial is UART0 -> CH343, not USB CDC.

Fixes for hangs that left the board alive on USB but dead on the network:

- The vendor library's UART path has loops with no timeout: sensorStop() is
  while(1) that only exits on a "sensorStop" reply, and the UART branch of
  getStatus() is while(len == 0). Calling either with no sensor attached hung
  setup() permanently. UART is now probed with a raw 1.5s read on Serial1, and
  the library only gets the port once bytes actually arrive. The I2C path is
  bounded, so prefer I2C.
- Floating SDA/SCL can stall Wire.endTransmission() forever. Check both lines
  read high with pull-ups before touching Wire.
- Serial.setTxTimeoutMs(0) is a trap: HWCDC::write seeds a uint32_t from it and
  does a bare tries--, so 0 underflows to 4.29e9 and spins for ~49 days. Use 10,
  and only on USB CDC boards.

Diagnostics, so "did it crash?" is answerable without a serial cable:

- Boot count in RTC memory, esp_reset_reason(), free/min heap and WiFi drop
  count exposed via /api/live and shown as header pills in the UI.
- WiFi auto-reconnect, and retry of station mode from the AP fallback. Without
  it a single dropout left the board unreachable forever, which looks exactly
  like a crash.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-14 11:55:03 -07:00
mattandClaude b9162db707 XIAO ESP32-C6 + DFRobot C4001 mmWave presence sensor
Firmware for a Seeed XIAO ESP32-C6 driving a C4001 24GHz radar, with a
web UI for live data and calibration.

- Auto-detects whether the C4001 is on I2C (0x2A/0x2B) or UART, so the
  board's mode switch position doesn't matter. Serves the probe log over
  HTTP when nothing is found.
- Single-page UI inlined into flash (no CDN, so it works in AP mode):
  presence state, target count, range, speed, energy, rolling 60s chart,
  and mode-aware calibration controls.
- Joins WiFi from a gitignored include/secrets.h, falls back to a
  "xiao-mmwave" AP, registers mmwave.local.
- Poll rate adapts to the interface: UART at 9600 costs ~60ms per register
  round-trip, so polling it at the I2C rate starved the HTTP server.

Two hardware gotchas documented in the README:

- The sensor UART must not use D6/D7. Those are GPIO16/17, the C6's
  hard-wired U0TXD/U0RXD. Pointing Serial1 at them deadlocks the UART
  driver and trips the interrupt watchdog, boot-looping the board. UART1
  has no fixed pins, so it routes through the GPIO matrix to D10/D9.
- DFRobot's own wiring table pairs the sensor's RX with the MCU's RX, and
  their library swaps the rxpin/txpin parameter names between the header
  and the .cpp.

Verified on ESP32-C6FH4 rev v0.1, 4MB flash: builds at 57.6% flash /
11.9% RAM, flashes over the native USB Serial/JTAG port, and reads a live
C4001 on I2C @ 0x2A.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-14 10:05:27 -07:00