Files
esp32-hacking/docs/CHEATSHEET.md
user c922e05266 feat: Add v0.4 adaptive sampling — wander detection, auto rate control
On-device CSI wander calculation (coefficient of variation over 50-packet
window). Rate drops to 10 Hz when idle, jumps to 100 Hz on motion with
3s holdoff. EVENT notifications sent to Pi on rate changes. New commands:
ADAPTIVE ON/OFF, THRESHOLD. RATE command disables adaptive mode.
All settings NVS-persisted.
2026-02-04 16:34:19 +01:00

6.0 KiB

Cheatsheet

Environment Setup

source ~/esp/esp-idf/export.sh          # Activate ESP-IDF (every shell)

Build & Flash

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

Deployed Sensors

Name IP mDNS Location
muddy-storm 192.168.129.29 muddy-storm.local Living Room
amber-maple 192.168.129.30 amber-maple.local Office
hollow-acorn 192.168.129.31 hollow-acorn.local Kitchen

Target: 192.168.129.11:5500 (Pi) | Cmd port: 5501

Remote Management (esp-cmd)

esp-cmd <host> STATUS                   # Uptime, heap, RSSI, rate, version, adaptive, motion
esp-cmd <host> IDENTIFY                 # LED solid 5s (find the device)
esp-cmd <host> RATE 50                  # Set ping rate to 50 Hz (disables adaptive)
esp-cmd <host> POWER 15                 # Set TX power to 15 dBm (NVS saved)
esp-cmd <host> ADAPTIVE ON              # Enable adaptive sampling (NVS saved)
esp-cmd <host> ADAPTIVE OFF             # Disable adaptive sampling
esp-cmd <host> THRESHOLD 0.005          # Set motion sensitivity (NVS saved)
esp-cmd <host> OTA http://pi:8070/fw    # Trigger OTA update (use esp-ota instead)
esp-cmd <host> REBOOT                   # Restart device

Host can be an IP or mDNS name (amber-maple.local).

esp-cmd amber-maple.local STATUS        # Single device via mDNS
esp-cmd 192.168.129.29 IDENTIFY         # Single device via IP

Fleet Management (esp-fleet)

esp-fleet status                        # Query all sensors at once
esp-fleet identify                      # Blink all LEDs
esp-fleet rate 50                       # Set rate on all devices
esp-fleet reboot                        # Reboot entire fleet
esp-fleet ota                           # OTA update all (sequential)
esp-fleet ota /path/to/firmware.bin     # OTA with custom firmware

OTA Updates (esp-ota)

esp-ota amber-maple.local               # OTA with default build
esp-ota amber-maple.local -f fw.bin     # OTA with custom firmware
esp-ota amber-maple.local --no-wait     # Fire and forget

First flash after enabling OTA requires USB (partition table change). After that, all updates are OTA.

OTA Flow

  1. Verifies device is alive via STATUS
  2. Starts temp HTTP server on Pi (port 8070)
  3. Sends OTA http://<pi>:8070/<fw>.bin via UDP
  4. Device downloads, flashes, reboots
  5. Verifies device responds post-reboot

Rollback

If new firmware crashes or hangs, the 30s watchdog reboots and bootloader automatically rolls back to the previous firmware.

Adaptive Sampling

When enabled, the device automatically adjusts ping rate based on CSI wander:

  • Motion detected (wander > threshold): 100 pkt/s
  • Idle (wander < threshold for 3s): 10 pkt/s
  • Rate changes send EVENT motion=<0|1> rate=<hz> wander=<value> via UDP
esp-cmd amber-maple.local ADAPTIVE ON   # Enable
esp-cmd amber-maple.local THRESHOLD 0.005  # Tune sensitivity
# Lower threshold = more sensitive, higher = less sensitive
# Good starting range: 0.001 - 0.01

LED States

LED Meaning
Off Not connected to WiFi
Slow blink (1 Hz) Connected, no CSI activity
Fast blink (5 Hz) CSI data flowing
Solid (5s) IDENTIFY command active
Double blink OTA in progress

Test CSI Reception

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 UDP Configuration → Cmd port 5501
CSI UDP Configuration → Hostname mDNS name (e.g., amber-maple)

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/cmd port config
tools/esp-cmd Pi-side management CLI
tools/esp-ota Pi-side OTA update tool
tools/esp-fleet Fleet-wide command tool
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 v5.5.2
~/esp/esp-csi/ Original esp-csi examples
~/.espressif/tools/ Xtensa toolchain

USB Serial

ls /dev/ttyUSB* /dev/ttyACM*            # Find connected devices
dmesg | tail                             # Check USB detection
sudo usermod -aG dialout $USER           # Fix permissions (re-login)