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.
| Chip | Band | Notes |
|---|---|---|
| ESP32-C6 | 2.4 GHz | RISC-V, native USB-Serial-JTAG |
| ESP32-C5 | 2.4 / 5 GHz | The only dual-band part |
| ESP32-C3 | 2.4 GHz | The cheapest of the supported parts |
| ESP32-S3 | 2.4 GHz | Xtensa; needs espup. Has vector SIMD |
| ESP32 | 2.4 GHz | Xtensa; 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.