ESP Wi-Fi Sensing Demo:基于 esp_wifi_sensing 组件的三通道人体感知实战指南
【免费下载链接】esp-csiApplications based on Wi-Fi CSI (Channel state information), such as indoor positioning, human detection项目地址: https://gitcode.com/GitHub_Trending/es/esp-csi
本文以 esp-csi 仓库中的wifi_sensing_demo为例,完整讲解如何基于esp_wifi_sensing组件搭建一套可独立运行、可调试的 Wi-Fi CSI 人体感知(Human Sensing)示例固件。通过本文你将掌握:感知状态机(FSM)的创建与启动流程、AP 与固定对端多通道监听、LED 状态反馈策略,以及一套可直接用浏览器 Web Serial 页面进行可视化调参的轻量串口协议,可用于快速完成从“设备上电”到“看到运动检测曲线”的完整 bring-up。
示例概览与组成
wifi_sensing_demo位于 examples/esp-radar/wifi_sensing_demo,是一个自包含(self-contained)的 ESP-IDF 示例工程,用于在贴近真实的上电联调流程中验证esp_wifi_sensing组件。根据 README.md 的说明,该示例组合了以下能力:
- Wi-Fi STA 连接与感知状态机启动:设备以 STA 模式接入路由器,并在连接建立后启动 CSI 感知 FSM;
- 三个被监控的通道(channel):已连接的 AP(BSSID)加上两个固定对端 MAC 地址,共三个感知参考通道;
- 状态 LED 策略:通过 LED 的闪烁、常亮、渐灭快速给出视觉反馈;
- 轻量串口协议:输出可供 tools/web_serial_monitor.html 浏览器页面消费的结构化数据,支持在线诊断与运行时调参。
工程依赖方面,main/idf_component.yml 声明了esp_wifi_sensing >= 0.1.1、espressif/led_strip ^3.0.0,并要求 ESP-IDF 版本不低于 5.4(idf: '>=5.4')。主组件在 main/CMakeLists.txt 中注册了app_main.c、led_control.c、web_serial_monitor.c三个源文件,并显式依赖esp_wifi_sensing、protocol_examples_common、driver、esp_driver_ledc与led_strip。
感知状态机:组件公开的标准工作流
示例遵循组件官方推荐的公开工作流,在 main/app_main.c 的demo_init()中依次完成五个步骤:
- 创建 FSM:调用
esp_wifi_sensing_fsm_create()创建感知状态机句柄; - 添加通道:分别添加 AP 通道与两个额外对端通道;
- 注册回调:注册 ACTIVE / INACTIVE 状态事件回调;
- 启动 FSM:调用
esp_wifi_sensing_fsm_control(..., ESP_WIFI_SENSING_FSM_CTRL_START, NULL); - (可选)保持 CSI 流量:调用
esp_wifi_sensing_fsm_ping_router_start()让 CSI 数据持续流动。
对应到源码,demo_init() 的核心片段如下:
esp_wifi_sensing_fsm_config_t cfg = DEFAULT_ESP_WIFI_SENSING_FSM_CONFIG(); cfg.max_channel_num = 3; ESP_ERROR_CHECK(esp_wifi_sensing_fsm_create(&cfg, &s_hms)); /* The demo monitors the connected AP plus two fixed reference peers. */ ESP_ERROR_CHECK(esp_wifi_sensing_fsm_add_channel(s_hms, ap_info.bssid)); ESP_ERROR_CHECK(esp_wifi_sensing_fsm_add_channel(s_hms, CONFIG_CSI_SEND_MAC)); ESP_ERROR_CHECK(esp_wifi_sensing_fsm_add_channel(s_hms, CONFIG_CSI_SEND_MAC_2)); /* Register the same callback for both state transitions to keep logging symmetric. */ ESP_ERROR_CHECK(esp_wifi_sensing_fsm_register_event_cb(s_hms, ESP_WIFI_SENSING_FSM_EVENT_ACTIVE, on_motion_event, NULL)); ESP_ERROR_CHECK(esp_wifi_sensing_fsm_register_event_cb(s_hms, ESP_WIFI_SENSING_FSM_EVENT_INACTIVE, on_motion_event, NULL)); ESP_ERROR_CHECK(esp_wifi_sensing_fsm_control(s_hms, ESP_WIFI_SENSING_FSM_CTRL_START, NULL));几点值得注意的实现细节:
- AP BSSID 的获取:在启动 FSM 前,示例先调用
esp_wifi_sta_get_ap_info()拿到当前所连 AP 的bssid,并缓存在s_mac_ap中,作为主通道; - 两个固定对端:
CONFIG_CSI_SEND_MAC与CONFIG_CSI_SEND_MAC_2定义为0x1a:00:00:00:00:00与0x1a:00:00:00:00:01,它们是示例约定的 CSI 发送端 MAC(详见 app_main.c); - 默认参数日志:启动后示例会打印默认通道配置(运动检测灵敏度
sensitivity、active_jitter_min、active_filter_ms、确认计数CONFIG_ESP_WIFI_SENSING_CONFIRM_COUNT、ping 频率ping_frequency_hz),方便与后续 Web 页面读数对照; - ping 路由器的容错处理:
esp_wifi_sensing_fsm_ping_router_start()返回ESP_ERR_INVALID_STATE时仅打印告警(说明 STA 未连接或没有网关),不会中断主流程。
此外,在 app_main.c 的 app_main() 中,示例遵循标准 ESP-IDF bring-up 顺序:nvs_flash_init()→esp_netif_init()→esp_event_loop_create_default()→led_init()→ 注册 Wi-Fi/IP 事件 →example_connect()完成配网连接,随后调用esp_wifi_set_ps(WIFI_PS_NONE)关闭 Wi-Fi 省电模式——注释明确指出这是为了保证 CSI 采样节奏稳定。之后初始化 ESPNOW 接收与demo_init(),最后按需启动 Web Serial 监视器并进入while(1)延时循环。
ESPNOW 接收通道
虽然感知通道本身基于 CSI,示例仍通过esp_now_init()初始化了 ESPNOW 接收,见 espnow_rx_init()。其作用是从专用 CSI 发送端接收 ESPNOW 心跳计数,便于在日志中确认对端仍在发包:
- 仅处理来自
CONFIG_CSI_SEND_MAC_2的数据包,保持控制台输出聚焦; - 设置 PMK(发送端当前关闭 ESPNOW 加密,PMK 对接收路径可选且无害);
- 添加一个广播对端(
ff:ff:ff:ff:ff:ff,channel = 0跟随当前 STA 信道、不加密),提高跨目标与终端工作流的兼容性。
目录结构
- main/app_main.c:示例入口与感知 FSM 装配;
- main/led_control.c / main/led_control.h:LED 后端与状态映射;
- main/web_serial_monitor.c / main/web_serial_monitor.h:面向行的串口协议,用于诊断与运行时调参;
- tools/web_serial_monitor.html:浏览器 UI,提供图表、实时诊断与配置功能;
- main/Kconfig.projbuild:示例自身的 menuconfig 选项(LED 类型、Web Serial 开关等);
- sdkconfig.defaults:默认工程配置(见下文)。
构建与运行
将wifi_sensing_demo目录作为 ESP-IDF 工程打开,按常规方式构建并烧录:
idf.py set-target <chip> idf.py flash monitor其中<chip>需要替换为实际目标芯片。示例使用protocol_examples_common完成 Wi-Fi 配网(参见 CMakeLists.txt 中通过EXTRA_COMPONENT_DIRS引入的protocol_examples_common),如果本地工作流需要,请在烧录前通过idf.py menuconfig配置好 Wi-Fi 凭据(SSID / 密码)。
默认配置要点(sdkconfig.defaults)
examples/esp-radar/wifi_sensing_demo/sdkconfig.defaults 给出了开箱即用的关键配置:
| 配置项 | 值 | 说明 |
|---|---|---|
CONFIG_ESP_CONSOLE_UART_BAUDRATE | 921600 | 控制台串口波特率,保证 Web Serial 大数据量传输不丢行 |
CONFIG_ESP_WIFI_DYNAMIC_RX_BUFFER_NUM | 128 | 加大 Wi-Fi 动态接收缓冲,适配 CSI 高频采样 |
CONFIG_ESP_WIFI_CSI_ENABLED/CONFIG_ESP32_WIFI_CSI_ENABLED | y | 打开 Wi-Fi CSI 采集开关(CSI 是感知的数据源) |
CONFIG_ESP_WIFI_AMPDU_TX_ENABLED | n | 关闭 TX AMPDU,保证采样节奏稳定 |
CONFIG_ESP_TASK_WDT_TIMEOUT_S | 30 | 放宽任务看门狗超时 |
CONFIG_ESP_WIFI_SENSING_DEFAULT_PRESENCE_SENSITIVITY | 250 | 存在检测默认灵敏度 |
Web Serial 监视器:HMS 协议与浏览器调参
当CONFIG_ESP_WIFI_SENSING_WEB_SERIAL_ENABLE=y(默认开启,见 Kconfig.projbuild)时,固件通过标准串口控制台输出以HMS:为前缀的、按行分隔的 JSON 消息,并接受以HMSCMD为前缀的命令。这样普通 ESP 日志与结构化诊断数据可以共用一个串口端口而互不干扰。
从实现上看,web_serial_monitor.c 的后台任务会:连接后立即发送一次初始快照(hello+ runtime + 全部通道配置),随后以stream_period_ms(默认 50ms,可配置范围 20~1000ms,见 Kconfig.projbuild)为周期,对每个已注册通道调用esp_wifi_sensing_fsm_get_channel_diag()与esp_wifi_sensing_fsm_get_state()组装sample消息;同时轮询标准输入与 USB Serial/JTAG 输入,按换行符切分命令并执行。
浏览器 UI 关注的诊断字段
浏览器 UI 目前聚焦于组件导出的最小公开诊断集合:
jitter_value:抖动值,运动检测的核心输入;smooth_scaled:平滑后的缩放值(图表中的绿线);enter_level_scaled:进入 ACTIVE 的触发电平(橙线);exit_level_scaled:退出到 INACTIVE 的电平(红线);state:FSM 过程状态(IDLE/DEBOUNCE_ACTIVE/ACTIVE/DEBOUNCE_INACTIVE,字符串与数值均有导出);init_stage:初始化阶段(START/GOLD_FOUND/STABLE)。
页面还展示存在检测(presence)与训练(train)相关的扩展字段,例如wander_value、presence_someone_threshold、train_status、train_sample_count、train_background_count等。图中曲线的判读逻辑在页面内也有说明:smooth_scaled持续高于橙色enter_level_scaled趋向 ACTIVE,持续低于红色exit_level_scaled趋向 INACTIVE。
串口命令集
串口监视器暴露了演示用到的主要运行时控制命令(均可从普通终端直接敲入):
| 命令 | 作用 |
|---|---|
HMSCMD HELLO | 请求设备返回 hello 元数据、运行时状态与全部通道配置 |
HMSCMD START_STREAM/HMSCMD STOP_STREAM | 开启 / 停止周期性的通道诊断数据流 |
HMSCMD FSM_START/HMSCMD FSM_STOP | 启动 / 停止感知 FSM(对应ESP_WIFI_SENSING_FSM_CTRL_START/STOP) |
HMSCMD RESET_BASELINE | 重置基线(对应ESP_WIFI_SENSING_FSM_CTRL_RESET_BASELINE) |
HMSCMD GET_CFG ALL | 获取全部通道配置 |
HMSCMD GET_CFG <peer> | 获取指定通道配置 |
HMSCMD GET_RUNTIME | 获取运行时状态(如amplitude_log_enabled) |
HMSCMD SET_AMPLITUDE_LOG on/off | 开启 / 关闭幅度日志 |
HMSCMD SET_CFG <peer> motion_sensitivity=<float> active_jitter_min=<float> active_filter_ms=<ms> | 在线修改指定通道参数 |
其中<peer>可以是演示名称(AP、MAC_1、MAC_2)或对端 MAC 字符串(大小写不敏感),二者均可被 find_peer_by_name_or_mac() 识别。SET_CFG的可写参数除 README 列出的三个外,实现还额外支持presence_sensitivity(见 apply_cfg_value()),修改成功后设备会回ack并附带最新的通道配置 JSON。除了上述命令,实现还支持TRAIN_START/TRAIN_STOP/TRAIN_REMOVE(对应esp_wifi_sensing_fsm_train_start/stop/remove),用于存在检测的阈值训练。
协议上的一个细节:所有输出都经write_line()统一加上HMS:前缀(web_serial_monitor.c),命令则在换行分隔的输入流中解析;\r被直接忽略,因此终端回车与浏览器发送均兼容。
使用浏览器监视器
- 构建并运行固件;
- 用 Chromium 内核浏览器(Chrome / Edge)打开 tools/web_serial_monitor.html;
- 通过 Web Serial 连接开发板串口;
- 在页面查看各通道实时诊断,或直接修改通道参数。
如果浏览器阻止file://方式访问 Web Serial,可以在本地起一个静态服务:
cd tools python3 -m http.server然后访问http://127.0.0.1:8000/web_serial_monitor.html。
页面本身是单文件应用,内置中英文切换(中文 / English按钮),提供通道列表(Channels)、事件日志(Event Log)、运动检测/存在检测双图表、配置表单(运动灵敏度、存在灵敏度、active_jitter_min、active_filter_ms)以及Amplitude Log开关;训练区支持“延迟开始 + 定时结束”的自动化流程,方便先让人离开房间再采集背景数据。
Demo 行为与 LED 状态机
README 明确列出了演示的整体行为,这些行为在 led_control.c 中有完整的实现支撑:
- AP BSSID 通道是 LED 反馈的主通道:只有 AP 通道的 ACTIVE/INACTIVE 事件会驱动 LED 状态变化(见 on_motion_event() 中
is_ap_channel判断); - Wi-Fi 断开时 LED 闪烁:以 500ms 周期、50% 占空比闪烁,提示设备仍在连接中;
- AP 通道进入 ACTIVE 时 LED 常亮:
led_notify_ap_active()将状态机置为LED_MOTION_ACTIVE,GPIO 版本输出满占空比,WS2812 版本点亮绿色; - AP 通道回到 INACTIVE 时 LED 渐灭:
led_notify_ap_inactive()进入LED_MOTION_FADING,在 1000ms 内从全亮线性衰减到熄灭,避免短暂的不活动间隙造成视觉跳变; - 两个固定对端通道作为额外感知参考:它们始终出现在日志与浏览器监视器中,但不参与 LED 反馈。
LED 后端支持两种类型(由 Kconfig.projbuild 的ESP_WIFI_SENSING_DEMO_LED_TYPE选择,默认 GPIO):
- GPIO LED:基于 LEDC 定时器(5kHz、8bit 分辨率)输出 PWM,引脚由
CONFIG_ESP_WIFI_SENSING_DEMO_LED_GPIO指定(默认 GPIO 2); - WS2812 LED:单颗可编程灯珠,后端可选 RMT(默认)或 SPI(
ESP_WIFI_SENSING_DEMO_WS2812_BACKEND),GPIO 作为数据引脚。
LED 状态由独立的 FreeRTOS 任务(栈 3072B、优先级 4)以 20ms 周期刷新,事件侧通过xTaskNotifyGive()唤醒,状态字段用临界区保护,避免多任务竞争。
小结与延伸阅读
wifi_sensing_demo是一个结构清晰的“最小可跑通”参考实现:把esp_wifi_sensing组件的 FSM 工作流、多通道监听、状态回调、LED 反馈与串口调参能力完整串在了一起。如果你需要在此基础上继续深入:
- 想了解整个 esp-csi 仓库的定位与更多示例(室内定位、人体检测等),可阅读根目录 README.md;
- 想对比其他基于 CSI 的应用形态(雷达评估工具、Wi-Fi 感知演示等),可查看 examples/esp-radar/console_test 与 examples/esp-radar/connect_rainmaker;
- 想理解 CSI 原始数据的含义与获取方式,可参考 docs/zh_CN/Wireless-indicators-CSI-and-RSSI.md 与 examples/get-started/csi_recv。
在接入真实环境时,请根据现场调整对端 MAC、Wi-Fi 凭据、LED 引脚与采样周期,并以idf.py monitor或浏览器监视器中的实测曲线为准进行灵敏度标定。
【免费下载链接】esp-csiApplications based on Wi-Fi CSI (Channel state information), such as indoor positioning, human detection项目地址: https://gitcode.com/GitHub_Trending/es/esp-csi
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考