Radar has worked this way for a century: send out a radio wave, watch how it comes back. Wi-Fi sensing does the same thing with the Wi-Fi signal you already have, and a cheap ESP32 is enough to see the effect for yourself.
01The core idea
When a Wi-Fi radio sends a packet, the signal does not travel in a single straight line. It takes the direct path to the receiver and also bounces off walls, the floor, furniture and anything else in the room. The receiver hears the sum of all those copies, each arriving with a slightly different delay and strength.
A human body is mostly water, which reflects and absorbs 2.4 GHz energy well. So when a person moves, the reflected copies shift, and the combined signal at the receiver changes measurably. Measure that change continuously and you can tell that something moved, roughly how much, and often whether a person is present at all, all without a camera.
02RSSI vs CSI: why one number is not enough
Every Wi-Fi device already reports RSSI, the received signal strength: one number for total power. You can do crude motion detection with RSSI alone, but it is noisy and misses small movements.
Channel State Information (CSI) is far richer. Modern Wi-Fi splits the channel into many narrow subcarriers using OFDM. CSI reports the amplitude and phase of each subcarrier, so instead of one number you get a detailed fingerprint of how the channel treats every frequency slice. A small change in the room shows up clearly in that fingerprint.
| Measure | What it is | Sensitivity |
|---|---|---|
| RSSI | One number: total received power | Low — large movements only |
| CSI | Amplitude + phase per subcarrier (tens of values) | High — small movements, breathing |
03What an ESP32 can actually measure
Espressif exposes CSI on the ESP32 family. You enable a callback and the chip hands you the raw CSI for each received packet. On a single board with one antenna, that is enough to extract several useful signals:
- Presence — is a person in the link area or not.
- Motion energy — how much movement is happening right now.
- Activity — walking versus small gestures versus stillness.
- Breathing — the slow, periodic chest motion of someone sitting still and close, which lands in the 0.1 to 0.5 Hz band.
- A rough distance estimate — closer movement disturbs the channel more.
Here is the minimal firmware shape. It enables CSI and prints a simple amplitude summary for each packet so you can watch the numbers move when you walk past.
#include <WiFi.h> #include "esp_wifi.h" static void onCSI(void* ctx, wifi_csi_info_t* info) { if (!info || !info->buf) return; int8_t* d = info->buf; // interleaved I/Q, int8 int len = info->len; long energy = 0; for (int i = 0; i < len; i += 2) { int I = d[i], Q = d[i + 1]; energy += (long)I * I + (long)Q * Q; // amplitude^2 per subcarrier } Serial.printf("csi_len=%d energy=%ld\n", len, energy); } void setup() { Serial.begin(115200); WiFi.mode(WIFI_STA); WiFi.begin("your-ap", "your-pass"); // your OWN access point while (WiFi.status() != WL_CONNECTED) delay(200); wifi_csi_config_t cfg = {}; cfg.lltf_en = true; // use the long training field cfg.channel_filter_en = false; // keep all subcarriers for sensing esp_wifi_set_csi_config(&cfg); esp_wifi_set_csi_rx_cb(onCSI, nullptr); esp_wifi_set_csi(true); } void loop() { delay(1000); }
Open the Serial Monitor, keep still, and the energy value settles. Walk across the room and it jumps. That jump is the whole principle in one number.
04How a real sensor is built on top
Raw CSI is noisy. A usable presence detector adds a few standard steps, which you run either on the ESP32 or on a connected computer:
- Pick stable subcarriers. Some subcarriers are quiet and useful, others are noisy. Select the responsive ones.
- Clean outliers. A Hampel filter removes spikes without smearing real motion.
- Learn the empty room. Record a short baseline of the room with nobody in it, then compare live readings against it. This auto-calibration takes a few seconds.
- Compute motion energy. How far the live channel sits from the baseline becomes a presence/motion score.
- Band-pass for breathing. To look for breathing, filter the slow variation to the 0.1–0.5 Hz band and look for a steady rhythm.
05The honest limits of one board
This is where a lot of online hype falls apart. With a single ESP32 and one antenna you get a real, useful motion and presence signal. You do not get a precise map of where a person is standing.
| Claim | One ESP32, one antenna |
|---|---|
| Detect presence and motion | Yes, reliably |
| Detect breathing (still, close) | Yes, with care |
| Estimate rough distance | Yes, as an estimate with uncertainty |
| Exact (x, y) position | No — needs 2–3 anchors to triangulate |
| Full body pose / imaging | No — needs many antennas and heavy processing |
Getting an exact position means placing several sensing nodes as anchors and combining them, because one antenna cannot tell direction. Full skeletal pose, the kind you see in research demos, uses antenna arrays and GPUs, not a single dev board. Being clear about this is the difference between an honest project and a disappointing one.
06Where Wi-Fi sensing is genuinely useful
- Camera-free presence for a room you own: turn on lights or heating when someone is there, without a lens in the corner.
- Occupancy for automation that keeps working in the dark, unlike a PIR that needs a clear line of sight.
- Learning signal processing hands-on: CSI is a friendly way to practise filtering, baselines and the FFT on real data.
- Prototyping before committing to a dedicated radar sensor, which we compare in a separate article.
07FAQ
Can Wi-Fi really detect people through walls?
Wi-Fi passes through drywall and furniture, so motion in the next room does change the signal. But a single ESP32 with one antenna can only tell that something moved and roughly how much, not build a clear image through a wall. Precise imaging needs many antennas and far more processing.
Does Wi-Fi sensing use a camera?
No. It uses only the radio signal between two Wi-Fi devices. There is no image sensor, which is part of its appeal for privacy-respecting presence detection in a room you own.
Can an ESP32 measure breathing or heart rate?
An ESP32 can pick up the small, periodic chest movement of breathing when a person sits still and close, because it repeats in the 0.1 to 0.5 Hz band. Heart rate is far weaker and is not reliable with a single low-cost board.
What is the difference between RSSI and CSI?
RSSI is a single number for total received power. CSI describes amplitude and phase for each of the many subcarriers in the channel, so it is much more sensitive to small changes in the environment.