docs: Complete v0.1 documentation sprint
- Add build & flash workflow (docs/INSTALL.md) - Add CSI config reference and firmware comparison (docs/USAGE.md) - Add quick reference cheatsheet (docs/CHEATSHEET.md) - Add dependencies.lock to .gitignore (env-specific) - Update TASKS.md with completed items and build notes - Verified firmware builds on ESP-IDF v6.1.0 / aarch64
This commit is contained in:
95
docs/CHEATSHEET.md
Normal file
95
docs/CHEATSHEET.md
Normal file
@@ -0,0 +1,95 @@
|
||||
# Cheatsheet
|
||||
|
||||
## Environment Setup
|
||||
|
||||
```bash
|
||||
source ~/esp/esp-idf/export.sh # Activate ESP-IDF (every shell)
|
||||
```
|
||||
|
||||
## Build & Flash
|
||||
|
||||
```bash
|
||||
cd ~/git/esp32-hacking/get-started/csi_recv_router
|
||||
|
||||
idf.py set-target esp32 # Set chip target
|
||||
idf.py menuconfig # Configure WiFi/UDP settings
|
||||
idf.py build # Compile firmware
|
||||
idf.py -p /dev/ttyUSB0 flash # Flash to device
|
||||
idf.py -p /dev/ttyUSB0 monitor # Serial monitor (Ctrl+] to exit)
|
||||
idf.py -p /dev/ttyUSB0 flash monitor # Flash + monitor combined
|
||||
idf.py fullclean # Clean build directory
|
||||
idf.py reconfigure # Re-fetch managed components
|
||||
|
||||
# IDF v6.1 workaround (after clean/reconfigure)
|
||||
ln -s 6.0 managed_components/espressif__esp_csi_gain_ctrl/6.1
|
||||
```
|
||||
|
||||
## Deployed Sensors
|
||||
|
||||
| Name | IP | Location |
|
||||
|------|-----|----------|
|
||||
| muddy-storm | 192.168.129.29 | Living Room |
|
||||
| amber-maple | 192.168.129.30 | Office |
|
||||
| hollow-acorn | 192.168.129.31 | Kitchen |
|
||||
|
||||
**Target:** `192.168.129.11:5500` (Pi)
|
||||
|
||||
## Test CSI Reception
|
||||
|
||||
```bash
|
||||
nc -lu 5500 # Listen for CSI packets
|
||||
socat UDP-RECV:5500 STDOUT # Alternative listener
|
||||
nc -lu 5500 | head -1 # See one packet
|
||||
nc -lu 5500 | wc -l # Count packets/sec (Ctrl+C)
|
||||
```
|
||||
|
||||
## Firmware Variants
|
||||
|
||||
| Firmware | Dir | Output | Needs |
|
||||
|----------|-----|--------|-------|
|
||||
| csi_recv_router | `get-started/csi_recv_router/` | UDP | WiFi router |
|
||||
| csi_recv | `get-started/csi_recv/` | Serial | csi_send device |
|
||||
| csi_send | `get-started/csi_send/` | N/A | csi_recv device |
|
||||
|
||||
## Key Config (menuconfig)
|
||||
|
||||
| Path | Setting |
|
||||
|------|---------|
|
||||
| Example Connection Configuration → SSID | WiFi network name |
|
||||
| Example Connection Configuration → Password | WiFi password |
|
||||
| CSI UDP Configuration → IP | `192.168.129.11` |
|
||||
| CSI UDP Configuration → Port | `5500` |
|
||||
|
||||
## CSI Data Format
|
||||
|
||||
```
|
||||
CSI_DATA,seq,mac,rssi,rate,sig_mode,mcs,cwb,smoothing,not_sounding,
|
||||
aggregation,stbc,fec_coding,sgi,noise_floor,ampdu_cnt,channel,
|
||||
secondary_channel,timestamp,ant,sig_len,rx_state,len,first_word,"[I,Q,...]"
|
||||
```
|
||||
|
||||
## Source Paths
|
||||
|
||||
| File | Purpose |
|
||||
|------|---------|
|
||||
| `get-started/csi_recv_router/main/app_main.c` | Main firmware source |
|
||||
| `get-started/csi_recv_router/main/Kconfig.projbuild` | UDP target config |
|
||||
| `get-started/csi_recv_router/sdkconfig.defaults` | SDK defaults |
|
||||
| `get-started/csi_recv_router/main/idf_component.yml` | Dependencies |
|
||||
| `get-started/csi_recv_router/CMakeLists.txt` | Build config |
|
||||
|
||||
## ESP-IDF Paths
|
||||
|
||||
| Path | Contents |
|
||||
|------|----------|
|
||||
| `~/esp/esp-idf/` | ESP-IDF v6.1.0 |
|
||||
| `~/esp/esp-csi/` | Original esp-csi examples |
|
||||
| `~/.espressif/tools/` | Xtensa toolchain |
|
||||
|
||||
## USB Serial
|
||||
|
||||
```bash
|
||||
ls /dev/ttyUSB* /dev/ttyACM* # Find connected devices
|
||||
dmesg | tail # Check USB detection
|
||||
sudo usermod -aG dialout $USER # Fix permissions (re-login)
|
||||
```
|
||||
134
docs/INSTALL.md
Normal file
134
docs/INSTALL.md
Normal file
@@ -0,0 +1,134 @@
|
||||
# Build & Flash Guide
|
||||
|
||||
## Prerequisites
|
||||
|
||||
| Component | Version | Location |
|
||||
|-----------|---------|----------|
|
||||
| ESP-IDF | v6.1.0 | `~/esp/esp-idf/` |
|
||||
| esp-csi | latest | `~/esp/esp-csi/` (reference only) |
|
||||
| Xtensa toolchain | GCC 15.2.0 | `~/.espressif/tools/` |
|
||||
| Python | 3.13+ | ESP-IDF venv |
|
||||
|
||||
**Note:** No RISC-V toolchain installed. Only ESP32 (Xtensa) targets are supported. For ESP32-C3/C5/C6, run `~/esp/esp-idf/install.sh` with the appropriate target first.
|
||||
|
||||
## Setup
|
||||
|
||||
### 1. Activate ESP-IDF Environment
|
||||
|
||||
```bash
|
||||
source ~/esp/esp-idf/export.sh
|
||||
```
|
||||
|
||||
This must be run in every new shell session. It adds `idf.py` and the toolchain to PATH.
|
||||
|
||||
### 2. Set Target Chip
|
||||
|
||||
```bash
|
||||
cd ~/git/esp32-hacking/get-started/csi_recv_router
|
||||
idf.py set-target esp32
|
||||
```
|
||||
|
||||
### 3. Configure WiFi and UDP Target
|
||||
|
||||
```bash
|
||||
idf.py menuconfig
|
||||
```
|
||||
|
||||
Navigate to:
|
||||
- **Example Connection Configuration** → Set WiFi SSID and password
|
||||
- **CSI UDP Configuration** → Set target IP and port
|
||||
|
||||
| Setting | Default | Description |
|
||||
|---------|---------|-------------|
|
||||
| WiFi SSID | (none) | Your router's SSID |
|
||||
| WiFi Password | (none) | Your router's password |
|
||||
| UDP Target IP | 192.168.129.11 | Pi's IP address |
|
||||
| UDP Target Port | 5500 | Listening port on Pi |
|
||||
|
||||
## Build
|
||||
|
||||
```bash
|
||||
cd ~/git/esp32-hacking/get-started/csi_recv_router
|
||||
idf.py build
|
||||
```
|
||||
|
||||
Build output goes to `build/` (excluded by `.gitignore`). External component `esp_csi_gain_ctrl` is fetched automatically to `managed_components/`.
|
||||
|
||||
### ESP-IDF v6.1 Workaround
|
||||
|
||||
The `esp_csi_gain_ctrl` component (v0.1.4) only ships prebuilt libraries up to ESP-IDF v6.0. On ESP-IDF v6.1+, the build fails with a missing `.a` file. Fix by symlinking:
|
||||
|
||||
```bash
|
||||
cd managed_components/espressif__esp_csi_gain_ctrl
|
||||
ln -s 6.0 6.1
|
||||
```
|
||||
|
||||
This is needed after every `idf.py fullclean` or component re-fetch. The v6.0 library is ABI-compatible with v6.1.
|
||||
|
||||
## Flash
|
||||
|
||||
### Connect ESP32
|
||||
|
||||
Plug ESP32-DevKitC into USB. The serial port appears as `/dev/ttyUSB0` or `/dev/ttyACM0`.
|
||||
|
||||
```bash
|
||||
ls /dev/ttyUSB* /dev/ttyACM*
|
||||
```
|
||||
|
||||
### Flash Firmware
|
||||
|
||||
```bash
|
||||
idf.py -p /dev/ttyUSB0 flash
|
||||
```
|
||||
|
||||
### Monitor Serial Output
|
||||
|
||||
```bash
|
||||
idf.py -p /dev/ttyUSB0 monitor
|
||||
```
|
||||
|
||||
Exit monitor with `Ctrl+]`.
|
||||
|
||||
### Flash + Monitor (combined)
|
||||
|
||||
```bash
|
||||
idf.py -p /dev/ttyUSB0 flash monitor
|
||||
```
|
||||
|
||||
## Deployed Devices
|
||||
|
||||
| Name | IP | Location | Notes |
|
||||
|------|-----|----------|-------|
|
||||
| muddy-storm | 192.168.129.29 | Living Room | |
|
||||
| amber-maple | 192.168.129.30 | Office | |
|
||||
| hollow-acorn | 192.168.129.31 | Kitchen | |
|
||||
|
||||
All devices run `csi_recv_router` firmware, sending CSI data to `192.168.129.11:5500`.
|
||||
|
||||
## Building Other Firmware Variants
|
||||
|
||||
Same process, different directory:
|
||||
|
||||
```bash
|
||||
# ESP-NOW receiver (serial output)
|
||||
cd ~/git/esp32-hacking/get-started/csi_recv
|
||||
idf.py set-target esp32 && idf.py build
|
||||
|
||||
# ESP-NOW transmitter
|
||||
cd ~/git/esp32-hacking/get-started/csi_send
|
||||
idf.py set-target esp32 && idf.py build
|
||||
|
||||
# Radar console (presence detection)
|
||||
cd ~/git/esp32-hacking/esp-radar/console_test
|
||||
idf.py set-target esp32 && idf.py build
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
| Problem | Solution |
|
||||
|---------|----------|
|
||||
| `idf.py: command not found` | Run `source ~/esp/esp-idf/export.sh` |
|
||||
| `/dev/ttyUSB0` not found | Plug in ESP32, check `dmesg \| tail` |
|
||||
| Permission denied on serial | `sudo usermod -aG dialout $USER`, then re-login |
|
||||
| Build fails on dependencies | `idf.py reconfigure` to re-fetch components |
|
||||
| WiFi not connecting | Check SSID/password in `idf.py menuconfig` |
|
||||
200
docs/USAGE.md
Normal file
200
docs/USAGE.md
Normal file
@@ -0,0 +1,200 @@
|
||||
# Usage Guide
|
||||
|
||||
## Firmware Variants
|
||||
|
||||
This repo contains three firmware approaches for CSI data collection:
|
||||
|
||||
| Firmware | Directory | Output | Use Case |
|
||||
|----------|-----------|--------|----------|
|
||||
| **csi_recv_router** | `get-started/csi_recv_router/` | UDP to Pi | **Production** - deployed on 3 sensors |
|
||||
| **csi_recv** | `get-started/csi_recv/` | Serial console | Development/debugging |
|
||||
| **csi_send** | `get-started/csi_send/` | N/A (transmit only) | Paired with csi_recv |
|
||||
|
||||
## csi_recv_router (Deployed Firmware)
|
||||
|
||||
### How It Works
|
||||
|
||||
1. ESP32 connects to WiFi router as a station
|
||||
2. Pings the gateway at 100 Hz (10ms interval)
|
||||
3. Each ping response triggers a CSI callback
|
||||
4. CSI data is formatted as CSV and sent via UDP
|
||||
|
||||
### Data Flow
|
||||
|
||||
```
|
||||
Router ←── ping ──→ ESP32 ──── UDP ──→ Pi (192.168.129.11:5500)
|
||||
(100 Hz) (CSI_DATA)
|
||||
```
|
||||
|
||||
### CSI Data Format (ESP32)
|
||||
|
||||
```
|
||||
CSI_DATA,<seq>,<mac>,<rssi>,<rate>,<sig_mode>,<mcs>,<cwb>,<smoothing>,
|
||||
<not_sounding>,<aggregation>,<stbc>,<fec_coding>,<sgi>,<noise_floor>,
|
||||
<ampdu_cnt>,<channel>,<secondary_channel>,<timestamp>,<ant>,<sig_len>,
|
||||
<rx_state>,<len>,<first_word_invalid>,"[csi_values]"
|
||||
```
|
||||
|
||||
| Field | Type | Description |
|
||||
|-------|------|-------------|
|
||||
| seq | int | Packet sequence number (increments from 0) |
|
||||
| mac | MAC | Gateway MAC address |
|
||||
| rssi | int8 | Received signal strength (dBm) |
|
||||
| rate | uint8 | PHY rate |
|
||||
| sig_mode | uint8 | 0=non-HT, 1=HT, 3=VHT |
|
||||
| mcs | uint8 | Modulation and coding scheme |
|
||||
| cwb | uint8 | Channel bandwidth (0=20MHz, 1=40MHz) |
|
||||
| smoothing | uint8 | Channel estimate smoothing |
|
||||
| not_sounding | uint8 | Not sounding frame |
|
||||
| aggregation | uint8 | AMPDU aggregation |
|
||||
| stbc | uint8 | Space-time block coding |
|
||||
| fec_coding | uint8 | FEC coding (0=BCC, 1=LDPC) |
|
||||
| sgi | uint8 | Short guard interval |
|
||||
| noise_floor | int8 | Noise floor (dBm) |
|
||||
| ampdu_cnt | uint8 | AMPDU sub-frame count |
|
||||
| channel | uint8 | Primary channel number |
|
||||
| secondary_channel | uint8 | Secondary channel offset |
|
||||
| timestamp | uint32 | Local timestamp (microseconds) |
|
||||
| ant | uint8 | Antenna number |
|
||||
| sig_len | uint16 | Signal length |
|
||||
| rx_state | uint32 | RX state (0 = valid) |
|
||||
| len | int | CSI data length (bytes) |
|
||||
| first_word_invalid | bool | First 4 bytes invalid flag |
|
||||
| csi_values | int8[] | Raw CSI I/Q values (interleaved) |
|
||||
|
||||
### CSI Values Interpretation
|
||||
|
||||
The `csi_values` array contains interleaved I/Q pairs per subcarrier:
|
||||
|
||||
```
|
||||
[I0, Q0, I1, Q1, I2, Q2, ...]
|
||||
```
|
||||
|
||||
- Each pair represents one OFDM subcarrier
|
||||
- Amplitude: `sqrt(I^2 + Q^2)`
|
||||
- Phase: `atan2(Q, I)`
|
||||
- Typical length: 128 bytes (64 subcarriers x 2 values) for HT20
|
||||
|
||||
## csi_recv vs csi_recv_router Comparison
|
||||
|
||||
| Aspect | csi_recv | csi_recv_router |
|
||||
|--------|----------|-----------------|
|
||||
| **WiFi mode** | STA, no AP connection | STA, connects to router |
|
||||
| **CSI source** | ESP-NOW packets from csi_send | Ping responses from gateway |
|
||||
| **Output** | Serial (`ets_printf`) | UDP socket |
|
||||
| **Requires** | Paired csi_send device | WiFi router only |
|
||||
| **Promiscuous mode** | Yes | No |
|
||||
| **MAC filtering** | Fixed `1a:00:00:00:00:00` | Gateway BSSID |
|
||||
| **WiFi credentials** | Not needed | Required (menuconfig) |
|
||||
| **CSI config (ESP32)** | All LTF types enabled | LLTF only (router compat) |
|
||||
| **Gain compensation** | Logged to serial | Applied to UDP data |
|
||||
| **Sequence counter** | From ESP-NOW payload (`rx_id`) | Local counter (`s_count`) |
|
||||
| **Network** | Standalone (no router needed) | Depends on router |
|
||||
| **Deployment** | Lab/testing | Production |
|
||||
|
||||
### Key Differences in CSI Config (ESP32 target)
|
||||
|
||||
| Setting | csi_recv | csi_recv_router |
|
||||
|---------|----------|-----------------|
|
||||
| `lltf_en` | true | true |
|
||||
| `htltf_en` | **true** | **false** |
|
||||
| `stbc_htltf2_en` | **true** | **false** |
|
||||
| `manu_scale` | **false** | **true** |
|
||||
| `shift` | **false** | **true** |
|
||||
|
||||
The router firmware uses only LLTF for broader router compatibility. The ESP-NOW firmware enables all LTF types since it controls both endpoints.
|
||||
|
||||
## CSI Configuration Reference
|
||||
|
||||
### sdkconfig.defaults
|
||||
|
||||
#### WiFi Settings
|
||||
|
||||
| Config | Value | Description |
|
||||
|--------|-------|-------------|
|
||||
| `CONFIG_ESP32_WIFI_CSI_ENABLED` | `y` | **Required.** Enables CSI extraction from received frames |
|
||||
| `CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED` | (empty) | Disables TX aggregation. Aggregated frames combine CSI, reducing quality |
|
||||
| `CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED` | (empty) | Disables RX aggregation (csi_recv_router only) |
|
||||
| `CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM` | `128` | Number of dynamic RX buffers. Higher = fewer drops at high CSI rates. Default is 32 |
|
||||
| `CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM` | `32` | Number of dynamic TX buffers |
|
||||
|
||||
#### Performance Settings
|
||||
|
||||
| Config | Value | Description |
|
||||
|--------|-------|-------------|
|
||||
| `CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ` | `240` | Max CPU clock. Ensures CSI callback and UDP send complete within 10ms |
|
||||
| `CONFIG_COMPILER_OPTIMIZATION_PERF` | `y` | `-O2` optimization. Faster CSI processing |
|
||||
| `CONFIG_FREERTOS_HZ` | `1000` | 1ms tick resolution. Required for 100 Hz ping timer accuracy |
|
||||
|
||||
#### System Settings
|
||||
|
||||
| Config | Value | Description |
|
||||
|--------|-------|-------------|
|
||||
| `CONFIG_ESP_TASK_WDT_TIMEOUT_S` | `30` | Watchdog timeout. Extended from default 5s to avoid false resets during WiFi reconnect |
|
||||
| `CONFIG_ESP_CONSOLE_UART_BAUDRATE` | `921600` | Fast serial for debug output |
|
||||
| `CONFIG_ESPTOOLPY_MONITOR_BAUD` | `921600` | Monitor baud rate (must match console) |
|
||||
|
||||
### Kconfig.projbuild (Custom Settings)
|
||||
|
||||
| Config | Default | Range | Description |
|
||||
|--------|---------|-------|-------------|
|
||||
| `CONFIG_CSI_UDP_TARGET_IP` | `192.168.129.11` | Any IPv4 | Destination IP for UDP CSI packets |
|
||||
| `CONFIG_CSI_UDP_TARGET_PORT` | `5500` | 1024-65535 | Destination UDP port |
|
||||
|
||||
### wifi_csi_config_t (Code-Level Settings)
|
||||
|
||||
#### ESP32 (Xtensa)
|
||||
|
||||
| Field | csi_recv_router | Description |
|
||||
|-------|----------------|-------------|
|
||||
| `lltf_en` | `true` | Enable Legacy Long Training Field. Most compatible with routers |
|
||||
| `htltf_en` | `false` | HT-LTF. Only in HT (802.11n) frames. Disabled for router compat |
|
||||
| `stbc_htltf2_en` | `false` | STBC HT-LTF2. Only with STBC encoding |
|
||||
| `ltf_merge_en` | `true` | Merge multiple LTF into one CSI report |
|
||||
| `channel_filter_en` | `true` | Apply channel estimation filter |
|
||||
| `manu_scale` | `true` | Manual amplitude scaling |
|
||||
| `shift` | `true` | Bit shift for value range |
|
||||
|
||||
### Compile-Time Defines (app_main.c)
|
||||
|
||||
| Define | Value | Description |
|
||||
|--------|-------|-------------|
|
||||
| `CONFIG_SEND_FREQUENCY` | `100` | Ping rate in Hz (10ms interval) |
|
||||
| `CONFIG_FORCE_GAIN` | `0` | Force AGC/FFT gain to baseline (disabled) |
|
||||
| `CONFIG_GAIN_CONTROL` | `1` (auto) | Enable gain compensation (ESP32-S3, C3, C5, C6, C61) |
|
||||
|
||||
## Receiving CSI Data on the Pi
|
||||
|
||||
Listen on UDP port 5500:
|
||||
|
||||
```bash
|
||||
# Quick test
|
||||
nc -lu 5500
|
||||
|
||||
# Save to file
|
||||
nc -lu 5500 > csi_capture.csv
|
||||
|
||||
# With socat (more reliable)
|
||||
socat UDP-RECV:5500 STDOUT
|
||||
```
|
||||
|
||||
## Python Visualization Tools
|
||||
|
||||
### get-started/tools/
|
||||
|
||||
```bash
|
||||
pip install -r get-started/tools/requirements.txt
|
||||
python get-started/tools/csi_data_read_parse.py
|
||||
```
|
||||
|
||||
Requires serial connection (not UDP). Use for development with `csi_recv` firmware.
|
||||
|
||||
### esp-radar/console_test/tools/
|
||||
|
||||
```bash
|
||||
pip install -r esp-radar/console_test/tools/requirements.txt
|
||||
python esp-radar/console_test/tools/esp_csi_tool.py
|
||||
python esp-radar/console_test/tools/esp_csi_tool_gui.py
|
||||
```
|
||||
|
||||
CLI and GUI tools for CSI analysis with presence detection algorithms.
|
||||
Reference in New Issue
Block a user