Arduino ESP32 Zigbee 颜色调光开关(ZigbeeColorDimmerSwitch)端点开发指南
Arduino ESP32 Zigbee 颜色调光开关ZigbeeColorDimmerSwitch端点开发指南【免费下载链接】arduino-esp32Arduino core for the ESP32 family of SoCs项目地址: https://gitcode.com/GitHub_Trending/ar/arduino-esp32导读本文以 arduino-esp32 仓库 Zigbee 库 中的ZigbeeColorDimmerSwitch类为核心讲解如何在 ESP32-C6 / ESP32-H2 上实现一个符合 Zigbee Home AutomationHA标准的高级照明控制开关端点。该端点可以绑定并同时控制灯具的开关状态、亮度0–100%、颜色RGB/HSV、色温以及场景和组操作。读完本文你将掌握该类的完整 API、四种目标寻址方式默认绑定、组地址、短地址、IEEE 地址的用法、ZCL 调光与颜色命令的底层实现原理并能基于仓库提供的示例独立搭建一个可用的 Zigbee 智能照明遥控器。类概览ZigbeeColorDimmerSwitchZigbeeColorDimmerSwitch是 ZigbeeColorDimmerSwitch.h 中定义的一个 Zigbee 端点类继承自通用端点基类ZigbeeEP见 ZigbeeEP.h。它面向开关/遥控器一侧的角色作为 Zigbee 协调器或路由器向被绑定的彩色可调光灯例如运行Zigbee_Color_Dimmable_Light示例的终端设备发送控制命令。从构造实现ZigbeeColorDimmerSwitch.cpp可以看到构造函数完成了三件事将设备 ID 注册为ESP_ZB_HA_COLOR_DIMMER_SWITCH_DEVICE_ID使用 Home Automation profileESP_ZB_AF_HA_PROFILE_ID通过ESP_ZB_DEFAULT_COLOR_DIMMABLE_SWITCH_CONFIG()与esp_zb_color_dimmable_switch_clusters_create()创建标准集群列表On/Off、Level Control、Color Control初始化内部颜色状态缓存RGB、HSV、XY 三个色彩模型。官方文档 ep_color_dimmer_switch.rst 将其功能概括为对被绑定灯具的开关控制亮度等级控制0–100%颜色控制RGB、HSV色温控制场景与组支持特殊效果与定时操作与通用端点功能集成绑定、OTA 等Zigbee HA 标准合规典型应用场景包括智能照明开关、彩色控制遥控器、高级照明控制器、智能家居照明自动化以及娱乐照明控制。支持的目标芯片根据示例 READMEZigbee_Color_Dimmer_Switch/README.md该功能目前支持ESP32-C6与ESP32-H2两个芯片系列这两个系列内置 IEEE 802.15.4 无线收发器可直接运行 Zigbee 协议栈。构造函数ZigbeeColorDimmerSwitch(uint8_t endpoint);endpoint端点号取值范围 1–254。示例中使用了5#define SWITCH_ENDPOINT_NUMBER 5 ZigbeeColorDimmerSwitch zbSwitch ZigbeeColorDimmerSwitch(SWITCH_ENDPOINT_NUMBER);基本控制命令开关三个基本开关命令均提供四种重载分别对应四种目标寻址方式重载目标寻址方式lightXxx()发送到所有已绑定设备ESP_ZB_APS_ADDR_MODE_DST_ADDR_ENDP_NOT_PRESENTlightXxx(uint16_t group_addr)发送到指定组地址16 位组地址广播给组内成员lightXxx(uint8_t endpoint, uint16_t short_addr)发送到指定端点的短地址设备lightXxx(uint8_t endpoint, esp_zb_ieee_addr_t ieee_addr)发送到指定端点的 IEEE长地址设备lightToggle切换被绑定灯具的开关状态开→关 或 关→开void lightToggle(); void lightToggle(uint16_t group_addr); void lightToggle(uint8_t endpoint, uint16_t short_addr); void lightToggle(uint8_t endpoint, esp_zb_ieee_addr_t ieee_addr);lightOn / lightOff打开 / 关闭被绑定灯具void lightOn(); void lightOn(uint16_t group_addr); void lightOn(uint8_t endpoint, uint16_t short_addr); void lightOn(uint8_t endpoint, esp_zb_ieee_addr_t ieee_addr); void lightOff(); void lightOff(uint16_t group_addr); void lightOff(uint8_t endpoint, uint16_t short_addr); void lightOff(uint8_t endpoint, esp_zb_ieee_addr_t ieee_addr);从实现源码看ZigbeeColorDimmerSwitch.cpp这些命令最终封装为 ZCL On/Off 集群的命令请求esp_zb_zcl_on_off_cmd_req命令 ID 对应ESP_ZB_ZCL_CMD_ON_OFF_TOGGLE_ID/ON_ID/OFF_ID并受acquireCommandLock()信号量保护以保证多任务下的线程安全。若尚未绑定_is_bound false命令不会发出而是打印错误日志Light not bound。调光控制命令setLightLevel设置被绑定灯具的亮度等级level取值范围 0–1000 为关100 为全亮void setLightLevel(uint8_t level); void setLightLevel(uint8_t level, uint16_t group_addr); void setLightLevel(uint8_t level, uint8_t endpoint, uint16_t short_addr); void setLightLevel(uint8_t level, uint8_t endpoint, esp_zb_ieee_addr_t ieee_addr);实现上对应 ZCL Level Control 集群的Move to Level命令esp_zb_zcl_move_to_level_cmd_t。注意一个实现细节无参版本在构造命令时把transition_time固定为0xffff源码即请求灯具以自身能达到的最快速度切换亮度不做渐变过渡。setLightLevelStep发送阶梯调光命令沿指定方向按固定步长改变当前亮度void setLightLevelStep(ZigbeeLevelStepDirection direction, uint8_t step_size, uint16_t transition_time); void setLightLevelStep(ZigbeeLevelStepDirection direction, uint8_t step_size, uint16_t transition_time, uint16_t group_addr); void setLightLevelStep(ZigbeeLevelStepDirection direction, uint8_t step_size, uint16_t transition_time, uint8_t endpoint, uint16_t short_addr); void setLightLevelStep(ZigbeeLevelStepDirection direction, uint8_t step_size, uint16_t transition_time, uint8_t endpoint, esp_zb_ieee_addr_t ieee_addr);参数说明direction方向枚举ZigbeeLevelStepDirectionZIGBEE_LEVEL_STEP_UP0表示向上、ZIGBEE_LEVEL_STEP_DOWN1表示向下定义见 ZigbeeColorDimmerSwitch.hstep_size步长即 CurrentLevel 属性变化的单位数例如 1–254transition_time执行该步进所需的过渡时间单位为 0.1 秒1 个单位 100 ms。ZCL Step 命令的过渡时间语义原文档明确说明务必留意过渡时间以十分之一秒为单位指设备执行这次步进应花费的时间一次步进即 CurrentLevel 变化step_size个单位设备应尽量贴近该时长执行如果设备不支持变速移动可以忽略过渡时间而以固定速率移动传入0xFFFF65535表示要求设备以它能力所及的最快速度移动不指定具体时长。示例// 向上步进 10 个单位过渡时间 1 秒10 × 100ms setLightLevelStep(ZIGBEE_LEVEL_STEP_UP, 10, 10); // 向下步进 5 个单位以最快速度执行 setLightLevelStep(ZIGBEE_LEVEL_STEP_DOWN, 5, 0xFFFF);实现上对应esp_zb_zcl_level_step_cmd_t与esp_zb_zcl_level_step_cmd_req源码step_mode直接取direction枚举值。颜色控制命令setLightColor使用 RGB 值设置被绑定灯具的颜色三个分量取值范围均为 0–255void setLightColor(uint8_t red, uint8_t green, uint8_t blue); void setLightColor(uint8_t red, uint8_t green, uint8_t blue, uint16_t group_addr); void setLightColor(uint8_t red, uint8_t green, uint8_t blue, uint8_t endpoint, uint16_t short_addr); void setLightColor(uint8_t red, uint8_t green, uint8_t blue, uint8_t endpoint, esp_zb_ieee_addr_t ieee_addr);底层实现值得注意源码Zigbee 的 Color Control 集群标准命令是Move to Color其颜色字段是CIE 1931 XY 色度坐标而非 RGB。因此库内部通过espRgbToXYColor(red, green, blue)将 RGB 转换为 XY 坐标后填入esp_zb_zcl_color_move_to_color_cmd_t再调用esp_zb_zcl_color_move_to_color_cmd_req发送。transition_time在此处固定为0即立即切换颜色、不做渐变。高级控制命令lightOffWithEffect以指定效果关闭灯具void lightOffWithEffect(uint8_t effect_id, uint8_t effect_variant);effect_id效果标识符effect_variant效果变体底层使用 On/Off 集群的Off with Effect命令esp_zb_zcl_on_off_off_with_effect_cmd_t源码例如延迟关闭淡出等由灯具端实现的视觉效果。lightOnWithTimedOff打开灯具并在指定时间后自动关闭void lightOnWithTimedOff(uint8_t on_off_control, uint16_t time_on, uint16_t time_off);on_off_control控制字节time_on保持开启的时间单位 0.1 秒time_off保持关闭的时间单位 0.1 秒底层使用esp_zb_zcl_on_off_on_with_timed_off_cmd_t源码on_time与off_wait_time字段分别对应time_on、time_off。lightOnWithSceneRecall打开灯具并同时恢复场景void lightOnWithSceneRecall();底层使用esp_zb_zcl_on_off_on_with_recall_global_scene_cmd_req源码适用于一键恢复预设场景的场景。状态查询与回调文档之外的有用补充除控制命令外ZigbeeColorDimmerSwitch.h 还提供了与文档 API 同构的状态读取与事件回调接口方便构建带反馈的遥控器getLightState()/getLightState(...)读取 On/Off 集群的OnOff属性ESP_ZB_ZCL_ATTR_ON_OFF_ON_OFF_IDgetLightLevel()/getLightLevel(...)读取 Level Control 集群的CurrentLevel属性ESP_ZB_ZCL_ATTR_LEVEL_CONTROL_CURRENT_LEVEL_IDgetLightColor()/getLightColor(...)读取 Color Control 集群的CurrentX/CurrentY两个 XY 属性getLightColorHS()/getLightColorHS(...)读取 Color Control 集群的CurrentHue/CurrentSaturation两个 HS 属性。回调接口每类均提供不带源信息与带源信息两个版本void onLightStateChange(void (*callback)(bool)); void onLightStateChangeWithSource(void (*callback)(bool, uint8_t, esp_zb_zcl_addr_t)); void onLightLevelChange(void (*callback)(uint8_t)); void onLightLevelChangeWithSource(void (*callback)(uint8_t, uint8_t, esp_zb_zcl_addr_t)); void onLightColorChange(void (*callback)(uint8_t, uint8_t, uint8_t)); void onLightColorChangeWithSource(void (*callback)(uint8_t, uint8_t, uint8_t, uint8_t, esp_zb_zcl_addr_t));这些回调由zbAttributeRead()虚函数ZigbeeColorDimmerSwitch.cpp触发它在收到属性读取响应后按集群分类处理On/Off 属性直接回调布尔状态Level 属性回调 8 位亮度Color Control 的 X/Y 与 H/S 属性则分别积累到内部_light_color_xy/_light_color_hsv缓存待成对数据齐全后通过espXYToRgbColor或espHsvColorToRgbColor转换为 RGB 再回调从而保证回调参数始终是完整的 RGB 三元组。绑定机制与底层原理开关必须先与灯具建立绑定关系才能向其发送命令。这一过程由基类与端点类协作完成从源码可以还原出完整流程ZigbeeColorDimmerSwitch.cpp设备入网后端点通过findEndpoint()发起 ZDOMatch Descriptor请求esp_zb_zdo_match_cluster匹配目标为 HA profile 下具备 On/Off、Level Control、Color Control 三个集群输入、输出各 3 个的设备——即彩色可调光灯匹配成功后触发findCb()在其中通过esp_zb_ieee_address_by_short将短地址解析为 IEEE 地址并依次对三个集群ESP_ZB_ZCL_CLUSTER_ID_ON_OFF、LEVEL_CONTROL、COLOR_CONTROL发起 ZDO 绑定请求esp_zb_zdo_device_bind_req绑定完成触发bindCb()源码成功后把灯具的短地址、端点、IEEE 地址存入_bound_devices列表并将_is_bound置真。因此用户代码中判断绑定状态的惯用法是轮询zbSwitch.bound()示例中即while (!zbSwitch.bound()) { Serial.printf(.); delay(500); }另外示例调用了zbSwitch.allowMultipleBinding(true)允许一个开关同时绑定多盏灯对应基类ZigbeeEP::allowMultipleBindingZigbeeEP.h并可用printBoundDevices(Serial)定时打印所有已绑定设备。这些能力继承自通用端点基类ZigbeeEP同类的绑定、OTA、鉴权等通用功能addOTAClient、requestOTAUpdate等对该端点同样可用。完整示例Zigbee_Color_Dimmer_Switch仓库提供了可编译运行的完整示例 Zigbee_Color_Dimmer_Switch.ino下面按模块拆解其核心逻辑。配置与初始化#include Arduino.h #ifndef ZIGBEE_MODE_ZCZR #error Zigbee coordinator mode is not selected in Tools-Zigbee mode #endif #include Zigbee.h #define SWITCH_ENDPOINT_NUMBER 5 uint8_t button BOOT_PIN; ZigbeeColorDimmerSwitch zbSwitch ZigbeeColorDimmerSwitch(SWITCH_ENDPOINT_NUMBER);示例角色是协调器ZCZR因此头文件通过#error强制校验ZIGBEE_MODE_ZCZR宏防止在错误模式下编译。setup()中的初始化步骤Serial.begin(115200); pinMode(button, INPUT_PULLUP); // 可选设置 Zigbee 设备名称与型号 zbSwitch.setManufacturerAndModel(Espressif, ZigbeeSwitch); // 可选允许开关同时绑定多盏灯 zbSwitch.allowMultipleBinding(true); // 将端点注册到 Zigbee Core Zigbee.addEndpoint(zbSwitch); // 开机后开放入网 180 秒 Zigbee.setRebootOpenNetwork(180); // 注册完所有端点后以协调器模式启动 Zigbee if (!Zigbee.begin(ZIGBEE_COORDINATOR)) { Serial.println(Zigbee failed to start!); Serial.println(Rebooting...); ESP.restart(); }几点说明Zigbee.addEndpoint(zbSwitch)将端点加入 ZigbeeCore见 ZigbeeCore.hZigbee.setRebootOpenNetwork(180)让协调器每次重启后自动开放入网 180 秒方便灯具重新入网/绑定。若需随时手动开放入网可调用Zigbee.openNetwork(time)Zigbee.begin(ZIGBEE_COORDINATOR)使用协调器角色启动角色枚举见 ZigbeeCore.h另有ZIGBEE_ROUTER、ZIGBEE_END_DEVICE可选。按键与串口控制loop()中按键默认 BOOT 引脚负责开关切换串口命令负责更精细的控制// 按键消抖后切换灯具开关 if (digitalRead(button) LOW) { while (digitalRead(button) LOW) { delay(50); } zbSwitch.lightToggle(); } // 串口命令解析 if (Serial.available()) { String command Serial.readString(); if (command on) { zbSwitch.lightOn(); } else if (command off) { zbSwitch.lightOff(); } else if (command toggle) { zbSwitch.lightToggle(); } else if (command red) { zbSwitch.setLightColor(255, 0, 0); } else if (command green) { zbSwitch.setLightColor(0, 255, 0); } else if (command blue) { zbSwitch.setLightColor(0, 0, 255); } else if (command white) { zbSwitch.setLightColor(255, 255, 255); } else if (command color) { // 依次等待输入 R、G、B0-255 ... zbSwitch.setLightColor(red, green, blue); } else if (command level) { // 等待输入 level0-255 ... zbSwitch.setLightLevel(level); } else if (command stepup) { // 向上步进 20 个单位过渡 1 秒 zbSwitch.setLightLevelStep(ZIGBEE_LEVEL_STEP_UP, 20, 10); } else if (command stepdown) { zbSwitch.setLightLevelStep(ZIGBEE_LEVEL_STEP_DOWN, 20, 10); } else if (command stepupfast) { // 向上步进 10 个单位最快速度transition_time 0xFFFF zbSwitch.setLightLevelStep(ZIGBEE_LEVEL_STEP_UP, 10, 0xFFFF); } else if (command stepdownfast) { zbSwitch.setLightLevelStep(ZIGBEE_LEVEL_STEP_DOWN, 10, 0xFFFF); } else if (command help) { Serial.println(Commands: on, off, toggle, red, green, blue, white, color, level, stepup, stepdown, stepupfast, stepdownfast); } else { Serial.println(Unknown command (type help for list)); } }此外loop()每 30 秒调用一次zbSwitch.printBoundDevices(Serial)在串口输出当前所有已绑定灯具的地址与端点信息方便调试绑定状态。环境配置与烧录要点根据示例 READMEZigbee_Color_Dimmer_Switch/README.md在 Arduino IDE 中运行该示例需要硬件两块开发板ESP32-C6 或 ESP32-H2——一块刷入Zigbee_Color_Dimmer_Light示例作为灯具终端设备另一块刷入Zigbee_Color_Dimmer_Switch示例作为协调器开关选择 Zigbee 协调器模式Tools - Zigbee mode - Zigbee ZCZR (coordinator/router)选择 Zigbee 分区方案Tools - Partition Scheme - Zigbee 4MB with spiffs选择正确的端口Tools - Port - 对应 COM 口可选将Tools - Core Debug Level设为Verbose以查看 Zigbee 协议栈的详细日志按键引脚默认使用板载 BOOT 按键ESP32-C6 / ESP32-H2 的 GPIO 9可通过修改代码中的引脚定义调整。常见故障排查README 给出的排查建议同样值得记录终端设备无法入网如果刷过灯具示例的终端设备连不上协调器建议在重新烧录前先擦除整片 flash。可在 Arduino IDE 的Tools菜单中开启Erase All Flash Before Sketch Upload或在代码中调用Zigbee.factoryReset()重置设备与 Zigbee 协议栈网络未开放协调器默认在重启或烧录新固件后关闭入网。可通过Zigbee.setRebootOpenNetwork(time);在Zigbee.begin()之前调用在重启后自动开放网络或随时调用Zigbee.openNetwork(time);手动开放烧录失败尝试降低串口连接速率无法识别端口检查 USB 线缆质量与 USB 转串口驱动是否安装LED 不闪烁检查接线与 IO 选择是否正确。结语ZigbeeColorDimmerSwitch是 arduino-esp32 Zigbee 库中面向照明控制端的完整 HA 端点实现。它通过 On/Off、Level Control、Color Control 三个标准 ZCL 集群配合自动匹配、绑定、多设备绑定等机制把控制一盏或多盏彩色灯的复杂协议细节封装为几十个直观的 Arduino 方法。结合 示例工程、类实现 与 API 文档开发者可以快速构建出支持开关、调光、变色、场景恢复与定时关闭的 Zigbee 智能照明遥控方案。【免费下载链接】arduino-esp32Arduino core for the ESP32 family of SoCs项目地址: https://gitcode.com/GitHub_Trending/ar/arduino-esp32创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考