RSSI and CSI are both measured from the exact same Wi-Fi packets, on the exact same board. The difference is not the hardware; it is how much of the measurement the radio hands back to you. RSSI throws almost all of it away and keeps one number. CSI keeps the full shape. That single design choice decides whether your sensor can notice a person breathing or only a person walking.
01What RSSI actually is
RSSI stands for Received Signal Strength Indicator. It is a single scalar that tells you, roughly, how much power arrived at the antenna when a packet was received. It is reported by every Wi-Fi chip ever made, which is why your phone can draw signal bars and why a laptop can pick the strongest access point. It is cheap, universal and easy to understand.
The catch is that RSSI collapses the entire channel into one value. A Wi-Fi channel is not a single tone; it is a band of frequencies carrying dozens of subcarriers at once. RSSI sums all of their power together and reports the total. Whatever happened to individual frequencies inside the band, whether some faded and others grew stronger, is averaged into oblivion. You are left with one loudness reading for the whole room.
That makes RSSI noisy as a sensing signal. Multipath, the way a signal bounces off walls and furniture and arrives many times over, can make the total power swing even when nothing important moved. You can smooth it and threshold it to catch big events, but the ceiling on what it can see is low.
02What CSI actually is
CSI, or Channel State Information, is the measurement RSSI throws away. Modern Wi-Fi uses OFDM, which splits the channel into many narrow subcarriers, each at a slightly different frequency. Every packet carries a known training pattern, and the receiver compares what it expected against what it got, for each subcarrier separately. The result is a complex number per subcarrier: an amplitude and a phase.
So where RSSI gives you one number, CSI gives you a vector of perhaps 52 or 64 amplitude values plus their phases, several times a second. It is a frequency-resolved portrait of the channel, not a single brightness. If OFDM and subcarriers are new to you, we unpack them in CSI subcarriers and OFDM explained.
The reason this matters is multipath again, but turned into an advantage. Different subcarriers are affected differently by the same reflections. A small movement might barely nudge total power, yet it can shift the balance between subcarriers sharply. CSI captures that shift; RSSI cannot, because the shift averages to almost nothing in the sum.
03Side by side
| Property | RSSI | CSI |
|---|---|---|
| What you get | One power value per packet | Amplitude + phase per subcarrier |
| Values per packet | 1 | Typically 52 to 64 (20 MHz) |
| Frequency detail | None, all summed | Full, per subcarrier |
| Phase information | No | Yes |
| Small motion / breathing | Usually missed | Detectable |
| Big motion / walking | Detectable | Detectable |
| Availability | Every Wi-Fi device | Chips that expose it, e.g. ESP32 |
| Processing effort | Very low | Higher, needs filtering |
The pattern is clear. RSSI wins on simplicity and availability. CSI wins on everything to do with sensitivity. For a deeper look at how CSI fits into the wider field, start with our complete guide to Wi-Fi CSI.
04Why CSI sees breathing and RSSI does not
Breathing is the cleanest example of the gap. When a person sits still and breathes, their chest moves by a centimeter or two, slowly, at about 0.1 to 0.5 Hz. That tiny periodic movement changes the length of some signal paths by a fraction of a wavelength. At 2.4 GHz a wavelength is only about 12.5 cm, so even a small chest movement is a meaningful fraction of it and shifts the phase of the affected paths.
In RSSI, that shift is buried. The total power barely changes, because some subcarriers rise while others fall and the sum stays almost flat. You smooth the noise and the breathing smooths away with it.
In CSI, the same breathing shows up as a slow, periodic ripple running through the amplitude and phase of the affected subcarriers. Because you have many subcarriers, you can look for a common rhythm across them and pull the breathing rate out of the noise. That is the whole basis of CSI breathing and vital-sign work, and it is simply impossible with a single scalar.
The same logic scales down to gestures and up to walking. CSI gives you a richer signal at every size of movement; RSSI only reliably catches the large end.
05When RSSI is still good enough
CSI is not always the right answer. If RSSI solves your problem, it is the simpler and more portable choice, and simpler is usually better.
- Link quality and access-point selection. RSSI exists for exactly this. If you only need to know whether a link is strong or weak, do not touch CSI.
- Rough proximity. A tag that gets stronger as it nears a reader gives a usable, if coarse, distance hint from RSSI alone. It will not be precise, but it is cheap.
- Crude presence on big movement. If you just want to know that someone walked into a room and you can tolerate noise and misses, a smoothed RSSI threshold can work.
- Any device, no special capture. RSSI is available everywhere. CSI needs a chip and firmware that expose it. If you must run on arbitrary hardware, RSSI may be your only option.
06Reading both on an ESP32
The neat part is that on an ESP32 you do not have to choose: a single board reports both from the same packets. RSSI lives in the rx_ctrl block of each received packet, while full CSI comes from enabling the CSI callback. The snippet below shows both paths inside one callback.
// Read RSSI (one number) and CSI energy (whole spectrum) from the // same packet, on YOUR OWN network. Tested on Arduino-ESP32 3.0.x. static void onCsi(void* ctx, wifi_csi_info_t* info) { if (!info || !info->buf) return; // --- RSSI: a single scalar already computed by the chip --- int rssi = info->rx_ctrl.rssi; // dBm, one value for the packet // --- CSI: amplitude across every subcarrier --- int8_t* d = info->buf; // interleaved [imag, real] int8 int n = info->len / 2; // subcarrier count double energy = 0; for (int i = 0; i < n; i++) { int im = d[i * 2], re = d[i * 2 + 1]; energy += (double)(re * re + im * im); // amplitude^2 summed } // One number vs a spectrum-derived number, side by side. Serial.printf("rssi=%d subcarriers=%d csi_energy=%.0f\n", rssi, n, energy); }
Watch the two columns as you move. The rssi value wanders and only jumps for large motion. The csi_energy figure, built from every subcarrier, reacts to far smaller changes. For the full connection-and-setup sketch this callback drops into, see how to capture Wi-Fi CSI on an ESP32. Always point the board at a network you own.
07FAQ
What is the difference between CSI and RSSI?
RSSI is a single number that sums the total received power of a packet. CSI is a whole vector: an amplitude and a phase value for each subcarrier in the channel. CSI therefore carries far more detail about how the room reshaped the signal, which is why it detects small motion and breathing that RSSI misses.
Can RSSI detect motion like CSI can?
RSSI can detect large movements, such as a person walking across the link, because big motion changes total power. But it is one noisy number, so it misses the small chest motion of breathing and struggles with subtle gestures. CSI spreads the same measurement across dozens of subcarriers, so small changes that cancel out in one average still show up clearly.
When is RSSI good enough instead of CSI?
RSSI is fine when you only need coarse information: estimating link quality, a rough proximity hint, a crude presence trigger for big movement, or choosing the strongest access point. It is simple, available on every Wi-Fi device, and needs no special capture. Reach for CSI only when you need the sensitivity it provides.
How do I read RSSI and CSI on an ESP32?
RSSI is in the rx_ctrl block of each received packet, so you read info->rx_ctrl.rssi inside the CSI callback or call WiFi.RSSI for the current link. Full CSI comes from enabling the CSI callback with esp_wifi_set_csi, which hands you the per-subcarrier bytes for every packet. The same board gives you both at once.