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_type为ESP_ZB_ZCL_IAS_ZONE_ZONETYPE_VIBRATION_MOVEMENT(振动/移动类型),zone_state为NOT_ENROLLED。
三、API 方法详解
3.1 setVibration —— 设置振动检测状态
bool setVibration(bool sensed);sensed:振动状态,true表示检测到振动,false表示未检测到。- 返回值:成功返回
true,失败返回false。
该方法是振动传感器的核心动作接口。底层实现(ZigbeeVibrationSensor.cpp)做了两件事:
- 将布尔值写入 IAS Zone 集群的ZoneStatus 属性(
ESP_ZB_ZCL_ATTR_IAS_ZONE_ZONESTATUS_ID); - 更新内部
_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_status、zone_id、extend_status = 0、delay = 0等字段。
正常情况下无需手动调用——setVibration()内部已自动上报。
3.4 requestIASZoneEnroll —— 请求 IAS Zone 入网
bool requestIASZoneEnroll();- 返回值:入网请求发送成功返回
true,否则返回false。注意,真正的入网结果需要用enrolled()等待并确认。
该方法用于新设备首次入网或已入网设备重新入网。底层发送IAS Zone Enroll Request命令(ZigbeeVibrationSensor.cpp),请求中携带:
src_endpoint:本设备端点;zone_type:ESP_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_ADDRESS与ZONEID两个属性,任一读取失败即返回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_SUPPORTED与CONFIG_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); }关键点:
- 首次上电(标志为 false):走
requestIASZoneEnroll()申请新入网,等待协调器分配 Zone ID; - 重启(标志为 true):走
restoreIASZoneEnroll()直接从闪存恢复,速度更快; - 入网成功后,仅当本次是全新入网时才把
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),包含三个集群的初始属性:
| 集群 | 关键默认值 | 说明 |
|---|---|---|
| Basic | zcl_version、power_source使用 ZCL 默认值 | 标识设备基础信息 |
| Identify | identify_time使用默认值 | 支持协调器识别指令 |
| IAS Zone | zone_state = NOT_ENROLLED、zone_type = VIBRATION_MOVEMENT、zone_status = 0、ias_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),仅供参考