Actually I misspoke. I previously used STA/AP mode (and two ESP32s) but I switched to something close to what you describe. I filter the pings to only get the ones targeting a specific MAC (in promiscuous mode). This way I get only specific CSI packets and they're perfectly periodic at whatever rate I want.
Sounds like your MVS approach is a sliding window variance of the cross channel variance, with some adaptive thresholding. My pre-processing has generally been an EWMA de-meaning filter followed by some type of dimensionality reduction and feature extraction (kernel or hand-crafted, like raw moments), which I think fits into your overall architecture.
I'll have to look more closely at your work, thanks for sharing!
Interesting note, I actually disabled promiscuous mode after some testing because it made the CSI signal noisier and consumed more resources. I found that normal station mode with pings to gateway gave me cleaner, more predictable CSI data. But your MAC filtering approach might mitigate those issues!
You're spot on about the MVS approach. It's essentially a sliding window variance of the spatial turbulence (std dev across subcarriers), with adaptive thresholding based on the moving variance of that signal.
If you're interested in the MVS details, I wrote a free Medium article that walks through the segmentation algorithm step-by-step with visualizations. Links are in the README.
Your approach is actually quite similar to what I'm doing, just in a different order:
- My flow: Raw CSI → Segmentation (MVS) → Filters (Butterworth/Wavelet/Hampel/SG) → Feature extraction
- Your flow: Raw CSI → EWMA de-meaning → Dimensionality reduction → Feature extraction
The main difference is that I segment first to separate IDLE from MOTION states (keeping segmentation on raw, unfiltered CSI to preserve motion sensitivity), then only extract features during MOTION (to save CPU cycles).
Thanks for the thoughtful feedback! Always great to exchange notes with someone who's been in the trenches with CSI signal processing