基于 ESP32 与 Arduino Matter 库构建色温灯设备:MatterTemperatureLight 示例全解析
【免费下载链接】arduino-esp32Arduino core for the ESP32 family of SoCs项目地址: https://gitcode.com/GitHub_Trending/ar/arduino-esp32
导读
本文围绕 arduino-esp32 仓库中 libraries/Matter/examples/MatterTemperatureLight 示例展开,深入讲解如何用 ESP32 系列 SoC 打造一台支持 Matter 协议的色温灯(Color Temperature Light)。读完本文,你将掌握:Matter 设备配网(Commissioning)的完整流程、Wi-Fi/Thread/BLE 三种芯片接入差异、色温(暖白到冷白)与亮度(0–255)的控制模型、基于Preferences的状态持久化,以及如何将设备接入 Home Assistant、Apple Home、Amazon Alexa 与 Google Home 四大智能家居生态,并得到源码级的实现佐证。
示例概述:从零构建 Matter 色温灯
MatterTemperatureLight是 arduino-esp32 的 Matter 库官方示例之一,其目标是在 ESP32 SoC 上实现一台符合 Matter 规范的色温灯配件。核心能力包括:
- Matter 协议实现色温灯设备(CW/WW 冷白/暖白双色温);
- 支持 Wi-Fi 与 Thread(*)两种底层网络;
- 色温控制(暖白到冷白,100–500 mireds 微倒度);
- 亮度控制(0–255);
- 使用
Preferences库实现开关、亮度、色温的状态持久化; - 物理按键控制:短按开关灯、长按(>5 秒)恢复出厂设置(decommission);
- RGB LED 支持(内置色温转 RGB 换算),普通 LED 支持 PWM 亮度控制;
- 通过二维码或手动配对码完成 Matter 配网;
- 与 Home Assistant、Apple HomeKit、Amazon Alexa、Google Home 集成。
(*)Thread 模式需将工程以 Arduino as IDF Component 方式编译。
在仓库中,该示例由三部分构成:MatterTemperatureLight.ino(主程序)、README.md(说明文档)与 ci.yml(CI 配置,其中fqbn_append: PartitionScheme=huge_app与CONFIG_ESP_MATTER_ENABLE_DATA_MODEL=y印证了编译所需的分区方案与 Matter 数据模型开关)。
支持的芯片目标与配网差异
| SoC | Wi-Fi | Thread | BLE Commissioning | RGB LED | 状态 |
|---|---|---|---|---|---|
| ESP32 | ✅ | ❌ | ❌ | 必需 | 完全支持 |
| ESP32-S2 | ✅ | ❌ | ❌ | 必需 | 完全支持 |
| ESP32-S3 | ✅ | ❌ | ✅ | 必需 | 完全支持 |
| ESP32-C3 | ✅ | ❌ | ✅ | 必需 | 完全支持 |
| ESP32-C5 | ❌ | ✅ | ✅ | 必需 | 支持(仅 Thread) |
| ESP32-C6 | ✅ | ❌ | ✅ | 必需 | 完全支持 |
| ESP32-H2 | ❌ | ✅ | ✅ | 必需 | 支持(仅 Thread) |
配网方式的关键差异
- ESP32 与 ESP32-S2:不支持通过 BLE(CHIPoBLE)配网,必须在 sketch 中直接写入 Wi-Fi 凭据,让设备手动连入网络。对应源码中
#if !CONFIG_ENABLE_CHIPOBLE分支(MatterTemperatureLight.ino):当未启用 CHIPoBLE 时,才会编译进WiFi.begin(ssid, password)的 Wi-Fi 连接逻辑。 - ESP32-C6:虽具备 Thread 能力,但 Arduino Matter 库预编译版本仅启用了 Wi-Fi。若需配置为纯 Thread 运行,必须以 Arduino as IDF Component 方式构建,并关闭 Matter 的 Wi-Fi station 功能。
- ESP32-C5:虽支持 2.4 GHz 与 5 GHz Wi-Fi,但 Arduino Matter 库预编译版本仅启用 Thread。若要启用 Wi-Fi,需以 Arduino as ESP-IDF component 构建并关闭 Thread 网络,仅保留 Wi-Fi station。
从 Matter.h 的 API 设计可见,ArduinoMatter 提供了isWiFiStationEnabled()、isWiFiAccessPointEnabled()、isThreadEnabled()、isBLECommissioningEnabled()等查询方法,用于在运行时同时检查 SoC 硬件能力与 Matter 配置——这正是上述芯片差异在软件层的抽象体现。
硬件要求与引脚配置
硬件上需要:
- 一块 ESP32 兼容开发板(参考上表选择芯片型号);
- 一颗 RGB LED(接到 GPIO,或使用板载 RGB LED);若无 RGB LED,也可用普通 LED 通过 PWM 做亮度控制;
- 一个用户按键用于手动控制(默认使用 BOOT 按键)。
示例中的默认引脚逻辑(MatterTemperatureLight.ino):
- RGB LED:优先使用
RGB_BUILTIN宏(板载 RGB LED),若未定义则回退到引脚 2,并触发#warning "Do not forget to set the RGB LED pin"编译警告提醒开发者; - 按键:默认使用
BOOT_PIN(即 GPIO 0,开发板 BOOT 按键)。
#ifdef RGB_BUILTIN const uint8_t ledPin = RGB_BUILTIN; #else const uint8_t ledPin = 2; // Set your pin here if your board has not defined LED_BUILTIN #warning "Do not forget to set the RGB LED pin" #endif // set your board USER BUTTON pin here const uint8_t buttonPin = BOOT_PIN; // Set your pin here. Using BOOT Button.软件环境与前置条件
安装要求
- 安装 Arduino IDE(推荐 2.0 或更新版本);
- 安装带 Matter 支持的 ESP32 Arduino Core(即当前仓库 arduino-esp32,其
libraries/Matter目录即 Matter 库本体); - 需要的 Arduino 库:
Matter(本仓库自带);Preferences(用于状态持久化);Wi-Fi(仅 ESP32 与 ESP32-S2 需要,因它们不通过 BLE 配网)。
关键配置项
上传 sketch 前需要确认以下配置:
1. Wi-Fi 凭据(不使用 BLE 配网时必须填写,对 ESP32 / ESP32-S2 是强制项):
const char *ssid = "your-ssid"; // Change to your Wi-Fi SSID const char *password = "your-password"; // Change to your Wi-Fi password2. LED 引脚(不使用板载 RGB LED 时):
const uint8_t ledPin = 2; // Set your RGB LED pin here3. 按键引脚(可选):默认使用 BOOT 按键(GPIO 0)作为灯的开关控制,可按需改到其他引脚:
const uint8_t buttonPin = BOOT_PIN; // Set your button pin here编译与烧录步骤
- 在 Arduino IDE 中打开
MatterTemperatureLight.inosketch; - 从Tools > Board菜单选择你的 ESP32 开发板型号;
- 在Tools > Partition Scheme菜单中选择"Huge APP (3MB No OTA/1MB SPIFFS)"分区方案;
- 在Tools菜单中启用"Erase All Flash Before Sketch Upload"(上传前擦除全部 Flash);
- 用 USB 连接开发板到电脑;
- 点击Upload按钮编译并烧录。
分区方案的选择在 CI 配置中亦有体现:ci.yml 中
fqbn_append: PartitionScheme=huge_app表明该示例在持续集成环境中同样使用 huge_app 分区,以保证 Matter 栈与固件有足够的 Flash 空间。
为什么必须擦除 Flash?
Matter 设备在首次配网时会在 NVS(非易失存储)中写入 fabric(信任域)信息、配网凭据等。若开发板上残留了旧固件或已配网状态,会出现"设备不可发现""配网失败"等诡异问题。启用 Erase All Flash 或用 esptool 全片擦除可确保干净起点(详见后文 Troubleshooting)。
预期运行输出
以115200波特率打开串口监视器。Wi-Fi 连接日志只会在 ESP32 与 ESP32-S2 上出现(因为#if !CONFIG_ENABLE_CHIPOBLE分支仅在未启用 CHIPoBLE 时编译 Wi-Fi 连接代码);其他目标芯片会使用 Matter CHIPoBLE 自动完成 IP 网络配置。典型输出如下:
Connecting to your-wifi-ssid ....... Wi-Fi connected IP address: 192.168.1.100 Matter Node is not commissioned yet. Initiate the device discovery in your Matter environment. Commission it to your Matter hub with the manual pairing code or QR code Manual pairing code: 34970112332 QR code URL: https://project-chip.github.io/connectedhomeip/qrcode.html?data=MT%3A6FCJ142C00KA0648G00 Matter Node not commissioned yet. Waiting for commissioning. Matter Node not commissioned yet. Waiting for commissioning. ... Initial state: ON | brightness: 15 | Color Temperature: 454 mireds Matter Node is commissioned and connected to the network. Ready for use. Light OnOff changed to ON Light Brightness changed to 128 Light Color Temperature changed to 370这些输出直接来自 MatterTemperatureLight.ino 的loop():在设备尚未配网时,循环打印手动配对码(Matter.getManualPairingCode())与二维码 URL(Matter.getOnboardingQRCodeUrl()),每 5 秒(50 × 100ms)提示一次等待配网;配网完成后打印初始状态并通过CW_WW_Light.updateAccessory()按初始状态点亮灯具。后三行Light OnOff/Brightness/Color Temperature changed to ...则来自三个 lambda 回调的Serial.printf。
设备使用方法
手动控制
用户按键(默认 BOOT 按键)提供两种控制:
- 短按:切换灯的开/关(内部调用
CW_WW_Light.toggle(),Matter 控制器同样能看到该状态变化); - 长按(>5 秒):恢复出厂设置(decommission),将设备从 Matter 网络中移除,之后需重新配网。
对应源码(MatterTemperatureLight.ino)实现了按键消抖(debouceTime = 250ms)与长按判定(decommissioningTimeout = 5000ms):按键释放且超过消抖时间则切换灯光;若按住超过 5 秒,则先关灯(CW_WW_Light = false),再调用Matter.decommission()完成移除。
色温控制
设备支持从暖白到冷白的色温调节,色温单位为 mireds(微倒度,即 1,000,000 / 开尔文色温):
- 暖白:较高的 mired 值(400–500 mireds),光线更黄更暖;
- 冷白:较低的 mired 值(100–200 mireds),光线更蓝更冷;
- 默认值:454 mireds(暖白)。
色温值保存在Preferences中,断电重启后自动恢复。
从端点实现看,色温合法区间由 MatterColorTemperatureLight.h 中的常量约束:
MIN_COLOR_TEMPERATURE = 100、MAX_COLOR_TEMPERATURE = 500。而WARM_WHITE_COLOR_TEMPERATURE = {454}定义于 ColorFormat.c。
亮度控制
Arduino API 中亮度范围为 0–255:
- 0:在 sketch 中视为关闭/最小亮度;
- 1–254:Matter CurrentLevel 有效区间(254 即满亮度);
- 255:不是合法的 Matter CurrentLevel 值(它是 nullable null 哨兵值),因此示例将其钳位到 254;
- 默认值:15(约 6% 亮度)。
亮度同样保存在Preferences中并在重启后恢复。
智能家居生态集成
使用 Matter 兼容的智能家居中枢(如 Home Assistant 服务器、Apple HomePod、Google Nest Hub 或 Amazon Echo)即可配网该设备。
Home Assistant
- 打开 Home Assistant;
- 进入 Settings > Devices & services > Add integration > Matter;
- 扫描串口监视器中的二维码,或输入手动配对码;
- 按提示完成设置。
Apple Home
- 打开 iOS 设备上的"家庭"App;
- 点"+" > 添加配件;
- 扫描串口监视器显示的二维码,或
- 点"我没有或无法扫描代码"并输入手动配对码;
- 按提示完成设置;
- 设备将以色温灯形式出现在家庭 App 中;
- 可在家庭 App 中调节色温(暖/冷)与亮度。
Amazon Alexa
- 打开 Alexa App;
- 点 More > Add Device > Matter;
- 选择"扫描二维码"或"手动输入代码";
- 完成设置流程;
- 灯具会出现在 Alexa App 中;
- 可通过语音命令或 App 控制色温与亮度。
Google Home
- 打开 Google Home App;
- 点"+" > 设置设备 > 新设备;
- 选择"Matter 设备";
- 扫描二维码或输入手动配对码;
- 按提示完成设置;
- 可在 Google Home App 中调节色温与亮度。
代码结构与底层实现解析
顶层结构
示例由三大部分构成:
1.setup():初始化硬件(按键、LED),按需配置 Wi-Fi,初始化 Matter 色温灯端点,从Preferences恢复上次状态(开/关、亮度、色温),注册状态变化回调,最后调用Matter.begin()启动 Matter 栈;若设备已配网(Matter.isDeviceCommissioned()),则打印初始状态并调用updateAccessory()点亮灯具。
2.loop():检查 Matter 配网状态,处理按键输入(切换灯光 / 恢复出厂),并为 Matter 栈处理事件留出执行时间。
3. 回调(Callbacks):
setLightState():控制物理 LED。对 RGB LED,将色温(mireds)转为 RGB 颜色并应用亮度;对普通 LED 使用 PWM 亮度控制;onChangeOnOff():处理开/关状态变化并打印日志;onChangeBrightness():处理亮度变化并打印日志;onChangeColorTemperature():处理色温变化并打印日志。
端点类MatterColorTemperatureLight
色温灯端点在库中由 MatterColorTemperatureLight 类封装,继承自MatterEndPoint。其公开 API 包括:
| API | 说明 |
|---|---|
begin(initialState, brightness, colorTemperature) | 初始化端点,默认参数为关、亮度 64(25%)、色温 370 mireds(Soft White) |
setOnOff(bool)/getOnOff()/toggle() | 开/关控制 |
setBrightness(uint8_t)/getBrightness() | 亮度控制(0–255) |
setColorTemperature(uint16_t)/getColorTemperature() | 色温控制(mireds) |
onChangeOnOff / onChangeBrightness / onChangeColorTemperature | 三个独立属性回调 |
onChange(cb) | 总回调:cb(bool state, uint8_t brightness, uint16_t temp) |
updateAccessory() | 依据 Matter 内部状态刷新物理灯 |
operator bool()/operator=(bool) | 便于if (CW_WW_Light)与CW_WW_Light = false的语法糖 |
在 MatterColorTemperatureLight.cpp 的begin()中可以看到底层实现:它通过esp_matter的color_temperature_light::create()创建端点,配置OnOff、LevelControl(亮度)与ColorControl(色温,color_mode设为kColorTemperature)三个集群;此外还针对CurrentLevel与ColorTemperatureMireds两个高频变化属性调用attribute::set_deferred_persistence()启用延迟持久化,减少 NVS 写磨损——这是灯具这类频繁调亮度/色温场景的底层优化。
attributeChangeCB()(MatterColorTemperatureLight.cpp)是 Matter 内部事件处理器回调:当控制器改变 OnOff、CurrentLevel 或 ColorTemperatureMireds 任一属性时,先调用对应属性回调,再调用总回调_onChangeCB,只有所有回调都返回true才把新值写入内部状态(onOffState/brightnessLevel/colorTemperatureLevel)。
物理灯控制:色温转 RGB 与 PWM
setLightState()是示例的核心物理控制逻辑(MatterTemperatureLight.ino):
- 开灯且为 RGB LED 时:调用
espCTToRgbColor(temperature_Mireds)将 mired 色温换算为 RGB 颜色,再按brightness / MatterColorTemperatureLight::MAX_BRIGHTNESS比例做亮度校正,最后用rgbLedWrite(ledPin, r, g, b)输出; - 开灯且为普通 LED 时:直接
analogWrite(ledPin, brightness)以 PWM 控制亮度(因此 LED 引脚必须支持 PWM 输出); - 关灯时:先把 GPIO 设回数字输出模式(
pinMode(ledPin, OUTPUT)),再digitalWrite(ledPin, LOW); - 无论开关,都会把最新状态写入
Preferences。
espCTToRgbColor()与espCtColor_t类型定义于 ColorFormat.h / ColorFormat.c(色温转 RGB 的具体换算实现见 ColorFormat.c),rgbLedWrite()则来自 esp32-hal-rgb-led.h,默认按 WS2812B 的 GRB 色彩顺序输出(RGB_BUILTIN_LED_COLOR_ORDER)。
状态持久化
状态持久化基于Preferences库,使用命名空间MatterPrefs,三个键分别为OnOff、Brightness、Temperature(MatterTemperatureLight.ino),存储与恢复的默认值:
- 开/关状态:默认 ON(
getBool(onOffPrefKey, true)); - 亮度:默认 15(
getUChar(brightnessPrefKey, 15),约 6%); - 色温:默认 454 mireds 暖白(
getUShort(temperaturePrefKey, WARM_WHITE_COLOR_TEMPERATURE.ctMireds))。
写入使用putUChar/putBool/putUShort,在setLightState()每次状态变化时同步写入,确保断电后重启可恢复。
Matter 配网状态机
从loop()与setup()的组合可以看出完整的配网生命周期:
- 未配网 → 循环打印配对码与二维码 URL,等待配网;
- 配网中(CHIPoBLE 或手动 Wi-Fi)→ Matter 栈自动完成网络配置;
- 配网完成 →
Matter.isDeviceCommissioned()返回 true,打印Ready for use; - 已配网重启 →
setup()直接进入就绪状态,并恢复灯具状态; - 长按按键 →
Matter.decommission()移除 fabric,回到未配网状态。
常见问题排查
- 配网时设备不可见:确认 Wi-Fi 或 Thread 连接已正确配置(对照芯片差异表,ESP32/ESP32-S2 必须在代码中写 Wi-Fi 凭据);
- RGB LED 无反应:核对引脚配置与接线。RGB LED 场景确保开发板定义了
RGB_BUILTIN,或手动设置引脚; - LED 色温显示不正确:RGB LED 的换算依赖
espCTToRgbColor()函数;普通 LED 只通过 PWM 控制亮度,不表现色温; - 色温不变化:确认色温在合法区间(100–500 mireds),并观察串口监视器中的回调日志;
- 亮度无响应:确认 LED 引脚支持 PWM 输出,并查看串口监视器中的亮度变化消息;
- 状态不持久化:确认
Preferences库工作正常,且 Flash 空间未满; - 配网失败:尝试长按按键恢复出厂设置;或在 Arduino IDE 的 Tools > Erase All Flash Before Sketch Upload 中启用全片擦除,或直接使用命令
esptool.py --port <PORT> erase_flash; - 无串口输出:检查波特率(115200)与 USB 连接。
小结
MatterTemperatureLight是理解 Arduino Matter 开发范式的极佳入口:它覆盖了从端点建模(MatterColorTemperatureLight)、配网流程(BLE/Wi-Fi/Thread 差异)、属性回调(OnOff/Brightness/ColorTemperature)到本地状态持久化的完整链路。在此基础上,你可以参考仓库中 libraries/Matter/src/MatterEndpoints 目录下的其他端点类(如MatterOnOffLight、MatterDimmableLight、MatterColorLight、MatterEnhancedColorLight、MatterThermostat等),将同一套模式推广到更多 Matter 配件类型的开发中。若需深入了解 Matter 协议本身、端点基类与色温灯端点的更多细节,可查阅仓库 docs/en/matter 目录下的官方文档(如 matter.html、matter_ep.html、ep_color_temperature_light.html)。
【免费下载链接】arduino-esp32Arduino core for the ESP32 family of SoCs项目地址: https://gitcode.com/GitHub_Trending/ar/arduino-esp32
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考