Presence, including still people
Motion energy measured against an empty-room calibration. A still person read as empty 2.1% of the time on one link and 0.4% on two.
the pipeline
A dedicated transmitter gives the receiver a channel to measure. The receiver turns 20 channel snapshots a second into one 68-byte summary, twice a second. The gateway fuses those links into a space and decides what to report, and when to stay silent.
skip to the resultsThe same stages exist three times, in Python, Rust and C++, and all three must agree on the same golden vectors.
what it measures
Every number on this page comes from the simulator. None of it has been measured in a real room.
Motion energy measured against an empty-room calibration. A still person read as empty 2.1% of the time on one link and 0.4% on two.
A Goertzel scan of the breathing band, 8–24 BPM at rest, with a confidence that abstains instead of guessing. Only in spaces that opted in.
Presence held, no gross motion, and breathing-band energy below its own baseline for at least 10 s. None were reported in 70.6 h of timelines that had none.
Rate, loss, calibration age and noise floor. A space with no usable link reports “blind”, never “empty”.
Heart rate is the weak output. CSI amplitude is nonlinear in chest movement, so breathing harmonics and intermodulation can outshine the cardiac peak. Gated on confidence it is right 97% of the time, but it abstains on 39% of scenarios. It stays off until it has been measured against a reference.
Held-out seeds 2–7: 252 runs, 187 simulated hours, thresholds tuned on other seeds. SYNTHETIC. The simulator's body never sways or blocks line of sight, and real ESP32 noise is unmeasured.
link diversity
At 20 MHz an ESP32 sees a narrow slice of spectrum, so a person at the wrong spot on a Fresnel boundary can null every subcarrier at once. No subcarrier trick escapes that: at whole-band blind spots, breathing accuracy stayed near two thirds for every method tested. A second link from another angle rarely shares the same blind spot.
| held out, synthetic | 1 link | 2 links | 3 links |
|---|---|---|---|
| occupancy accuracy | 98.2% | 99.5% | 98.9% |
| still person read as empty | 2.1% | 0.4% | 1.3% |
| breathing reported, still breather | 93.6% | 100% | 100% |
| … within 1 BPM | 93.9% | 99.9% | 100% |
| breathing pauses caught | 81.5% | 89.9% | 88.7% |
More links are not always better: a third link slightly raised false occupancy here. 248 true pauses of 10–40 s were scored, with 98.5–98.7% precision.
position
We tested radio tomographic imaging on 4–12 simulated single-antenna nodes. In all 15 configurations it lost to a six-line weighted-link-midpoint estimator (0.71 m median error, synthetic), and it answered only 13–18% of the time. Until a real mesh shows it can do better, Saans reports per space, not per position.
keep reading