[HN Gopher] Show HN: ESPectre - Motion detection based on Wi-Fi ...
___________________________________________________________________
Show HN: ESPectre - Motion detection based on Wi-Fi spectre
analysis
Hi everyone, I'm the author of ESPectre. This is an open-source
(GPLv3) project that uses Wi-Fi signal analysis to detect motion
using CSI data, and it has already garnered almost 2,000 stars in
two weeks. Key technical details: - The system does NOT use
Machine Learning, it relies purely on Math. -- Runs in real-time on
a super affordable chip like the ESP32. - It integrates seamlessly
with Home Assistant via MQTT.
Author : francescopace
Score : 91 points
Date : 2025-11-17 14:40 UTC (8 hours ago)
(HTM) web link (github.com)
(TXT) w3m dump (github.com)
| tetris11 wrote:
| Amazing stuff!
|
| Am I right in understanding that only a single ESP32 device is
| needed (plus a router)?
| pmontra wrote:
| Probably one per room because all the examples at
| https://github.com/francescopace/espectre/blob/main/CALIBRAT...
| are about a single room.
|
| Is the author reads this, how does the system cope with
| multiple rooms in the same house, maybe a two or three storeys
| house?
| francescopace wrote:
| Yes, you're both correct:
|
| You need one sensor for each area you want to monitor
| independently. With devices more capable than the ESP32-S3,
| the coverage would likely be greater.
|
| The ESP32-C6, in particular, offers significantly better
| performance. Check out this comparison video from Espressif:
| https://www.youtube.com/watch?v=JjdpzM6zVJ8
| yoavm wrote:
| How about if I want to monitor the apartment as a whole?
| Would 100m2 be too much for one sensor to handle?
| francescopace wrote:
| It really depends on the environment: wall materials,
| interference, signal strength, and even temperature and
| humidity all play a role. Honestly, 100 m2 is probably
| too large for a single sensor to cover reliably.
|
| That said, ESP32 boards are very inexpensive, you can
| find them online for around EUR1 or even less.
| yoavm wrote:
| Is the ESP-S3 your recommendation? Or should one look
| into the ESP-C6 / another model? The prices I'm seeing
| here in Sweden are more around EUR10 rather than EUR1,
| but I guess that's still much less than the average
| presence detector.
| roger_ wrote:
| Been working on this very idea casually for couple years with
| ESP-IDF and I could never get the statistical signal processing
| just right (by my definition). Things I've tried: adapting
| filtering (LMS, Kalman), kernel methods (NEWMA, MMD), detectors
| (CUSUM, GLR), dimensionality reduction (random projection, online
| PCA), whitening, etc.
|
| I use a single ESP32 in STA/AP mode which sniffs ACK packets with
| a specific destination mac, which come from any server on my WiFi
| network (uses a special sniffing mode IIRC). This way I can
| receive regular CSI packets originating from a fixed location and
| doesn't need another device running.
|
| I'll have to look at this code, maybe I just overlooked the
| obvious or my requirements were too high!
| francescopace wrote:
| ESPectre takes a different architectural approach that might
| address some of the challenges you encountered:
|
| 1. Instead of STA/AP mode on a single ESP32, ESPectre uses the
| natural traffic between your existing router and an ESP32-S3 in
| station mode. To ensure a stable, continuous CSI packet rate, I
| implemented a traffic generator that sends ICMP pings to the
| gateway at a configurable rate (default: 20 pps). This provides
| bidirectional traffic (request + reply) that reliably triggers
| CSI generation, giving you predictable packet timing without
| relying on ambient network traffic or special sniffing modes.
|
| 2. Rather than applying filters directly to raw CSI, ESPectre
| uses Moving Variance Segmentation (MVS) on unfiltered spatial
| turbulence (std dev of subcarrier amplitudes).
|
| 3. The filters are applied to features, not to the segmentation
| signal itself. This preserves motion sensitivity while cleaning
| up the feature data
|
| I found that having a stable transmitter (the router) combined
| with controlled traffic generation provides more consistent
| multipath patterns and predictable CSI timing, which makes the
| segmentation more reliable.
| roger_ wrote:
| 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!
| francescopace wrote:
| 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
| Gys wrote:
| Interesting! Are you familiar with tommysense.com? I think it
| doing something similar? Did not yet have time to try it.
| francescopace wrote:
| Tommysense creates a sensing mesh between devices, while
| ESPectre uses your existing Wi-Fi router as the transmitter. As
| a result, ESPectre needs only one device per area but requires
| a compatible router with solid 2.4 GHz coverage. The overall
| goal is similar, but ESPectre is open-source!
| acl wrote:
| Would this work with a mesh router?
| francescopace wrote:
| Sure, the ESP32 will connect to whichever mesh node provides
| the best 2.4 GHz signal
|
| - It monitors CSI from that specific node (the one it's
| associated with)
|
| - If the ESP32 roams to a different mesh node, it will start
| monitoring CSI from the new node
|
| The system doesn't care about the router's internal mesh
| topology, it just needs a stable connection to receive CSI data
| from the associated access point.
| francescopace wrote:
| Fun fact: I'm working on turning ESPectre into a Wi-Fi Theremin
| (the musical instrument you play by moving your hands near an
| antenna).
|
| The idea of "playing" by simply moving around a room sounds a bit
| ridiculous... but also kind of fun.
|
| The key is the Moving Variance of the spatial turbulence: this
| value is continuous and stable, making it perfect for mapping
| directly to pitch/frequency, just like the original Theremin.
| Other features can be mapped to volume and timbre.
|
| It's pure signal processing, running entirely on the ESP32. Has
| anyone here experimented with audio synthesis or sonification
| using real-time signal processing?
___________________________________________________________________
(page generated 2025-11-17 23:00 UTC)