尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

arduino-esp32 Zigbee 风扇控制路由设备实战:用 ZigbeeFanControl 类构建 HA 风扇控制节点

arduino-esp32 Zigbee 风扇控制路由设备实战:用 ZigbeeFanControl 类构建 HA 风扇控制节点 arduino-esp32 Zigbee 风扇控制路由设备实战用 ZigbeeFanControl 类构建 HA 风扇控制节点【免费下载链接】arduino-esp32Arduino core for the ESP32 family of SoCs项目地址: https://gitcode.com/GitHub_Trending/ar/arduino-esp32本文基于 arduino-esp32 仓库中的 Zigbee_Fan_Control 示例 展开讲解如何把一块 ESP32-C6 或 ESP32-H2 开发板构建成 Zigbee 网络中的风扇控制Fan Control路由设备从 Arduino IDE 的 Zigbee 模式与分区配置、示例代码逐段解析到 ZigbeeFanControl 端点类在底层如何通过 Basic、Identify、Fan Control 三个 ZCL 集群响应网络风扇控制指令。读完本文你可以独立完成风扇控制节点的烧录、入网、模式切换回调绑定并理解工厂重置factoryReset与网络开放openNetwork机制的原理。一、示例定位与支持的目标芯片该示例演示了如何用 Arduino-ESP32 自带的 Zigbee 库创建一个router路由器角色的风扇控制设备并将其作为 Home AutomationHA配置文件下的风扇控制终端。其核心功能包含三点摘自 README初始化一个 Zigbee 风扇控制设备控制风扇模式OFF、LOW、MEDIUM、HIGH、ON响应来自 Zigbee 网络协调器/其他设备下发的风扇控制指令。README 声明支持的目标为ESP32-C6和ESP32-H2并配套硬件为ESP32-H2 或 ESP32-C6 开发板用于供电与烧录的 USB 数据线RGB LED 用于状态可视化多数开发板内置。从源码结构看这两个芯片的 Zigbee 支持走的是“本地射频”路线。在 boards.txt 中esp32c6与esp32h2的ZigbeeMode.zczr选项都链接了zboss_port.native例如esp32c6.menu.ZigbeeMode.zczr.build.zigbee_libs-lesp_zb_api.zczr -lzboss_stack.zczr -lzboss_port.native即片上 802.15.4 射频直接驱动 ZBOSS 协议栈而 ESP32-C3/S2/S3 等芯片的 zczr 选项则使用zboss_port.remote外挂 RCP 方案。这也解释了为什么本示例的支持目标限定在 C6/H2 这类原生射频芯片上。示例目录下的 ci.yml 也印证了编译前提fqbn_append: PartitionSchemezigbee_zczr,ZigbeeModezczr且要求CONFIG_ZB_ENABLEDy。二、风扇模式与 LED 颜色映射示例用 RGB LED 直观显示当前风扇控制模式README 定义的映射关系如下风扇模式LED 表现OFF不亮LOW蓝色MEDIUM黄色HIGH红色ON白色按钮引脚通过修改button变量设置默认使用BOOT_PINESP32-C6 与 ESP32-H2 上的 BOOT 按键用于长时间按压触发工厂重置。三、示例代码逐段解析完整源码见 Zigbee_Fan_Control.ino全文如下关键处附说明#include Arduino.h #ifndef ZIGBEE_MODE_ZCZR #error Zigbee coordinator mode is not selected in Tools-Zigbee mode #endif #include Zigbee.h /* Zigbee light bulb configuration */ #define ZIGBEE_FAN_CONTROL_ENDPOINT 1 #ifdef RGB_BUILTIN uint8_t led RGB_BUILTIN; // To demonstrate the current fan control mode #else uint8_t led 2; #endif uint8_t button BOOT_PIN; ZigbeeFanControl zbFanControl ZigbeeFanControl(ZIGBEE_FAN_CONTROL_ENDPOINT); /********************* fan control callback function **************************/ void setFan(ZigbeeFanMode mode) { switch (mode) { case FAN_MODE_OFF: rgbLedWrite(led, 0, 0, 0); // Off Serial.println(Fan mode: OFF); break; case FAN_MODE_LOW: rgbLedWrite(led, 0, 0, 255); // Blue Serial.println(Fan mode: LOW); break; case FAN_MODE_MEDIUM: rgbLedWrite(led, 255, 255, 0); // Yellow Serial.println(Fan mode: MEDIUM); break; case FAN_MODE_HIGH: rgbLedWrite(led, 255, 0, 0); // Red Serial.println(Fan mode: HIGH); break; case FAN_MODE_ON: rgbLedWrite(led, 255, 255, 255); // White Serial.println(Fan mode: ON); break; default: log_e(Unhandled fan mode: %d, mode); break; } } /********************* Arduino functions **************************/ void setup() { Serial.begin(115200); // Init LED that will be used to indicate the current fan control mode rgbLedWrite(led, 0, 0, 0); // Init button for factory reset pinMode(button, INPUT_PULLUP); //Optional: set Zigbee device name and model zbFanControl.setManufacturerAndModel(Espressif, ZBFanControl); // Set the fan mode sequence to LOW_MED_HIGH zbFanControl.setFanModeSequence(FAN_MODE_SEQUENCE_LOW_MED_HIGH); // Set callback function for fan mode change zbFanControl.onFanModeChange(setFan); //Add endpoint to Zigbee Core Serial.println(Adding ZigbeeFanControl endpoint to Zigbee Core); Zigbee.addEndpoint(zbFanControl); // When all EPs are registered, start Zigbee in ROUTER mode if (!Zigbee.begin(ZIGBEE_ROUTER)) { Serial.println(Zigbee failed to start!); Serial.println(Rebooting...); ESP.restart(); } Serial.println(Connecting to network); while (!Zigbee.connected()) { Serial.print(.); delay(100); } Serial.println(); } void loop() { // Checking button for factory reset if (digitalRead(button) LOW) { // Push button pressed // Key debounce handling delay(100); int startTime millis(); while (digitalRead(button) LOW) { delay(50); if ((millis() - startTime) 3000) { // If key pressed for more than 3secs, factory reset Zigbee and reboot Serial.println(Resetting Zigbee to factory and rebooting in 1s.); delay(1000); Zigbee.factoryReset(); } } } delay(100); }3.1 模式编译期检查与端点对象文件开头用#ifndef ZIGBEE_MODE_ZCZR#error做编译期断言只有在 Arduino IDE 的Tools - Zigbee mode选中Zigbee ZCZR (coordinator/router)时预处理器宏ZIGBEE_MODE_ZCZR才会被定义对应 boards.txt 中zigbee_mode-DZIGBEE_MODE_ZCZR的构建参数否则直接编译失败并给出提示。ZIGBEE_FAN_CONTROL_ENDPOINT定义为端点号1ZigbeeFanControl zbFanControl ZigbeeFanControl(1)在栈上创建风扇控制端点对象构造参数即 ZCL 端点号。LED 优先取板级内置宏RGB_BUILTIN多数 ESP32 板支持rgbLedWrite直接驱动否则回退到 GPIO 2按钮默认BOOT_PIN。3.2 setup() 初始化流程按顺序做了 5 件事Serial.begin(115200)打开串口日志rgbLedWrite(led, 0, 0, 0)先熄灭 LED 作为初始状态pinMode(button, INPUT_PULLUP)把 BOOT 按键配置为内部上拉输入用于后续工厂重置检测配置设备标识与风扇行为setManufacturerAndModel(Espressif, ZBFanControl)可选步骤写入 Basic 集群的厂商/型号字符串便于协调器识别设备setFanModeSequence(FAN_MODE_SEQUENCE_LOW_MED_HIGH)声明该风扇支持的模式切换序列为“低→中→高”onFanModeChange(setFan)注册风扇模式变化回调网络端下发新风扇模式时即调用setFan更新 LED 与串口日志注册端点并启动协议栈Zigbee.addEndpoint(zbFanControl)把端点挂到全局ZigbeeZigbeeCore 的单例上随后Zigbee.begin(ZIGBEE_ROUTER)以路由器角色启动失败则ESP.restart()重启进入while (!Zigbee.connected())阻塞等待入网成功串口每秒打印一个.。3.3 loop() 中的工厂重置逻辑loop()持续轮询 BOOT 按键检测到按下后先做 100 ms 消抖之后若按键持续超过 3000 ms则延时 1 s 并调用Zigbee.factoryReset()默认参数restarttrue执行协议栈重置并重启将设备从当前 Zigbee 网络中“摘除”恢复出厂网络状态。这对应 README 排障章节中“在 sketch 里加入Zigbee.factoryReset()以重置设备和 Zigbee 栈”的建议。四、ZigbeeFanControl 类的底层实现示例的全部行为由 ZigbeeFanControl继承自公共端点基类ZigbeeEP驱动实现见 ZigbeeFanControl.cpp。4.1 端点与集群构造构造器ZigbeeFanControl.cpp#L18-L31做了三件事创建 ZCL 集群列表并依次加入Basic、Identify、Fan Control三个集群角色均为ESP_ZB_ZCL_CLUSTER_SERVER_ROLE服务器角色即该端点响应读取/写入这些集群属性的指令填充端点配置app_profile_id ESP_ZB_AF_HA_PROFILE_IDHA 配置文件、app_device_id ESP_ZB_HA_HEATING_COOLING_UNIT_DEVICE_ID源码注释明确说明_device_id取的是ESP_ZB_HA_THERMOSTAT_DEVICE_ID因为“Zigbee 规范中没有 FAN_CONTROL_DEVICE_ID”即风扇控制在 HA 规范里归入温控单元类设备——这是理解该端点为何能接入 HA 生态的关键细节。4.2 风扇模式与模式序列枚举ZigbeeFanControl.h#L27-L44 定义了 Arduino 风格的两个枚举一一映射到 ESP-IDF Zigbee 栈的 ZCL 常亮值风扇模式ZigbeeFanMode语义FAN_MODE_OFF关闭FAN_MODE_LOW低速FAN_MODE_MEDIUM中速FAN_MODE_HIGH高速FAN_MODE_ON开启最高档FAN_MODE_AUTO自动FAN_MODE_SMART智能扩展枚举值模式序列ZigbeeFanModeSequence语义FAN_MODE_SEQUENCE_LOW_MED_HIGH低→中→高示例采用FAN_MODE_SEQUENCE_LOW_HIGH低→高FAN_MODE_SEQUENCE_LOW_MED_HIGH_AUTO低→中→高→自动FAN_MODE_SEQUENCE_LOW_HIGH_AUTO低→高→自动FAN_MODE_SEQUENCE_ON_AUTO开/关→自动这些值最终写入 Fan Control 集群的Fan Mode与Fan Mode Sequence属性供网络侧如 Zigbee 控制台/协调器应用读取以正确渲染控制 UI。4.3 属性写入与回调触发链路setFanModeSequence()ZigbeeFanControl.cpp#L33-L50通过esp_zb_cluster_list_get_cluster取到 Fan Control 集群再用esp_zb_cluster_update_attr更新Fan Mode Sequence属性成功后把本地_current_fan_mode重置为FAN_MODE_OFF并同步写入Fan Mode属性——即每次设置序列都会把风扇状态复位到 OFF。任一步esp_err_t非 OK 都会记录错误日志并返回false。zbAttributeSet()ZigbeeFanControl.cpp#L53-L74这是基类虚函数是网络侧 ZCL 属性写请求进入应用层的入口。它做严格的数据校验——仅接受ESP_ZB_ZCL_CLUSTER_ID_FAN_CONTROL集群、ESP_ZB_ZCL_ATTR_FAN_CONTROL_FAN_MODE_ID属性、类型为 8 位枚举的消息再检查原始值不超过FAN_MODE_SMART越界则打 warning 并忽略最后更新_current_fan_mode并调用fanModeChanged()。fanModeChanged()若用户已注册回调则执行之否则打印No callback function set for fan mode change警告。示例中这条链路就是协调器下发 Write Attributes →zbAttributeSet校验通过 →setFan(mode)点灯并打印Fan mode: XXX。4.4 状态查询接口类还暴露了两个只读接口getFanMode()与getFanModeSequence()方便应用代码在loop()中主动读取当前风扇状态例如驱动真实风机电机、PWM 调速器而不只是演示 LED。五、Arduino IDE 配置步骤按 README 的要求编译烧录前需在 IDE 中完成以下选择Tools - Board选择正确的 ESP32-C6 / ESP32-H2 开发板Tools - Zigbee mode: Zigbee ZCZR (coordinator/router)该选项向构建系统注入-DZIGBEE_MODE_ZCZR并链接esp_zb_api.zczr、zboss_stack.zczr、zboss_port.native三个库见 boards.txt 中对应板型的ZigbeeMode.zczr配置C6/H2 另有ZCZR debug变体会链接带.debug后缀的调试库Tools - Partition Scheme: Zigbee ZCZR 4MB with spiffs对应zigbee_zczr分区表boards.txt 中该方案的upload.maximum_size为 1310720 字节约 1.25 MB应用空间C6/H2 同时提供 2MB/8MB 的 Zigbee 分区变体Tools - Port: xxx选择检测到的串口可选Tools - Core Debug Level: Verbose可看到 Zigbee 协议栈的全部日志便于排障。注意Zigbee 功能依赖CONFIG_ZB_ENABLEDy见 ci.yml 中的requiresIDE 下选择 ZCZR 模式后即会自动启用同时所有 Zigbee 库头文件都包在#if CONFIG_ZB_ENABLED条件编译中如 ZigbeeCore.h 的头部未启用时整个库不参与编译。六、入网管理开放网络与工厂重置README 的排障章节给出了入网失败的常见处理其背后机制都可以从 ZigbeeCore.h 的 API 得到印证设备连不上协调器重新烧录协调器后建议先擦除从设备示例中的路由设备全部 Flash 再烧录。两种做法IDE 中把Erase All Flash Before Sketch Upload设为Enabled或在 sketch 中调用Zigbee.factoryReset()重置设备与 Zigbee 栈。对应ZigbeeCore::factoryReset(bool restart true)ZigbeeCore.h#L196。协调器默认在重启或烧录新固件后网络关闭。若要允许设备加入有两个入口ZigbeeCore.h#L185-L187在调用Zigbee.begin()之前设置Zigbee.setRebootOpenNetwork(time);使每次重启后自动开放网络time秒或在应用任意时刻调用Zigbee.openNetwork(time);临时开放入网窗口closeNetwork()可随时关闭。示例中设备角色是ZIGBEE_ROUTER见Zigbee.begin(ZIGBEE_ROUTER)README 排障段落虽以“End device”措辞描述但原理一致ZBOSS 对路由/终端设备都要求擦除旧 NV 网络数据后才能加入新网络。路由角色默认配置可从ZIGBEE_DEFAULT_ROUTER_CONFIG()宏看到max_children 10即最多可托管 10 个子终端设备ZigbeeCore.h#L61-L69。ZigbeeCore的角色枚举为ZIGBEE_COORDINATOR / ZIGBEE_ROUTER / ZIGBEE_END_DEVICEbegin()的第二参数erase_nvs可在启动时直接擦除 NVS 网络存储ZigbeeCore.h#L140是与“擦 Flash 重烧”等效的代码级手段。七、常见问题速查整理自 README 的 Troubleshooting 章节并强调其前置提醒——务必使用质量可靠的 USB 线与稳定的电源现象处理建议设备加入网络失败先擦除从设备 Flash 再烧录重新烧录协调器时尤其如此代码中可加Zigbee.factoryReset()协调器重启后不开放网络Zigbee.setRebootOpenNetwork(time)在begin前调用或运行时Zigbee.openNetwork(time)LED 不亮检查接线与 IO 选择led引脚烧录失败降低串口通信速率检测不到 COM 口检查 USB 线与 USB 转串口驱动若问题依旧可参考仓库贡献与问题反馈流程见 CONTRIBUTING.md提交 issue 前建议先排查上述条目并检索是否已有同类问题。八、关键文件索引文件说明libraries/Zigbee/examples/Zigbee_Fan_Control/README.md示例官方说明目标、硬件、IDE 配置与排障libraries/Zigbee/examples/Zigbee_Fan_Control/Zigbee_Fan_Control.ino示例主程序端点注册、回调、工厂重置libraries/Zigbee/examples/Zigbee_Fan_Control/ci.ymlCI 编译约束ZCZR 模式 zigbee_zczr分区 CONFIG_ZB_ENABLEDlibraries/Zigbee/src/ep/ZigbeeFanControl.h风扇模式/序列枚举与端点类声明libraries/Zigbee/src/ep/ZigbeeFanControl.cpp集群构造、属性写入与回调触发实现libraries/Zigbee/src/ZigbeeCore.h协议栈核心角色、begin、open/closeNetwork、factoryReset、全局单例Zigbeeboards.txt各板型 Zigbee 模式与 Zigbee 分区选项ZigbeeMode.zczr、PartitionScheme.zigbee_zczr按本文配置完成烧录后串口会先打印Adding ZigbeeFanControl endpoint to Zigbee Core入网成功后停止打印.此后从协调器侧下发任意 Fan Control 写指令设备即会按“OFF 灭灯 / LOW 蓝 / MEDIUM 黄 / HIGH 红 / ON 白”的映射更新 LED 并输出Fan mode: XXX日志按住 BOOT 键 3 秒以上则执行Zigbee.factoryReset()重置网络——即完成了一个可复用为真实风扇控制节点的完整闭环。【免费下载链接】arduino-esp32Arduino core for the ESP32 family of SoCs项目地址: https://gitcode.com/GitHub_Trending/ar/arduino-esp32创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表