ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

基于 Arduino ESP32 的 Matter 开关插头(On/Off Plugin)实战:MatterOnOffPlugin 示例深度解析

2026/9/14 9:03:20 拓冰建站 浏览量
基于 Arduino ESP32 的 Matter 开关插头(On/Off Plugin)实战:MatterOnOffPlugin 示例深度解析 基于 Arduino ESP32 的 Matter 开关插头On/Off Plugin实战MatterOnOffPlugin 示例深度解析【免费下载链接】arduino-esp32Arduino core for the ESP32 family of SoCs项目地址: https://gitcode.com/GitHub_Trending/ar/arduino-esp32本文以 libraries/Matter/examples/MatterOnOffPlugin 示例为骨架系统讲解如何在 ESP32 系列 SoC 上使用 Arduino 语言开发一个符合 Matter 协议的电源插头/继电器on/off plugin unit设备涵盖芯片选型、Wi-Fi/Thread 连接差异、BLE 配网commissioning、状态持久化、工厂复位与 Apple HomeKit / Amazon Alexa / Google Home 生态接入。读完本文你将掌握从源码配置、编译烧录到串口调试、智能家居配网的完整链路并理解底层MatterOnOffPlugin端点的实现原理。Matter 与 On/Off Plugin 设备类型Matter 是由连接标准联盟CSA推动的统一智能家居应用层协议让不同厂商的智能设备可以被同一个生态如 Apple Home、Amazon Alexa、Google Home发现、配网和控制。在 Matter 设备模型中On/Off Plugin Unit是一种标准设备类型用于描述电源插座、智能插头、继电器等只有开/关两态的控制类设备。在 ESP32 Arduino Core 的 Matter 库 中MatterOnOffPlugin类封装了该设备类型的完整实现。它向上对 Matter 控制器手机 App、智能音箱、中枢网关暴露标准的 On/Off Cluster向下通过用户注册的回调函数驱动实际的 GPIO继电器或 LED从而把Matter 命令翻译成物理动作。本示例 MatterOnOffPlugin.ino 的核心价值在于演示了四件事创建一个 Matter on/off plugin 端点Endpoint并启动 Matter 协议栈通过 CHIPoBLEMatter over BLE或预置 Wi-Fi 凭据完成配网使用Preferences库把最后一次开关状态写入 NVS 闪存实现断电恢复用板载 BOOT 按钮实现长按 5 秒解除配网decommission/factory reset。支持的 SoC 目标与网络差异示例 README 给出了各芯片的支持情况这是一个重要的选型依据。下表与 README 保持一致SoCWi-FiThreadBLE CommissioningRelay/LED状态ESP32✅❌❌需要Fully supportedESP32-S2✅❌❌需要Fully supportedESP32-S3✅❌✅需要Fully supportedESP32-C3✅❌✅需要Fully supportedESP32-C5❌✅✅需要Supported (Thread only)ESP32-C6✅❌✅需要Fully supportedESP32-H2❌✅✅需要Supported (Thread only)关于配网方式的三个关键注意点ESP32 与 ESP32-S2 不支持 BLE 配网。这两颗芯片无法通过 Matter CHIPoBLE 完成 commissioning必须在代码中直接写入 Wi-Fi 凭据让设备先手动连上你的网络。这也是示例代码中使用预处理宏#if !CONFIG_ENABLE_CHIPOBLE包裹WiFi.h和连接逻辑的原因见 MatterOnOffPlugin.ino当该宏未启用时说明当前芯片不支持 BLE 配网才需要编译进 Wi-Fi 手动连接代码以节省 Flash 空间。ESP32-C6 默认按 Wi-Fi 预编译。虽然 C6 硬件支持 Thread但 ESP32 Arduino Matter 库预编译固件仅启用了 Wi-Fi。要将其配置为 Thread-only 运行需要使用Arduino as an IDF Component方式构建项目并关闭 Matter 的 Wi-Fi station 功能。ESP32-C5 默认按 Thread 预编译。尽管 C5 支持 2.4 GHz 与 5 GHz Wi-Fi但预编译库只启用了 Thread。如需 Wi-Fi 运行同样要改用 ESP-IDF Component 方式构建并关闭 Thread 网络、仅保留 Wi-Fi station。从 Matter.h 的源码可以看到运行时还可以通过Matter.isWiFiStationEnabled()、Matter.isWiFiAccessPointEnabled()、Matter.isThreadEnabled()、Matter.isBLECommissioningEnabled()四个查询接口确认当前固件实际启用了哪些网络能力它们同时检查芯片硬件能力与 Matter 配置适合在开机自检阶段打印出来辅助判断。硬件需求与引脚配置按 README 的要求你需要准备一块上表列出的 ESP32 系列开发板一个功率继电器模块或直接用板载 LED 做可视化测试一个用于工厂复位的用户按键示例默认用 BOOT 按键。示例的引脚定义如下见 MatterOnOffPlugin.ino// 若开发板定义了 LED_BUILTIN测试时直接使用板载 LED否则回退到 GPIO 2 #ifdef LED_BUILTIN const uint8_t onoffPin LED_BUILTIN; #else const uint8_t onoffPin 2; // 生产环境改为继电器控制引脚 #warning Do not forget to set the Power Relay pin #endif // 工厂复位按钮默认使用 BOOT 按键 const uint8_t buttonPin BOOT_PIN;要点onoffPin测试阶段输出到LED_BUILTIN便于观察生产环境请改为继电器模块的控制引脚见下文电源继电器集成。当开发板未定义LED_BUILTIN时编译器会通过#warning提示你记得设置继电器引脚。buttonPin默认BOOT_PIN通常为 GPIO 0带外部上拉、按下为低电平用于长按触发 decommission。软件环境准备Prerequisites安装 Arduino IDE推荐 2.0 或更高版本安装带 Matter 支持的 ESP32 Arduino Core即本仓库确保以下 Arduino 库可用Matter本仓库自带库目录PreferencesArduino 内置用于状态持久化Wi-Fi仅 ESP32 与 ESP32-S2 需要因为这两款不支持 BLE 配网。需要特别说明的是Matter 功能依赖CONFIG_ESP_MATTER_ENABLE_DATA_MODEL编译选项。在 MatterOnOffPlugin.h 中整个类定义被#ifdef CONFIG_ESP_MATTER_ENABLE_DATA_MODEL包裹只有开启该配置后端点类才会被编译进固件。示例的 ci.yml 也印证了这一点CI 验证时通过requires: - CONFIG_ESP_MATTER_ENABLE_DATA_MODELy声明该依赖并追加fqbn_append: PartitionSchemehuge_app。配置项详解上传固件前在 MatterOnOffPlugin.ino 中需要按需修改三处1. Wi-Fi 凭据非 BLE 配网时必填ESP32/ESP32-S2 为硬性要求const char *ssid your-ssid; // 改为你的 Wi-Fi SSID const char *password your-password; // 改为你的 Wi-Fi 密码这段代码同样被#if !CONFIG_ENABLE_CHIPOBLE包裹支持 BLE 配网的芯片如 ESP32-C3/C6/S3不需要它配网时由 Matter 通过 CHIPoBLE 自动把设备加入 IP 网络。2. 继电器控制引脚不用板载 LED 时const uint8_t onoffPin 2; // 设为你的继电器控制引脚3. 按钮引脚可选const uint8_t buttonPin BOOT_PIN; // 可改为其他 GPIO构建与烧录步骤在 Arduino IDE 中打开MatterOnOffPlugin.ino草图从Tools Board菜单选择你的 ESP32 开发板型号从Tools Partition Scheme菜单选择Huge APP (3MB No OTA/1MB SPIFFS)分区方案在Tools菜单中启用Erase All Flash Before Sketch Upload选项通过 USB 连接 ESP32 开发板到电脑点击Upload按钮编译并烧录。为什么必须用 Huge APP 分区方案Matter 协议栈体积较大默认分区无法容纳。示例 CI 配置 ci.yml 中的PartitionSchemehuge_app明确指定了这一约束。该分区方案提供 3 MB APP 空间且不保留 OTA 分区为 Matter 固件腾出足够空间。Erase All Flash则确保清除可能残留的旧配网信息fabric 数据避免配网异常。串口输出解读Expected Output烧录完成后打开串口监视器波特率设为115200。Wi-Fi 连接信息只会在 ESP32/ESP32-S2 上打印因为其他芯片通过 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?dataMT%3A6FCJ142C00KA0648G00 Matter Node not commissioned yet. Waiting for commissioning. Matter Node not commissioned yet. Waiting for commissioning. ... Initial state: OFF Matter Node is commissioned and connected to the network. Ready for use. User Callback :: New Plugin State ON User Callback :: New Plugin State OFF逐行解读Manual pairing code与QR code URL是配网所需的关键信息。它们由 Matter.h 中声明的Matter.getManualPairingCode()和Matter.getOnboardingQRCodeUrl()在Matter.begin()之后生成源码注释说明这两个值由 CommissionableDataProvider 生成在begin()之前调用会返回空字符串并打印警告输出Initial state: OFF说明设备恢复了上一次保存的状态此处为默认 OFF随后调用OnOffPlugin.updateAccessory()让物理继电器/LED 与实际状态对齐User Callback :: New Plugin State ON/OFF则来自示例注册的回调函数setPluginOnOff()每次 Matter 控制器下发开/关命令时触发。代码结构深度解析示例的主程序结构非常清晰我们结合源码逐段分析。setup()初始化与端点创建void setup() { pinMode(buttonPin, INPUT_PULLUP); pinMode(onoffPin, OUTPUT); Serial.begin(115200); #if !CONFIG_ENABLE_CHIPOBLE // 非 BLE 配网芯片手动连接 Wi-Fi WiFi.begin(ssid, password); while (WiFi.status() ! WL_CONNECTED) { delay(500); Serial.print(.); } #endif // 1. 打开 Preferences读取上次开关状态默认 OFF matterPref.begin(MatterPrefs, false); bool lastOnOffState matterPref.getBool(onOffPrefKey, false); // 2. 创建 On/Off Plugin 端点传入初始状态 OnOffPlugin.begin(lastOnOffState); // 3. 注册状态变更回调 OnOffPlugin.onChange(setPluginOnOff); // 4. 启动 Matter 协议栈必须在所有端点 begin 之后 Matter.begin(); // 5. 若设备已被配网过重启场景恢复状态并同步物理输出 if (Matter.isDeviceCommissioned()) { Serial.printf(Initial state: %s\r\n, OnOffPlugin.getOnOff() ? ON : OFF); OnOffPlugin.updateAccessory(); } }关键调用顺序先OnOffPlugin.begin()再Matter.begin()。在 MatterOnOffPlugin.cpp 中begin(initialState)内部会调用ArduinoMatter::_init()然后通过 esp-matter 的on_off_plug_in_unit::create()创建端点把initialState写入 On/Off Cluster 的on_off属性plugin_config.on_off.on_off initialState并把start_up_on_off设为nullptr表示不做启动自恢复恢复逻辑由应用层通过 Preferences 自己实现。每个端点只允许创建一次若getEndPointId() ! 0说明已创建会打印错误并返回false。回调setPluginOnOff()bool setPluginOnOff(bool state) { Serial.printf(User Callback :: New Plugin State %s\r\n, state ? ON : OFF); if (state) { digitalWrite(onoffPin, HIGH); } else { digitalWrite(onoffPin, LOW); } // 保存状态到 Preferences用于重启后恢复 matterPref.putBool(onOffPrefKey, state); return true; // 返回值表示处理是否成功 }这个回调的注册通过OnOffPlugin.onChange(setPluginOnOff)完成。从 MatterOnOffPlugin.h 可以看到回调类型为std::functionbool(bool)且除了onChange()外还提供了语义相同的onChangeOnOff()。底层触发链路在 MatterOnOffPlugin.cpp 的attributeChangeCB()中当 Matter 控制器修改 On/Off Cluster 的OnOff属性时系统回调会校验 endpoint_id 与 cluster/attribute ID然后依次调用_onChangeOnOffCB与_onChangeCB只有两个回调都返回true时才会把onOffState内部状态更新为新值——这保证了物理执行失败如返回 false时Matter 侧的状态不会错误地自认为已切换。loop()配网等待、状态恢复与工厂复位void loop() { // 1. 等待配网完成 if (!Matter.isDeviceCommissioned()) { // 打印配对码/QR 码每 5 秒提示一次 while (!Matter.isDeviceCommissioned()) { delay(100); if ((timeCount % 50) 0) { // 50 * 100ms 5s Serial.println(Matter Node not commissioned yet. Waiting for commissioning.); } } // 配网完成后恢复状态 OnOffPlugin.updateAccessory(); } // 2. 按钮消抖检测按下记录时间戳 if (digitalRead(buttonPin) LOW !button_state) { button_time_stamp millis(); button_state true; } if (button_state digitalRead(buttonPin) HIGH) { button_state false; // 松开 } // 3. 长按 5 秒以上 → 解除配网 uint32_t time_diff millis() - button_time_stamp; if (button_state time_diff decommissioningTimeout) { OnOffPlugin.setOnOff(false); // 先关闭插头 Matter.decommission(); // 清除 fabric 信息 button_time_stamp millis(); // 防重复触发 } }两点值得注意工厂复位流程先调用OnOffPlugin.setOnOff(false)关闭继电器再调用Matter.decommission()。decommission()在 Matter.h 中声明作用是移除已保存的 Matter fabric配网凭据之后设备需要重新配网。示例用decommissioningTimeout 5000毫秒定义长按阈值。示例没有实现按钮短按切换开关的功能——插头完全由 Matter 应用命令控制按钮仅用于工厂复位。如需短按控制可在释放检测分支中加入toggle()调用见下文 API 参考。状态持久化机制示例用Preferences库命名空间MatterPrefs键OnOff保存开关状态开机时matterPref.getBool(onOffPrefKey, false)读取上次状态默认falseOFF状态变化时matterPref.putBool(onOffPrefKey, state)写入最新状态断电/重启后设备恢复到上次保存的状态且通过updateAccessory()让继电器/LED 与实际状态一致同时 Matter 控制器会收到状态同步通知。这是状态持久化章节State Persistence的实现基础设备将恢复到上次的 ON/OFF 状态若无历史记录则默认为 OFF。MatterOnOffPlugin API 参考除示例本身外docs/en/matter/ep_on_off_plugin.rst 提供了该端点的完整 API 文档与 MatterOnOffPlugin.h 声明一一对应API说明返回MatterOnOffPlugin()创建 on/off plugin 端点对象—bool begin(bool initialState false)初始化端点initialStatetrue表示初始为开默认关成功返回truevoid end()停止处理该端点的 Matter 事件—bool setOnOff(bool newState)设置开关状态true开false关成功返回truebool getOnOff()读取当前开关状态true开false关bool toggle()翻转当前状态成功返回truevoid onChange(EndPointCB cb)注册状态变更回调bool cb(bool newState)—void onChangeOnOff(EndPointCB cb)注册 OnOff 状态变更回调与onChange同—void updateAccessory()用当前 Matter 内部状态驱动物理输出触发已注册回调—operator bool()隐式转换返回当前状态可写if (myPlugin)状态值void operator(bool state)赋值运算符myPlugin true;开myPlugin false;关—setOnOff()的实现MatterOnOffPlugin.cpp有两点值得学习其一若目标状态与当前状态相同则直接返回true避免无意义写入其二状态写入通过updateAttributeVal(OnOff::Id, OnOff::Attributes::OnOff::Id, ...)走 Matter 属性更新通道成功后同步更新内部onOffState。toggle()则实现为setOnOff(!onOffState)。begin()与Matter.begin()的分工是前者创建并注册端点后者启动整个 Matter 协议栈。从 Matter.h 与示例代码可见Matter.begin()必须放在所有端点begin()之后执行。若设备重启时已被配网Matter.isDeviceCommissioned()为真则跳过配网等待直接打印Matter Node is commissioned and connected to the network. Ready for use.。使用设备手动控制、继电器集成与智能家居接入手动控制与工厂复位长按按钮超过 5 秒触发工厂复位decommission设备需重新配网示例不提供短按切换功能开关完全由 Matter 应用命令控制。电源继电器集成生产环境接入继电器模块接线Relay VCC → ESP32 3.3 V 或 5 V以继电器模块规格为准Relay GND → ESP32 GNDRelay IN → ESP32 GPIO即代码中的onoffPin。修改引脚配置把onoffPin改为实际继电器控制引脚验证通过 Matter App 下发开关命令观察继电器是否跟随动作。智能家居生态配网使用 Matter 兼容中枢如 Apple HomePod、Google Nest Hub、Amazon Echo进行配网。Apple Home打开 iOS 上的家庭App点 添加配件扫描串口打印的 QR 码或点我没有代码或无法扫描并输入手动配对码按提示完成设置设备会以开关/插座形式出现在家庭 App 中。Amazon Alexa打开 Alexa App依次进入更多 添加设备 Matter选择扫描二维码或手动输入代码完成后插件出现在 Alexa 设备列表中可用语音控制例如 Alexa, turn on the plugin / Alexa, turn off the plugin。Google Home打开 Google Home App点 设置设备 新设备选择Matter 设备扫描 QR 码或输入手动配对码完成后可通过语音或 App 控制。故障排查Troubleshooting按 README 的排障清单整理如下配网时设备不可见确认 Wi-Fi 或 Thread 连接配置正确。对 ESP32/ESP32-S2 检查 SSID/密码与路由器对 C5 确认 Thread 边界路由器环境。继电器/LED 不响应检查onoffPin配置与接线。继电器模块需确保供电充足、接线正确。状态不持久化确认Preferences库已正确初始化matterPref.begin(MatterPrefs, false)且 Flash 未被损坏。继电器无法切换核对控制信号电平与继电器模块要求是否匹配——部分继电器需要 5 V 驱动部分 3.3 V 即可。配网失败先尝试长按按钮工厂复位或者通过 Arduino IDE 的Tools Erase All Flash Before Sketch Upload: Enabled擦除 Flash也可以直接用命令esptool.py --port PORT erase_flash擦除。无串口输出检查波特率是否为 115200以及 USB 连接是否正常。延伸阅读仓库内与本文主题直接相关的资源Matter 总览文档Matter 协议与库的整体介绍Matter 端点基类文档MatterEndPoint基类与通用端点能力MatterOnOffPlugin 端点 API 文档本示例所用端点的完整 API 参考MatterOnOffPlugin 端点实现端点类的底层实现esp-matter 数据模型Matter 库根目录包含 20 余种端点类型与大量示例可在此基础上扩展为调光灯、温湿度传感器、恒温器等其他 Matter 设备。许可证本示例基于 Apache License 2.0 许可发布见 MatterOnOffPlugin.ino 文件头版权声明。【免费下载链接】arduino-esp32Arduino core for the ESP32 family of SoCs项目地址: https://gitcode.com/GitHub_Trending/ar/arduino-esp32创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考