Skip to main content

ESPectre Implementation on NM-CYD-C5

This solution ports the WiFi CSI human motion detection of ESPectre to the NM-CYD-C5, using the on-board display and touch panel to provide a real-time curve, threshold adjustment, and one-tap calibration. The implementation is entirely driven by the ESPHome configuration — no changes to the ESPectre C++ component are required.

ESPectre running on NM-CYD-C5

Hardware Mapping​

FunctionPinsImplementation Notes
SPISCK=GPIO6, MISO=GPIO2, MOSI=GPIO7Shared bus for LCD, touch panel, and SD card
LCDCS=GPIO23, DC=GPIO242.8-inch ST7789, 320×240, using ESPHome mipi_spi
BacklightGPIO25Active high, controlled by the display component's enable_pin
Touch panelCS=GPIO1XPT2046 resistive touch, polling mode
SD cardCS=GPIO10Not used by the current firmware
RGB LEDGPIO27Not used by the current firmware; can be extended as a motion indicator
MCUESP32-C5-WROOM-116 MB Flash, 8 MB PSRAM

Reference touch calibration range: X: 185–3700, Y: 250–3800. Resistive touch panels vary between units; if the button positions are offset, fine-tune touchscreen.calibration in the ESPHome configuration based on the actual readings of your device.

Visualization Data​

The existing entities of the ESPectre component already cover everything the screen interaction needs — no new component interfaces are required:

Data or StateESPHome EntityScreen Use
Movement scoremovement_sensorPlots the real-time motion curve
Motion statemotion_sensorShows IDLE or MOTION
Movement Thresholdthreshold_numberDraws the threshold line and receives touch adjustments
Calibration statecalibrate_switchTriggers recalibration and shows the calibration status
WiFi signalwifi_signalShows RSSI

Movement is published about once per second by default. The screen keeps 272 samples, providing roughly 4.5 minutes of scrolling history. The Y axis auto-scales based on the historical peak and the current threshold; curve segments above the threshold are drawn in red, and the rest in cyan.

Screen Layout​

┌──────────────────────────────────────────────┐
│ 192.168.1.100 MOTION / IDLE / CAL MVS │
├──────────────────────────────────────────────┤
│ ╭─╮ Movement curve (cyan) │
│ ╱ ╲╭─╮ over-threshold (red) │
│ - - - - - - - - Threshold (yellow dash) │
├──────────────────────────────────────────────┤
│ 1.83 mv 1.10 thr -55 dBm │
├────────────┬──────────────────┬──────────────┤
│ THR -0.5 │ CALIBRATE │ THR +0.5 │
└────────────┴──────────────────┴──────────────┘

The top status bar shows the IP address, detection state, and algorithm; the middle area shows the scrolling curve; the three touch zones at the bottom lower the threshold, recalibrate, and raise the threshold.

Touch Interaction​

ButtonActionBehavior
THR -0.5Calls number.setLowers the manual threshold by 0.5, down to a minimum of 0
CALIBRATETurns on calibrate_switchRe-selects subcarriers and computes an adaptive threshold
THR +0.5Calls number.setRaises the manual threshold by 0.5, up to a maximum of 10

Manual adjustments take effect immediately but only persist for the current session; after a reboot the threshold is recomputed from the YAML configuration or the calibration result. Calibration usually takes about 10 seconds, during which the device and its surroundings should remain still.

Refresh and Shared-SPI Constraints​

The LCD and the XPT2046 share the same SPI bus. Display refreshes must be executed uniformly in the ESPHome main loop — the display must not be updated directly from the entity callbacks of Movement, Motion, Threshold, or Calibrate.

It is recommended to set the display component to update_interval: never and trigger redraws from a 1-second interval instead. Entity callbacks only update in-memory state, and the main loop reads the state and refreshes the screen. This prevents display writes and touch polling from contending for the bus simultaneously, which would trigger an spi_master: Cannot acquire bus when a polling transaction is in progress assertion and reboot the device.

Future Extensions​

  • Expose the gain-lock state as a diagnostic entity and show it in the status bar;
  • Expose the calibration sample count to show real calibration progress;
  • Add a diagnostic view of the selected CSI subcarriers;
  • Use the on-board RGB LED as a motion indicator;
  • Turn off the backlight after prolonged inactivity and wake it with a touch.

Next, see the ESPectre × NM-CYD-C5 Usage Guide.