Arduino ESP32 Zigbee 振动传感器(IAS Zone)端点开发指南:ZigbeeVibrationSensor 类详解
2026/9/14 17:10:23 网站建设 项目流程

Arduino ESP32 Zigbee 振动传感器(IAS Zone)端点开发指南:ZigbeeVibrationSensor 类详解

【免费下载链接】arduino-esp32Arduino core for the ESP32 family of SoCs项目地址: https://gitcode.com/GitHub_Trending/ar/arduino-esp32

导读

本文围绕 Arduino-ESP32 核心仓库中的ZigbeeVibrationSensor类展开,讲解如何在 ESP32-C6 / ESP32-H2 上实现一个符合 Zigbee Home Automation(HA)标准的振动检测设备(IAS Zone 端点)。读完本文,你将掌握振动传感器的端点创建、灵敏度状态上报、IAS Zone 入网(Enrollment)与断电恢复的全套 API 用法,并能在真实示例工程(Zigbee_Vibration_Sensor.ino)基础上直接搭建自己的安全监测设备。


一、ZigbeeVibrationSensor 是什么

ZigbeeVibrationSensor是 Arduino-ESP32 的 Zigbee 库 提供的一个振动传感器端点(Endpoint)类。它基于 Zigbee HA 标准中的IAS Zone(Intrusion Alarm System Zone,入侵报警系统区域)设备类型实现,用于在 Zigbee 网络中作为终端设备(End Device)检测并上报振动事件。

从源码看(ZigbeeVibrationSensor.h),该类继承自公共端点基类ZigbeeEP,并在构造时声明了三个服务端(Server)集群:

  • Basic 集群:提供 ZCL 版本、电源来源等基础信息;
  • Identify 集群:支持协调器侧识别/定位设备;
  • IAS Zone 集群:核心集群,承载振动检测的状态属性与上报命令。

其端点配置使用 HA 配置文件(ESP_ZB_AF_HA_PROFILE_ID),设备类型为ESP_ZB_HA_IAS_ZONE_ID(见 ZigbeeVibrationSensor.cpp),因此可被 Home Assistant 等支持 Zigbee HA 标准的网关直接识别为振动传感器。

典型应用场景:

  • 安防系统振动探测(门窗被撬、设备被移动检测);
  • 工业设备运行状态监测;
  • 建筑结构健康监测;
  • 智能家居安防联动;
  • 机器状态监控。

注意:当前官方示例支持的芯片为ESP32-C6 与 ESP32-H2(见 示例 README 的 Supported Targets 表),这两个芯片内置 IEEE 802.15.4 收发器,是 Arduino-ESP32 支持 Zigbee 功能的前提。


二、类构造函数与端点号

构造函数

ZigbeeVibrationSensor(uint8_t endpoint);
  • endpoint:端点号,取值范围1~254。示例中固定使用1
#define VIBRATION_SENSOR_ENDPOINT_NUMBER 1 ZigbeeVibrationSensor zbVibrationSensor = ZigbeeVibrationSensor(VIBRATION_SENSOR_ENDPOINT_NUMBER);

从构造函数实现(ZigbeeVibrationSensor.cpp)可以看到,构造时完成了以下初始化:

  • _device_id设为ESP_ZB_HA_IAS_ZONE_ID
  • _zone_status = 0(初始无振动);
  • _zone_id = 0xff(未分配区域 ID);
  • _ias_cie_endpoint = 1(IAS 客户端端点默认 1);
  • _enrolled = false(尚未完成入网);
  • 通过ZIGBEE_DEFAULT_VIBRATION_SENSOR_CONFIG()宏创建默认集群配置(见 ZigbeeVibrationSensor.h),其中zone_typeESP_ZB_ZCL_IAS_ZONE_ZONETYPE_VIBRATION_MOVEMENT(振动/移动类型),zone_stateNOT_ENROLLED

三、API 方法详解

3.1 setVibration —— 设置振动检测状态

bool setVibration(bool sensed);
  • sensed:振动状态,true表示检测到振动,false表示未检测到。
  • 返回值:成功返回true,失败返回false

