If you have met Channel State Information and wondered why it always comes as a list of values rather than a single number, the answer is OFDM. Wi-Fi does not send one signal on one frequency. It sends many signals on many frequencies at once, and CSI measures each of them. Understand that structure and every CSI article afterwards reads easily.
01What OFDM is
OFDM stands for Orthogonal Frequency-Division Multiplexing. The idea is to take one wide channel and divide it into many narrow, closely spaced tones called subcarriers, then send a small slice of data on each tone simultaneously. Instead of one fast stream on a single frequency, you get dozens of slow streams running in parallel across the band.
Why bother? A single fast signal is badly hurt by multipath, the way reflections arrive late and smear symbols into each other. Splitting the data across many slow subcarriers makes each symbol long compared with those echoes, so the smearing is manageable. The word orthogonal means the subcarriers are spaced so precisely that they do not interfere with one another even though they overlap. Nearly every modern radio standard, Wi-Fi included, is built on OFDM for this reason.
02Splitting a channel into subcarriers
In Wi-Fi the subcarrier spacing is about 312.5 kHz. A standard 20 MHz channel is processed with a 64-point FFT, which means the radio treats the channel as 64 frequency bins. The data is mapped onto those bins, transmitted, and the receiver runs the reverse transform to separate them again.
Here is the key point for sensing. Because the receiver already has to estimate what each subcarrier did to a known training pattern, in order to decode the data, that per-subcarrier estimate is sitting right there in the hardware. Reading it out is exactly what CSI capture does. The spectrum view in our complete guide to Wi-Fi CSI is literally this bank of subcarriers, measured.
03Why 20, 40 and 80 MHz have different counts
Since the spacing between subcarriers stays roughly fixed, a wider channel simply fits more of them. Double the bandwidth and you roughly double the FFT size and the number of subcarriers. That is why a wider link carries more data, and why it also gives a CSI-based sensor more frequency points to look at.
| Bandwidth | FFT size | Used subcarriers (typical) |
|---|---|---|
| 20 MHz | 64 | about 52 to 56 |
| 40 MHz | 128 | about 114 |
| 80 MHz | 256 | about 242 |
| 160 MHz | 512 | about 484 |
The exact usable counts vary a little between the older 802.11a/g format and the newer 802.11n/ac/ax ones, so treat these as typical figures rather than fixed constants. The trend is what matters: more bandwidth means more subcarriers, which means a richer CSI vector per packet. A wider channel is not automatically better for sensing, though, because it also spreads the same transmit power over more frequency and can be noisier per subcarrier.
04Data, pilot and null subcarriers
Not every subcarrier carries payload. Within a channel, the bins fall into three roles, and knowing them saves you from feeding junk into your sensing pipeline.
- Data subcarriers carry the actual bits. They are the majority, and they are where most of the useful CSI variation lives.
- Pilot subcarriers carry known, fixed values. The receiver uses them as references to track residual frequency and phase drift during a packet. There are usually only a handful, four in a 20 MHz channel.
- Null subcarriers carry nothing on purpose. The bins at the channel edges are left empty as guard bands so the signal does not leak into neighboring channels, and the center bin, the DC subcarrier, is nulled because hardware offsets pile up there.
When you clean CSI, the first step is almost always to drop the null subcarriers, because their values are meaningless noise. We walk through that in cleaning Wi-Fi CSI data.
05What the ESP32 gives you
On an ESP32, CSI is derived from the training fields at the start of each packet. For a 20 MHz link the chip reports the legacy long training field, or LLTF, as about 64 subcarriers. In the raw buffer those arrive as 128 signed bytes, interleaved as an imaginary and a real value per subcarrier. If the link runs at 40 MHz, or you enable the high-throughput training fields, you get more subcarriers and a longer buffer.
Because the LLTF spans 64 bins but only the central ones carry real energy, the edge bins and the DC bin come back near zero. That is expected, not a bug. Your code reads the subcarrier count from the buffer length rather than hard-coding it, then keeps the valid central subcarriers. The capture mechanics are covered in how to capture Wi-Fi CSI on an ESP32.
06Why per-subcarrier data is the foundation of CSI
Everything that makes Wi-Fi sensing powerful comes from having a value per subcarrier instead of one value for the channel. Different subcarriers sit at different frequencies, so they fade and strengthen differently as the room changes. A movement that barely shifts total power can swing individual subcarriers in opposite directions, and because you can see each one, you catch the movement.
That richness is also why CSI beats plain signal strength, which we lay out in CSI vs RSSI. It is why amplitude and phase can be analyzed separately, the subject of amplitude vs phase in Wi-Fi CSI. And it is why machine-learning models for activity and gesture recognition treat CSI as an image, with subcarriers on one axis and time on the other. None of that exists without OFDM slicing the channel first. Learn the comb of subcarriers and the rest of Wi-Fi sensing stops being mysterious.
07FAQ
What is a subcarrier in Wi-Fi?
A subcarrier is one of the many narrow frequencies that make up a single Wi-Fi channel. OFDM divides the channel into these closely spaced tones and sends a little data on each one at the same time. CSI is measured separately for every subcarrier, which is what makes it so detailed compared with a single power reading.
Why do 20, 40 and 80 MHz channels have different subcarrier counts?
The subcarrier spacing stays roughly constant at about 312.5 kHz, so a wider channel simply fits more of them. A 20 MHz channel uses an FFT of 64 bins, a 40 MHz channel uses 128, and an 80 MHz channel uses 256. Wider channels therefore carry more data and give CSI more frequency points to work with.
What is the difference between data, pilot and null subcarriers?
Data subcarriers carry the actual payload. Pilot subcarriers carry known reference values that the receiver uses to track phase and frequency drift. Null subcarriers carry nothing: they sit at the channel edges as guard bands and at the center as the DC bin, and they are left empty to avoid interference and hardware offsets.
How many subcarriers does the ESP32 report for CSI?
For a 20 MHz link the ESP32 reports the legacy long training field as about 64 subcarriers, delivered as 128 interleaved bytes. Not all of them carry useful energy, because the guard and DC bins are near zero, so you typically keep the valid central subcarriers and discard the empty edges before processing.