Detector architecture
ESPectre runs both detector profiles on the device. They consume the same timestamped CSI stream and publish the same runtime snapshot and motion events; the profile changes the feature state, classifier, startup behavior, and runtime cost.
One physical-time pipeline
The detector targets 100 admitted CSI samples per second. Each packet is assigned to a 10 ms slot, but only the packet nearest that slot's center is retained. Missing slots remain missing, and several packets arriving in the same slot still contribute one sample. This keeps detector evidence tied to elapsed time instead of packet count, so an access-point burst cannot advance the feature window faster than the physical-time grid.
A decision window covers one second and becomes ready at 70% slot occupancy. The runtime evaluates it every 250 ms. A gap resets temporal state instead of stitching two unrelated periods together.
Frequency paths follow the feature
ESPectre does not search for a different subcarrier set in every room. Both profiles use twelve fixed tones distributed across the usable HT20 band for temporal turbulence: ±4, ±9, ±14, ±19, ±24, ±28 in centered coordinates. The set came from measured channel-coherence behavior rather than a search over detector metrics, then remained fixed so every session uses the same frequency geometry.
| Signal view | Frequency input | Used by |
|---|---|---|
| Temporal turbulence | 12 fixed tones across the usable band | Both profiles |
| Aggregated turbulence | Five-bin neighborhoods around the 12 tones | Both profiles |
| L1 displacement | The same 12 fixed tones | High Accuracy |
| Channel shape | All 56 live HT20 bins, reduced to 8 gain-normalized subbands | High Accuracy |
The twelve-tone path is therefore not the whole High Accuracy input. Its channel-shape features retain a normalized view of the full live band, while the narrower path keeps the temporal trackers small. Ratios, correlations, crossing rates, and normalized geometry limit sensitivity to absolute receive gain while AGC remains enabled.
Two profiles, one integration contract
| Lightweight | High Accuracy | |
|---|---|---|
| Decision input | 2 engineered features | 8 engineered features |
| Classifier | Fixed weighted logistic fusion | MLP: 8 → 24 → 12 → 1 |
| Learned parameters | None | 529 |
| Startup threshold | Adapts from clean equivalent slot coverage | Uses a default threshold of 0.5 without startup calibration |
| Runtime cost | Lower feature state and compute | Additional temporal and channel-shape work |
Lightweight combines temporal autocorrelation with a robust turbulence-spread ratio. Its startup calibration needs ten seconds of clean, ready slot coverage; because missing slots do not count, wall-clock calibration may take longer.
High Accuracy adds temporal, displacement, and channel-shape features before inference. The current production export has 492 connection weights and 37 biases: 529 parameters in total, or 2,116 bytes when stored as 32-bit floats. The C++ detector evaluates those generated arrays directly and does not depend on a separate neural-network runtime.
Why the model can stay small
The classifier does not start from raw CSI. Temporal admission has already restored a physical-time axis, the selected frequency views have reduced redundancy, and the eight inputs describe normalized motion and channel-shape behavior. The network only has to combine that compact representation. The 529-parameter count describes the current production export; it is not a promise that this topology will never change or a claim that no smaller model could work.
On-device performance
Normal detection does not send CSI to a computer for processing. Capture, temporal admission, feature extraction, and inference all run on the ESP32. Once the one-second feature window is ready, the runtime evaluates the selected profile four times per second.
The High Accuracy path evaluates 492 matrix weights through fixed C++ loops and reuses its feature trackers and activation workspace. It performs more work than Lightweight, but neither profile allocates memory for each inference. The firmware benchmarks instrument the complete detection path, including feature extraction; their timings should not be read as isolated MLP latency.
Current selection + holdout diagnostic
The generated performance report compares both profiles on the same 13 real dataset pairs from the combined selection + holdout corpus. Both detectors receive identical base + drift + burst-loss augmentation generated from the same two fixed seeds. The device columns are unweighted arithmetic means of the Native campaign averages reported for ESP32, ESP32-C3, ESP32-C5, ESP32-C6, and ESP32-S3.
| Detection profile | Recall | False-positive rate | F1 | Mean device path | Mean runtime CPU |
|---|---|---|---|---|---|
| Lightweight | 98.8% | 0.8% | 98.6% | 0.700 ms | 3.21% |
| High Accuracy | 99.4% | 0.1% | 99.5% | 2.943 ms | 3.52% |
Select the profile through the runtime
Set the profile before setup(). The full runtime then owns temporal admission, evaluation cadence, readiness, and hit filtering.
espectre::RuntimeConfig config;
config.detection_algorithm =
espectre::DetectionAlgorithm::HIGH_ACCURACY;
espectre::RuntimeFrontendController runtime;
runtime.set_config(config);
runtime.setup(listener);
Use DetectionAlgorithm::LIGHTWEIGHT for the lower-cost profile. A core-only integration may instantiate the detector classes directly, but it must reproduce the runtime's timing, readiness, gap-reset, and hit-filter contracts. See the architecture reference before choosing that path.
Evidence and limits
The algorithm reference specifies the temporal and frequency contracts, and the feature ledger records evaluated features and their evidence. The generated replay and firmware reports remain the sources of truth for the current quality, timing, and resource measurements summarized above.