← WiFi Sensing Fundamentals

Anatomy of a CSI node

12 min

Walking the real config

Open the WiFi CSI Presence Node config from the catalog and follow along — every design choice there earns its place.

The unlock

esp32:
  framework:
    type: esp-idf
    sdkconfig_options:
      CONFIG_ESP_WIFI_CSI_ENABLED: "y"

CSI capture is off by default in ESP-IDF; this compiles it in. And in the wifi block, power_save_mode: none — with power saving on, the radio naps between beacons and your CSI stream starves.

Who measures whom

One node alone measures CSI from its access point traffic. But our config also runs an ESP-NOW mesh: every node broadcasts a tiny beacon at 50 Hz, and every other node measures CSI from those beacons. Six nodes = thirty measurement paths crisscrossing the space. A person cannot move anywhere without bending at least one path.

Getting data out

uart:
  baud_rate: 921600

50 Hz × ~200 bytes of JSON ≈ 10 KB/s — comfortably inside 921600 baud. The logger is silenced on UART0 (baud_rate: 0) because data owns that port; a stray log line mid-JSON corrupts frames.

Practical capture notes

  • The ring buffer (ring_size: 8) absorbs burst jitter between your reads.
  • min_rssi: -85 drops garbage frames from distant networks.
  • One hard-won lesson baked into the components: on ESP32-S3 + IDF 5.x, promiscuous mode must be enabled before CSI config, or capture silently dies after a few frames. The latentfield_csi component handles the ordering — one reason to use it rather than raw IDF calls.

Sign in to use this feature — it takes 20 seconds and it’s free. Sign in Next lesson →