该方法是振动传感器的核心动作接口。底层实现(ZigbeeVibrationSensor.cpp)做了两件事:

  1. 将布尔值写入 IAS Zone 集群的ZoneStatus 属性ESP_ZB_ZCL_ATTR_IAS_ZONE_ZONESTATUS_ID);
  2. 更新内部_zone_status并自动调用report()向协调器发送状态变更通知。

也就是说,调用一次setVibration()即可同时完成属性更新与上报,无需手动再调report()

3.2 setIASClientEndpoint —— 设置 IAS 客户端端点

void setIASClientEndpoint(uint8_t ep_number);
  • ep_number:IAS 客户端(通常为协调器/CIE 端)的端点号,默认值为 1

IAS Zone 设备向协调器发送状态变更通知时,需要知道接收方(IAS Client / CIE)的端点号。该值保存在_ias_cie_endpoint中(ZigbeeVibrationSensor.cpp),并用于report()dst_endpoint字段(L66)。当你的协调器端点不是 1 时,应在入网前调用此方法修改。

3.3 report —— 手动上报当前振动状态

bool report();
  • 返回值:成功返回true,失败返回false

report()向 IAS 客户端发送IAS Zone 状态变更通知(Status Change Notification)命令(ZigbeeVibrationSensor.cpp)。实现要点:

  • 仅当设备已完成入网(_enrolled == true)时才会真正发送;未入网时返回false并打印错误日志;
  • 使用 64 位长地址(ESP_ZB_APS_ADDR_MODE_64_ENDP_PRESENT)作为目标地址模式;
  • 通过acquireCommandLock()/releaseCommandLock()保证 Zigbee 命令线程安全;
  • 报文携带zone_statuszone_idextend_status = 0delay = 0等字段。

正常情况下无需手动调用——setVibration()内部已自动上报。

3.4 requestIASZoneEnroll —— 请求 IAS Zone 入网

bool requestIASZoneEnroll();
  • 返回值:入网请求发送成功返回true,否则返回false。注意,真正的入网结果需要用enrolled()等待并确认。

该方法用于新设备首次入网已入网设备重新入网。底层发送IAS Zone Enroll Request命令(ZigbeeVibrationSensor.cpp),请求中携带:

  • src_endpoint:本设备端点;
  • zone_typeESP_ZB_ZCL_IAS_ZONE_ZONETYPE_VIBRATION_MOVEMENT(振动/移动传感器类型);
  • 地址模式为广播式(ESP_ZB_APS_ADDR_MODE_DST_ADDR_ENDP_NOT_PRESENT),让协调器(CIE)响应分配 Zone ID。

协调器响应后,类内部的重写方法zbIASZoneEnrollResponse()(ZigbeeVibrationSensor.cpp)会校验响应码,成功时从属性表中读取 IAS CIE 地址、保存zone_id并将_enrolled置为true

3.5 restoreIASZoneEnroll —— 从存储属性恢复入网信息

bool restoreIASZoneEnroll();
  • 返回值:恢复成功返回true,否则返回false

已入网设备重启后应优先调用本方法,而不是重新请求入网。它从设备闪存中存储的 IAS Zone 集群属性(IAS CIE 地址、Zone ID)恢复入网信息(ZigbeeVibrationSensor.cpp),实现要点:

  • 依次读取IAS_CIE_ADDRESSZONEID两个属性,任一读取失败即返回false
  • 校验zone_id合法性(0xFF视为无效,因为 0xFF 表示未分配);
  • 成功后_enrolled = true

休眠设备(Sleepy Device)尤其有利:省去了重新入网所需的协商时间,开机即可快速恢复上报能力。

注意:恢复入网的前提是入网信息确实已保存到设备属性/闪存中。因此示例代码在首次成功入网后,会把ENROLLED标志写入 Preferences,以便重启时判断走恢复路径(详见下文示例解读)。

3.6 enrolled —— 查询入网状态

bool enrolled();
  • 返回值:已入网返回true,否则返回false

这是一个内联查询方法,直接返回内部_enrolled标志(ZigbeeVibrationSensor.h)。典型用法是调用requestIASZoneEnroll()restoreIASZoneEnroll()之后轮询等待入网完成:

