Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Getting Started

This section takes you from nothing to CSI printing on your terminal. It uses a prebuilt firmware binary, so no Rust code is written and no embedded toolchain is needed — only a flashing tool.

What to Buy

Any supported board works. If you have no preference, an ESP32-C6 or ESP32-C5 development board is the most flexible starting point: both are RISC-V, so they build on stable Rust, and both have native USB-Serial-JTAG.

ChipBandNotes
ESP32-C62.4 GHzRISC-V, native USB-Serial-JTAG
ESP32-C52.4 / 5 GHzThe only dual-band part
ESP32-C32.4 GHzThe cheapest of the supported parts
ESP32-S32.4 GHzXtensa; needs espup. Has vector SIMD
ESP322.4 GHzXtensa; no USB-Serial-JTAG, UART only

One board is enough to run a sniffer collector against whatever ambient Wi-Fi traffic already exists in the room. That is the fastest way to confirm the hardware works, and it is enough for this section.

Two boards unlock the controlled pairing — one emitting a known sounding frame at a known rate, one measuring it — which is what almost every sensing experiment actually wants. If you are buying anyway, buy two.

You will also need a USB cable that carries data. A surprising number do not.

Install the Host Tools

Only one tool is required to flash a prebuilt binary:

cargo install espflash

On Linux, your user needs permission to open the serial port. On most distributions that means joining the dialout group (uucp on Arch):

sudo usermod -aG dialout $USER

Log out and back in for the change to take effect. Then plug the board in and confirm it appears:

ls /dev/ttyACM* /dev/ttyUSB*

Native USB-Serial-JTAG boards (the C3, C5, C6, and S3) enumerate as /dev/ttyACM*. Boards behind a UART bridge — the original ESP32, and many third-party carriers — appear as /dev/ttyUSB*.

Flash the CLI Firmware

Download the binary for your chip from the esp-csi-cli-rs releases page. Each release publishes one .bin per chip, named esp-csi-cli-rs-<chip>.bin, plus a manifest.json listing each file’s SHA-256, flash address, and the baud rate it was built for.

The baud rate is fixed at build time. That is why the manifest publishes it. A monitor opened at the wrong rate shows garbage rather than a slow stream, which looks alarmingly like a dead board.

Flash it and open the monitor in one step:

espflash flash --monitor esp-csi-cli-rs-esp32c6.bin

If the board does not enter the bootloader on its own, hold BOOT, tap RESET, release BOOT, and run the command again.

First Contact

After a reset you should see the identification banner:

ESP-CSI-CLI/0.7.0
mac=D0:CF:13:E2:90:E8
******* Welcome to the CSI Collection CLI utility! *******
Available Commands:
    set-wifi                Configure WiFi settings (e.g., mode).
    ...

That first line is the firmware identification contract from CSI Data Formats, and seeing it means the board, the cable, the port, and the baud rate are all correct. Write down the mac= value — it is the stable device key that host tooling uses to recognise this specific board across resets.

Your First Capture

The firmware defaults to sniffer mode on channel 1, which is a collector measuring whatever it overhears. That is enough for a first run:

set-log-mode --mode=text
start --duration=10

Within a second or two, records should begin to appear:

mac: 56:6C:EB:6F:BC:3D
sequence number: 426
rssi: -82
rate: 11
noise floor: 165
channel: 1
timestamp: 2424915
...
data length: 128
csi raw data: [0, 0, 0, 0, -6, 0, 6, 0, -24, 10, -23, 9, ...]

That array is a CSI measurement: the channel’s response, sampled per subcarrier, as complex pairs. Wave your hand between the board and whatever is transmitting and the numbers will move.

Press q to stop early, or let the duration expire.

If Nothing Appears

Work through these in order; the first two account for most cases.

No records at all. Channel 1 may simply be quiet. Ambient sniffing depends on there being ambient traffic, so try a channel your own Wi-Fi is on:

set-wifi --set-channel=6
start --duration=10

Nothing changes until the next start — most CLI commands stage configuration rather than applying it live.

Records, but far fewer than expected. Check the counters:

show-stats

A large drop count means the serial console or the logging queue is the bottleneck, not the radio. Switching to a denser format helps immediately:

set-log-mode --mode=array-list

Garbled output. Almost always a baud mismatch. Confirm the rate against the release manifest and reopen the monitor.

The banner never appears. Confirm the port with ls /dev/ttyACM* /dev/ttyUSB* and your group membership with groups. A cable that only carries power looks identical to a broken board.

Where to Go Next

You now have one board producing CSI. Three directions from here, and they are independent:

  • To write your own firmware rather than operate a prebuilt one, continue to Your First Collector.
  • To set up the controlled emitter/collector pairing and use the full configuration surface, continue to Driving the CLI.
  • To get the data onto your computer in a form you can analyse, jump to Streaming to a Host.