ESPHome firmware for the Waveshare S3KM1110 24GHz mmWave presence sensor on an ESP32-S3-DevKitC-1 N16R8 (16MB Flash, 8MB Octal PSRAM).
- mmWave Presence Detection via patched LD2420 component (protocol-compatible with S3KM1110)
- Bluetooth Proxy for Home Assistant BLE integrations
- Zigbee Bridge to ESP32-C5 Coordinator via UART (JSON Lines protocol)
- GPIO Presence Output (hardware pin, no UART parsing needed)
- Web Server for local status/control
- Full Gate Configuration (16 gates, move/still thresholds)
| Component | Board | Module |
|---|---|---|
| Main MCU | SparkleIoT XH-S3E N16R8 | ESP32-S3 (16MB Flash, 8MB Octal PSRAM) |
| mmWave Sensor | Waveshare HMMD | S3KM1110 (24GHz) |
| Zigbee Coordinator | Waveshare ESP32-C5-WiFi6-KIT-NXRX 16R8 | ESP32-C5 (optional) |
Full pinout diagrams and wiring details: PINOUT.md
mmWave Sensor (S3 right header -> Sensor J2):
| S3 Pin | Sensor Pin (J2) |
|---|---|
| 3V3 | 3V3 (1) |
| GND | GND (2) |
| GPIO17 (TX) | RX (4) |
| GPIO18 (RX) | TX (3) |
| GPIO8 | OT2 (5) |
Zigbee Bridge (S3 right header -> C5 left header):
| S3 Pin | C5 Pin | Cable |
|---|---|---|
| GPIO15 (TX) | IO6 (RX) | Orange |
| GPIO16 (RX) | IO7 (TX) | White |
| 3V3 | 3V3 | Purple |
| GND | GND | Brown |
Note: GPIO35-37 are NOT available (used by Octal PSRAM on N16R8).
The stock ESPHome LD2420 component fails to initialize the S3KM1110 after software reboots (OTA, API restart, watchdog). The sensor becomes unresponsive because GPIO17 (UART TX) drops LOW during the ESP32 bootloader phase, which the sensor interprets as a UART break condition and enters an unrecoverable state.
-
gpio_hold_enon shutdown — Before any software restart, GPIO17 is detached from the UART peripheral, driven HIGH, and latched viagpio_hold_en(). The RTC hold keeps the pin HIGH through the entire reboot sequence (bootloader + app init), preventing the UART break. -
gpio_hold_dison setup — At the start of LD2420setup(), the hold is released so the UART driver can take control of the pin. -
UART RX buffer flush — Drains any buffered sensor data before attempting command mode, preventing streaming data from corrupting command framing.
-
get_firmware_intcrash fix — Preventsstoicrash when the sensor returns non-numeric version strings. -
Retry logic — If initial config mode fails, retries with full UART driver reset.
Hardware reset button: The
gpio_hold_enfix only covers software restarts. For hardware reset (EN pin), add an external 10kOhm pull-up resistor from GPIO17 to 3V3.
Add this as an external component source in your ESPHome YAML:
external_components:
- source:
type: git
url: https://github.com/moag1000/esphome-s3km1110
ref: main
components: [ld2420, zigbee_bridge]Clone and compile directly:
git clone https://github.com/moag1000/esphome-s3km1110.git
cd esphome-s3km1110
esphome run esp32-s3-mmwave.yamlCopy esp32-s3-mmwave.yaml and adjust:
substitutions— device nameapi.encryption.key— generate a new keyota.password— set your OTA passwordwifi— your network credentialsmqtt— broker address (if using Zigbee bridge)
MIT