while (!zbVibrationSensor.enrolled()) { Serial.print("."); delay(100); }

四、完整示例工程解读

官方提供了开箱即用的示例工程:Zigbee_Vibration_Sensor.ino。其工作流程可分为“启动入网”与“运行上报”两个阶段。

4.1 编译前置条件

示例工程在setup()开头强制校验 Zigbee 端设备模式宏:

#ifndef ZIGBEE_MODE_ED #error "Zigbee end device mode is not selected in Tools->Zigbee mode" #endif

因此编译前必须在 Arduino IDE 中完成以下配置(详见示例 README):

  • 开发板Tools -> Board选择 ESP32-C6 / ESP32-H2 开发板;
  • Zigbee 模式Tools -> Zigbee mode: Zigbee ED (end device)
  • 分区方案Tools -> Partition Scheme: Zigbee 4MB with spiffs
  • 串口Tools -> Port选择实际 COM 口;
  • 可选Tools -> Core Debug Level: Verbose可查看 Zigbee 协议栈完整日志。

示例的 CI 配置(ci.yml)也印证了这一点:构建参数为PartitionScheme=zigbee, ZigbeeMode=ed,并要求芯片具备CONFIG_SOC_IEEE802154_SUPPORTEDCONFIG_ZB_ENABLED(即带 802.15.4 无线电的芯片)。

4.2 硬件接线

  • 传感器引脚:默认sensor_pin = 4,可自行修改。pinMode(sensor_pin, INPUT),高电平表示检测到振动;
  • 按键引脚:默认button = BOOT_PIN(即开发板 BOOT 键),用于长按 3 秒触发 Zigbee 出厂复位。

4.3 启动流程:入网 / 恢复入网

preferences.begin("Zigbee", false); bool enrolled = preferences.getBool("ENROLLED"); // 读取上次的入网标志 preferences.end();

示例使用Preferences在闪存中保存ENROLLED标志,用于区分“首次入网”与“重启恢复”两条路径:

if (enrolled) { Serial.println("Device has been enrolled before - restoring IAS Zone enrollment"); zbVibrationSensor.restoreIASZoneEnroll(); } else { Serial.println("Device is factory new - first time joining network - requesting new IAS Zone enrollment"); zbVibrationSensor.requestIASZoneEnroll(); } while (!zbVibrationSensor.enrolled()) { Serial.print("."); delay(100); }

关键点:

  1. 首次上电(标志为 false):走requestIASZoneEnroll()申请新入网,等待协调器分配 Zone ID;
  2. 重启(标志为 true):走restoreIASZoneEnroll()直接从闪存恢复,速度更快;
  3. 入网成功后,仅当本次是全新入网时才把ENROLLED写为true,避免重复写闪存:
    if (!enrolled) { preferences.begin("Zigbee", false); preferences.putBool("ENROLLED", true); preferences.end(); }

启动前还需完成端点注册与网络启动:

zbVibrationSensor.setManufacturerAndModel("Espressif", "ZigbeeVibrationSensor"); Zigbee.addEndpoint(&zbVibrationSensor); // 注册端点 if (!Zigbee.begin()) { ... ESP.restart(); } while (!Zigbee.connected()) { ... } // 等待加入网络

Zigbee.begin()在注册完所有端点后以端设备模式启动协议栈,Zigbee.connected()用于判断设备是否已成功加入网络(两者均在 ZigbeeCore 中声明,端点注册实现在 ZigbeeCore.cpp)。

4.4 主循环:振动检测与上报

