ESP32 CSI human detection: a practical, calibrated setup
2026-10-11 · 2 min read
ESP32 CSI human detection is the cheapest way to get a working Wi-Fi sensing demo. The hard part is not capture — it is calibration and gating. Here is a setup that survives a real room.
1. Capture
| Path | Tool | Output |
|---|---|---|
| Minimal | espressif/esp-csi examples [2] |
CSR/CIR data over UART or Wi-Fi |
| Dataset-friendly | ESP32-CSI-Tool [3] |
CSV of amplitude/phase per subcarrier |
| Home Assistant | ESPectre (ESPHome) [4] |
presence/motion entity directly |
Keep one ESP32 as a sender (UDP packets at a fixed rate) and one as the receiver; independent Wi-Fi traffic makes the measurement rate jump around.
2. Features that work
import numpy as np
# H: (time, subcarriers) amplitude matrix (30-64 subcarriers on ESP32)
detail = np.abs(np.diff(H, axis=0)).mean(axis=1) # inter-packet change
var = H.var(axis=1) # per-packet variance
motion = 0.5 * detail + 0.5 * var # cheap fusion
Do not feed raw CSI into a threshold — normalize per subcarrier first, otherwise a single noisy subcarrier dominates. Amplitude-variance features of this kind are standard for CSI activity recognition [1].
3. Calibrate with hysteresis (the part demos skip)
ENTER, EXIT = 3.0, 1.5 # tune per room; ENTER > EXIT
state, hold = False, 0
for m in motion:
if not state and m > ENTER:
state, hold = True, 0
elif state and m < EXIT:
hold += 1
if hold > 5: # ~0.5 s of quiet before leaving
state = False
else:
hold = 0
Record quiet and active baselines per room, then set ENTER ≈ quiet_mean + 4σ and EXIT ≈ quiet_mean + 2σ.
4. Why demos fail in real rooms
| Failure | Cause | Fix |
|---|---|---|
| Works in the office, not at home | different multipath baseline | recalibrate per room |
| False positives when nobody moves | HVAC, curtains, pets | longer windows + higher ENTER |
| Misses a still person | no micro-motion | add respiration detection or an mmWave sensor |
| Random dropouts | ESP32 shares the channel with home Wi-Fi | fixed sender + channel planning |
5. When to switch to a router
If you want whole-home coverage without scattering ESP32 boards, a CSI-capable router does the same job with 80 MHz / 256 subcarriers and 8 chains — see the router guide and the ESP32 vs router comparison.
Related: Home Assistant integration · vs mmWave radar · Wi-Fi CSI radar
References and data sources
Every external claim carries a source and an evidence grade (grading scheme). Grade E marks first-party, reproducible measurements from this project.
- Grade A · standard/review
WiFi Sensing with Channel State Information: A Survey
W. Ma, W. Zhou, X. Wang · ACM Computing Surveys · 2019
doi:10.1145/3310194 · citations 857 · verified: CrossRef API, 2026-10-11 · The field's most-cited CSI sensing survey (857 citations, verified via CrossRef). - Grade C · official docs
espressif/esp-csi — Applications based on Wi-Fi CSI
Espressif Systems
github.com/espressif/esp-csi · verified: GitHub API 2026-10-11 (stars 1,679) · The official README states: "All ESP32 series support CSI, including ESP32 / ESP32-S2 / ESP32-C3 / ESP32-S3 / ESP32-C5 / ESP32-C6 / ESP32-C61." - Grade C · official docs
StevenMHernandez/ESP32-CSI-Tool — active/passive CSI extraction for ESP32
S. M. Hernandez
github.com/StevenMHernandez/ESP32-CSI-Tool · verified: GitHub API 2026-10-11 (stars 571, MIT, last push 2024-07-16) - Grade C · official docs
francescopace/espectre — Wi-Fi CSI motion sensing for ESP32 (ESPHome)
F. Pace
github.com/francescopace/espectre · verified: GitHub API 2026-10-11 (stars 9,505)
This page contains affiliate links (rel="sponsored"). Buying through them costs you nothing extra and earns this site a small commission.