static bool sensed = false; if (digitalRead(sensor_pin) == HIGH && !sensed) { zbVibrationSensor.setVibration(true); // 检测到振动 → 属性更新 + 自动上报 sensed = true; delay(2000); // 检测到后延时 2 秒再检测 } else if (digitalRead(sensor_pin) == LOW && sensed) { zbVibrationSensor.setVibration(false); // 振动消失 → 上报恢复状态 sensed = false; delay(500); }

设计要点:

  • 使用static bool sensed边沿检测,只在状态翻转时上报,避免重复发送;
  • 检测到振动后延时 2 秒,防止传感器抖动导致高频上报;
  • 振动消失后延时 0.5 秒,保持上报实时性。

4.5 长按按键出厂复位

if (digitalRead(button) == LOW) { delay(100); int startTime = millis(); while (digitalRead(button) == LOW) { delay(50); if ((millis() - startTime) > 3000) { preferences.putBool("ENROLLED", false); // 清除入网标志 Zigbee.factoryReset(); // 触发协议栈出厂复位并重启 } } }

按住 BOOT 键超过 3 秒,会清除 Preferences 中的入网标志并调用Zigbee.factoryReset()(实现见 ZigbeeCore.cpp)复位 Zigbee 协议栈并重启设备。这样设备下次启动就会以“新设备”身份重新入网,便于重新配对或移交到其他协调器。


五、源码级原理:默认配置与集群创建

5.1 默认配置宏

振动传感器端点的默认 Zigbee 配置由宏ZIGBEE_DEFAULT_VIBRATION_SENSOR_CONFIG()定义(ZigbeeVibrationSensor.h),包含三个集群的初始属性:

集群关键默认值说明
Basiczcl_versionpower_source使用 ZCL 默认值标识设备基础信息
Identifyidentify_time使用默认值支持协调器识别指令
IAS Zonezone_state = NOT_ENROLLEDzone_type = VIBRATION_MOVEMENTzone_status = 0ias_cie_addr默认、zone_id = 0xff初始未入网、振动/移动类型、无振动状态

5.2 集群列表创建

构造时调用zigbee_vibration_sensor_clusters_create()(ZigbeeVibrationSensor.cpp),依次向集群列表注册 Basic、Identify、IAS Zone 三个服务端角色集群。端点配置_ep_config声明了:

  • app_profile_id = ESP_ZB_AF_HA_PROFILE_ID(HA 应用配置文件);
  • app_device_id = ESP_ZB_HA_IAS_ZONE_ID(IAS Zone 设备类型);
  • endpoint为用户传入的端点号。

这套“HA 配置文件 + IAS Zone 设备类型 + IAS Zone 集群”的组合,正是 Home Assistant 等网关能将其识别为振动传感器的根本原因。


六、故障排查与注意事项

结合 示例 README 与源码行为,常见问题及对策如下:

  • 设备无法加入网络:先擦除端设备 Flash 再烧录示例。若之前烧录过其他 Zigbee 固件,残留的入网信息会阻止重新入网;
  • setVibration()返回 false:检查是否已入网——report()_enrolled == false时会直接返回失败并打印IAS Zone not enrolled日志;
  • restoreIASZoneEnroll()返回 false:说明存储属性中缺少 IAS CIE 地址或 Zone ID,或 Zone ID 无效(0xFF)。请确认设备此前确实完成过入网;
  • 上报不生效:确认协调器的 IAS 客户端端点号,若不为 1,需在入网前调用setIASClientEndpoint()修改;
  • 硬件与连接:使用质量可靠的 USB 数据线与稳定电源;若烧录失败可降低串口波特率;COM 口无法识别时检查驱动安装。

七、总结

ZigbeeVibrationSensor为 ESP32-C6 / ESP32-H2 提供了完整、开箱即用的 Zigbee HA 振动传感器实现:

  • 状态上报setVibration()一条调用即可完成属性写入与自动上报;
  • 入网管理requestIASZoneEnroll()/restoreIASZoneEnroll()/enrolled()覆盖新设备入网、断电恢复、状态查询全流程;
  • 工程实践:官方示例示范了 Preferences 持久化入网标志、边沿触发检测、防抖延时、长按复位等生产级细节。

开发者只需替换自己的振动传感器引脚与检测逻辑,即可快速构建安防监测、设备状态监控等 Zigbee 应用。更完整的端点基类能力(绑定、OTA、电源属性等)可进一步参考 ZigbeeEP 与 Zigbee 核心 的公开接口。

【免费下载链接】arduino-esp32Arduino core for the ESP32 family of SoCs项目地址: https://gitcode.com/GitHub_Trending/ar/arduino-esp32

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询