ESP32 Arduino Matter 占用传感器端点(MatterOccupancySensor)开发实战指南
【免费下载链接】arduino-esp32Arduino core for the ESP32 family of SoCs项目地址: https://gitcode.com/GitHub_Trending/ar/arduino-esp32
本文以 Arduino-ESP32 核心库中的MatterOccupancySensor类为对象,系统讲解如何在 ESP32 系列芯片上基于 Matter 协议实现标准占用传感器(Occupancy Sensor)端点,涵盖 API 用法、HoldTime 保持时间配置、传感器类型选择、真实 PIR 传感器接入以及 HomeKit / Alexa / Google Home 的联调方法。读完本文,你将能独立编写并配网一个符合 Matter 标准的占用检测设备,并掌握其底层实现原理。
一、MatterOccupancySensor 概述
MatterOccupancySensor是 Arduino-ESP32 Matter 库提供的一个占用传感器端点类(见 MatterOccupancySensor.h),其作用是在 Matter 网络中提供一个符合 Matter 占用感知标准的端点,用于检测并上报"有人占用(occupied)"与"无人占用(unoccupied)"两种状态,典型应用包括 PIR 人体红外传感器、门磁接触式检测等。
该类的核心特性:
- 占用状态上报:支持 occupied / unoccupied 双状态实时上报;
- 多种传感器类型:PIR(被动红外)、超声波(Ultrasonic)、PIR+超声波组合、物理接触(Physical Contact);
- HoldTime 属性:配置传感器在检测到占用后保持"occupied"状态的时长;
- HoldTimeLimits:提供最小值、最大值、默认值三段式校验与控制器参考元数据;
- HoldTime 变更回调:Matter 控制器修改 HoldTime 时实时通知应用;
- 简单布尔状态:支持
bool运算符直接读写; - 只读传感器:无任何控制功能,仅上报状态;
- 状态自动更新:应用侧改状态后自动同步到 Matter 属性;
- 生态集成:可接入 Apple HomeKit、Amazon Alexa、Google Home;
- Matter 标准合规:实现基于 Matter Occupancy Sensing Cluster。
典型应用场景包括:人体移动检测(PIR)、占用检测、安防系统、智能照明自动化(有人开灯、无人关灯)、能耗管理(无人时自动关闭灯光/空调)。
从源码结构看,MatterOccupancySensor继承自MatterEndPoint基类,并在内部封装了 esp-matter 的occupancy_sensor::create()端点创建逻辑与 Occupancy Sensing Cluster 的属性和特性(feature flags)配置。
二、API 参考
2.1 构造函数
MatterOccupancySensor();创建一个新的 Matter 占用传感器端点对象。该构造函数本身不创建 Matter 端点,真正的端点创建发生在begin()中。对象通常在全局作用域声明,例如:
MatterOccupancySensor OccupancySensor;2.2 初始化
begin
bool begin(bool _occupancyState = false, OccupancySensorType_t _occupancySensorType = OCCUPANCY_SENSOR_TYPE_PIR);初始化占用传感器端点,参数说明:
_occupancyState:初始占用状态(true= 有人占用,false= 无人占用,默认false);_occupancySensorType:传感器类型(默认OCCUPANCY_SENSOR_TYPE_PIR)。
返回true表示初始化成功,false表示失败。
从 MatterOccupancySensor.cpp 的实现可以看到,begin()内部会:
- 调用
ArduinoMatter::_init()完成 Matter 运行时初始化; - 通过
occupancy_sensor::create()创建端点,并把当前对象指针作为私有数据传入; - 根据传感器类型设置对应的 feature flags(
passive_infrared、ultrasonic、physical_contact或other); - 注册自定义的
OccupancySensingAttrAccessWrapper属性访问接口,用于支持 HoldTime / HoldTimeLimits 属性(这两个属性属于 Matter 1.4+ 新增,由 CHIP server 内部管理,不会随occupancy_sensor::create()自动添加); - 通过
create_hold_time()/create_hold_time_limits()为 Occupancy Sensing 集群补充创建这两个属性。
end
void end();停止处理 Matter 占用传感器事件。实现中将started标志置为false,此后setOccupancy()、setHoldTime()等操作会因未启动而返回false。析构函数会自动调用end()。
2.3 传感器类型枚举
OccupancySensorType_t定义于 MatterOccupancySensor.h:
| 枚举值 | 含义 | 对应 feature flag |
|---|---|---|
OCCUPANCY_SENSOR_TYPE_PIR | 被动红外(PIR)传感器 | passive_infrared |
OCCUPANCY_SENSOR_TYPE_ULTRASONIC | 超声波传感器 | ultrasonic |
OCCUPANCY_SENSOR_TYPE_PIR_AND_ULTRASONIC | PIR 与超声波组合 | passive_infrared \| ultrasonic |
OCCUPANCY_SENSOR_TYPE_PHYSICAL_CONTACT | 物理接触传感器 | physical_contact |
这些枚举值直接映射到 Matter 的OccupancySensorTypeEnum标准枚举。组合类型在内部还会通过occupancySensorTypeBitmap映射表设置occupancy_sensor_type_bitmap属性(PIR=0x01、Ultrasonic=0x02、PhysicalContact=0x04 的位图组合)。
2.4 占用状态控制
bool setOccupancy(bool _occupancyState); bool getOccupancy();setOccupancy():设置占用状态(true= occupied,false= unoccupied),成功返回true。从实现看,若状态无变化会直接返回true跳过处理;有变化时通过updateAttributeVal()更新 Occupancy 属性并同步内部成员,这样 Matter 控制器才能收到状态变更通知;getOccupancy():返回当前占用状态,true表示有人,false表示无人。
2.5 HoldTime 控制
bool setHoldTime(uint16_t _holdTime_seconds); uint16_t getHoldTime();setHoldTime():设置 HoldTime 值(单位:秒)。HoldTime 决定传感器在最后一次检测后维持"occupied"状态的时长。重要:该函数必须在Matter.begin()之后调用,因为它依赖 Matter 事件循环(实现中通过chip::DeviceLayer::SystemLayer().ScheduleLambda()将属性更新调度到 Matter 事件循环上下文执行,以避免栈锁错误)。若holdTimeMax_seconds大于 0(即已设置限制),新值必须落在 min/max 范围内,否则返回false;getHoldTime():返回当前 HoldTime 值(秒)。
bool setHoldTimeLimits(uint16_t _holdTimeMin_seconds, uint16_t _holdTimeMax_seconds, uint16_t _holdTimeDefault_seconds);设置 HoldTime 限制(最小值、最大值、默认值),为控制器提供有效范围校验与参考指导。参数说明:
_holdTimeMin_seconds:HoldTime 最小值(秒);_holdTimeMax_seconds:HoldTime 最大值(秒);_holdTimeDefault_seconds:HoldTime 默认/推荐值(秒),作为控制器的参考元数据。
注意事项:
- 必须在
Matter.begin()之后调用(依赖 Matter 事件循环); holdTimeDefault_seconds仅是提供给 Matter 控制器的信息性元数据(推荐默认值),不会自动设置 HoldTime 属性本身——要真正设置值必须调用setHoldTime();- 若当前 HoldTime 值超出新设置的范围,会自动被调整到最近的边界(最小值或最大值)。这一逻辑在源码中体现为:先比较
holdTime_seconds与新的 min/max,超出时构造adjustedHoldTime并通过SetHoldTimeLimitsAndHoldTimeInEventLoop()一次性在事件循环中同时更新限制与 HoldTime; - 实现中还会做参数自检:
min > max或default不在[min, max]区间内都会返回false。
2.6 onHoldTimeChange 回调
using HoldTimeChangeCB = std::function<bool(uint16_t holdTime_seconds)>; void onHoldTimeChange(HoldTimeChangeCB onHoldTimeChangeCB);注册一个回调函数,当 Matter 控制器修改 HoldTime 值时被调用。回调接收新的 HoldTime 值,返回true表示接受变更,返回false表示拒绝。
示例:
OccupancySensor.onHoldTimeChange([](uint16_t holdTime_seconds) -> bool { Serial.printf("HoldTime changed to %u seconds\n", holdTime_seconds); return true; // 接受变更 });从 MatterOccupancySensor.cpp 实现看,HoldTime 的写入拦截是通过自定义OccupancySensingAttrAccessWrapper(继承chip::app::AttributeAccessInterface)完成的:它先按 HoldTimeLimits 做标准校验,再调用用户回调,回调返回false时返回ConstraintError拒绝写入,通过后才调用OccupancySensing::SetHoldTime()并同步内部成员变量。这样既保留了官方 server 的校验逻辑,又扩展了用户回调能力。
2.7 运算符重载
operator bool(); void operator=(bool _occupancyState);operator bool():直接返回当前占用状态,可用于条件判断:
if (mySensor) { Serial.println("Room is occupied"); } else { Serial.println("Room is unoccupied"); }operator=:设置占用状态,等价于setOccupancy():
mySensor = true; // 设为 occupied mySensor = false; // 设为 unoccupied三、基础示例:MatterOccupancySensor
完整示例见 MatterOccupancySensor.ino,演示了如何创建一个 Matter 占用传感器设备,并模拟每 2 分钟切换一次占用状态。
3.1 端点声明与全局配置
#include <Arduino.h> #include <Matter.h> #if !CONFIG_ENABLE_CHIPOBLE // 若设备可通过 BLE 配网,则无需 WiFi,可节省 flash 空间 #include <WiFi.h> #endif // Matter 占用传感器端点 MatterOccupancySensor OccupancySensor; #if !CONFIG_ENABLE_CHIPOBLE const char *ssid = "your-ssid"; // 修改为你的 WiFi SSID const char *password = "your-password"; // 修改为你的 WiFi 密码 #endif // 使用板载 BOOT 按键做解除配网(decommission) const uint8_t buttonPin = BOOT_PIN; const uint32_t decommissioningTimeout = 5000; // 长按 5 秒解除配网CONFIG_ENABLE_CHIPOBLE启用时设备通过 BLE 配网(CHIPoBLE),不需要手工连接 WiFi;未启用时(如 ESP32、ESP32-S2 芯片不支持 BLE 配网)则必须显式提供 WiFi 凭据。
3.2 setup() 初始化流程
void setup() { pinMode(buttonPin, INPUT_PULLUP); Serial.begin(115200); #if !CONFIG_ENABLE_CHIPOBLE WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(); #endif // 设置初始占用状态为 false,传感器类型为 PIR(默认) OccupancySensor.begin(); // Matter 初始化必须是最后一步:在所有 EndPoint 初始化完成后调用 Matter.begin(); if (!Matter.isDeviceCommissioned()) { Serial.println("Matter Node is not commissioned yet."); Serial.println("Initiate the device discovery in your Matter environment."); Serial.println("Commission it to your Matter hub with the manual pairing code or QR code"); Serial.printf("Manual pairing code: %s\r\n", Matter.getManualPairingCode().c_str()); Serial.printf("QR code URL: %s\r\n", Matter.getOnboardingQRCodeUrl().c_str()); // 等待 Matter 占用传感器完成配网 uint32_t timeCount = 0; while (!Matter.isDeviceCommissioned()) { delay(100); if ((timeCount++ % 50) == 0) { // 50*100ms = 5 秒 Serial.println("Matter Node not commissioned yet. Waiting for commissioning."); } } Serial.println("Matter Node is commissioned and connected to the network. Ready for use."); } }关键要点:
OccupancySensor.begin()必须在Matter.begin()之前完成端点注册;Matter.begin()是最后一步,用于启动整个 Matter 协议栈;- 配网信息(手动配对码 + 二维码 URL)在配网前通过串口打印,配网期间阻塞等待;
Matter.isDeviceCommissioned()用于判断设备是否已被 Matter 网络(如 HomePod、Nest Hub、Echo)接受。
3.3 模拟传感器与主循环
bool simulatedHWOccupancySensor() { // 模拟占用传感器:每 2 分钟切换一次状态 static bool occupancyState = false; static uint32_t lastTime = millis(); const uint32_t occupancyTimeout = 120000; // 2 分钟 if (millis() - lastTime > occupancyTimeout) { occupancyState = !occupancyState; lastTime = millis(); } return occupancyState; } void loop() { // 按钮消抖与解除配网逻辑(长按 5 秒) if (digitalRead(buttonPin) == LOW && !button_state) { button_time_stamp = millis(); button_state = true; } if (button_state && digitalRead(buttonPin) == HIGH) { button_state = false; } uint32_t time_diff = millis() - button_time_stamp; if (button_state && time_diff > decommissioningTimeout) { Serial.println("Decommissioning Occupancy Sensor Matter Accessory. It shall be commissioned again."); Matter.decommission(); button_time_stamp = millis(); } // 读取模拟传感器并同步到 Matter 属性 OccupancySensor.setOccupancy(simulatedHWOccupancySensor()); delay(50); }loop()中通过setOccupancy()将传感器读数持续同步到 Matter 属性,Matter 协议栈会自动向控制器推送状态变更。按钮逻辑实现"长按 5 秒解除配网"的出厂重置功能。
3.4 编译与烧录要点
- 在 Arduino IDE 中打开 MatterOccupancySensor.ino;
- 选择目标 ESP32 开发板(Tools > Board);
- 分区方案选择"Huge APP (3MB No OTA/1MB SPIFFS)";
- 开启"Erase All Flash Before Sketch Upload";
- 串口监视器波特率115200。
串口预期输出示例(配网信息):
Manual pairing code: 34970112332 QR code URL: MT:6FCJ142C00KA0648G00... Matter Node not commissioned yet. Waiting for commissioning. ... Matter Node is commissioned and connected to the network. Ready for use.配网完成后,占用传感器每 2 分钟自动切换 occupied/unoccupied,Matter 控制器(手机 App / 智能家居中枢)可实时收到状态更新。
四、HoldTime 进阶示例:MatterOccupancyWithHoldTime
完整示例见 MatterOccupancyWithHoldTime.ino,它在前一个示例基础上增加了 HoldTime 完整功能演示,重点覆盖:
- 在
Matter.begin()之后配置 HoldTimeLimits; - 设置并持久化 HoldTime 值(通过 Preferences/NVS 跨重启保持);
- 使用
onHoldTimeChange()回调接收控制器的实时修改; - 在传感器模拟逻辑中实现 HoldTime 过期自动切换为空闲。
4.1 HoldTime 常量与 Preferences 持久化
const uint16_t HOLD_TIME_MIN = 0; // 最小 HoldTime(秒) const uint16_t HOLD_TIME_MAX = 3600; // 最大 HoldTime(秒,1 小时) const uint16_t HOLD_TIME_DEFAULT = 30; // 默认 HoldTime(秒) MatterOccupancySensor OccupancySensor; Preferences matterPref; const char *holdTimePrefKey = "HoldTime";setup() 中先恢复上次保存的 HoldTime:
matterPref.begin("MatterPrefs", false); uint16_t storedHoldTime = matterPref.getUShort(holdTimePrefKey, HOLD_TIME_DEFAULT); // 校验存储值是否在合法范围内 if (storedHoldTime < HOLD_TIME_MIN || storedHoldTime > HOLD_TIME_MAX) { uint16_t invalidValue = storedHoldTime; storedHoldTime = HOLD_TIME_DEFAULT; Serial.printf("Invalid stored HoldTime (%u), using default: %u seconds\n", invalidValue, HOLD_TIME_DEFAULT); } else if (storedHoldTime != HOLD_TIME_DEFAULT) { Serial.printf("Restored HoldTime from Preferences: %u seconds\n", storedHoldTime); }4.2 注册 HoldTime 变更回调并持久化
OccupancySensor.onHoldTimeChange([](uint16_t holdTime_seconds) -> bool { Serial.printf("HoldTime changed to %u seconds by Matter Controller\n", holdTime_seconds); // 将新 HoldTime 写入 Preferences,实现跨重启持久化 matterPref.putUShort(holdTimePrefKey, holdTime_seconds); // 回调返回 false 可拒绝变更,这里始终接受并同步模拟器 return true; });4.3 初始化顺序:先 begin,后设 Limits 与 HoldTime
// 设置初始占用状态为 false,传感器类型为 PIR(默认) OccupancySensor.begin(); // Matter 初始化必须是最后一步 Matter.begin(); // 在 Matter.begin() 之后设置 HoldTimeLimits(可选,但推荐用于校验) if (!OccupancySensor.setHoldTimeLimits(HOLD_TIME_MIN, HOLD_TIME_MAX, HOLD_TIME_DEFAULT)) { Serial.println("Warning: Failed to set HoldTimeLimits"); } else { Serial.printf("HoldTimeLimits set: Min=%u, Max=%u, Default=%u seconds\n", HOLD_TIME_MIN, HOLD_TIME_MAX, HOLD_TIME_DEFAULT); } // 设置初始 HoldTime(优先使用存储值,否则用默认值) if (!OccupancySensor.setHoldTime(storedHoldTime)) { Serial.printf("Warning: Failed to set HoldTime to %u seconds\n", storedHoldTime); } else { Serial.printf("HoldTime set to: %u seconds\n", storedHoldTime); } Serial.printf("Initial HoldTime: %u seconds\n", OccupancySensor.getHoldTime());顺序非常关键:setHoldTimeLimits()与setHoldTime()都依赖Matter.begin()启动的 Matter 事件循环(SystemLayer),必须在Matter.begin()之后调用,否则会因SystemLayer未初始化而失败。
4.4 带 HoldTime 过期的传感器模拟
bool simulatedHWOccupancySensor() { static bool occupancyState = false; static uint32_t lastDetectionTime = 0; static uint32_t lastDetectionEvent = millis(); const uint32_t detectionInterval = 120000; // 每 2 分钟模拟一次检测 // 获取当前 HoldTime(可能已被 Matter 控制器修改),转换为毫秒 uint32_t holdTime_ms = OccupancySensor.getHoldTime() * 1000; // 先检查 HoldTime 是否过期(确保即使同一轮迭代有新检测也能正确过期) if (occupancyState && (millis() - lastDetectionTime > holdTime_ms)) { occupancyState = false; lastDetectionEvent = millis(); Serial.println("HoldTime expired. Switching to unoccupied state."); } // 再模拟周期性检测(放在过期检查之后,使新检测能立即重新触发占用) if (millis() - lastDetectionEvent > detectionInterval) { lastDetectionEvent = millis(); if (!occupancyState) { // 从无人切换到有人:启动保持计时 occupancyState = true; lastDetectionTime = millis(); Serial.printf("Occupancy detected! Holding state for %u seconds (HoldTime)\n", OccupancySensor.getHoldTime()); } else { // 已处于有人状态:新检测重置保持计时(模拟持续有人) lastDetectionTime = millis(); Serial.printf("Occupancy still detected. Resetting hold timer to %u seconds (HoldTime)\n", OccupancySensor.getHoldTime()); } } return occupancyState; }模拟器对 HoldTime 与检测间隔关系的处理逻辑:
holdTime < detectionInterval:状态在 HoldTime 后切回无人,等待下一次检测;holdTime == detectionInterval:检测持续到来时计时器不断重置,表现为持续占用;holdTime > detectionInterval:检测持续到来时计时器重置(持续占用);检测停止后,从最后一次检测起 HoldTime 到期切换为空闲。
主循环与基础示例一致:OccupancySensor.setOccupancy(simulatedHWOccupancySensor());持续同步状态。
五、接入真实 PIR 传感器
两个示例的 README(MatterOccupancySensor/README.md、MatterOccupancyWithHoldTime/README.md)都给出了接入真实 PIR 传感器的完整方案。
5.1 硬件接线
以 HC-SR501、AM312 等常见 PIR 模块为例(典型三引脚:VCC、GND、OUT):
- PIR VCC→ ESP32 3.3V 或 5V(以传感器规格为准);
- PIR GND→ ESP32 GND;
- PIR OUT→ ESP32 任意 GPIO(如 GPIO 4)。
5.2 代码改造
定义引脚并初始化:
const uint8_t pirPin = 4; // 修改为你的 PIR 引脚 // setup() 中: pinMode(pirPin, INPUT);将模拟函数替换为真实读数(含 100ms 消抖,避免误触发):
bool simulatedHWOccupancySensor() { // 带消抖的 PIR 读数:HIGH = 检测到移动(有人),LOW = 无移动(无人) static bool lastState = false; static uint32_t lastChangeTime = 0; const uint32_t debounceTime = 100; // 100ms 消抖 bool currentState = digitalRead(pirPin) == HIGH; if (currentState != lastState) { if (millis() - lastChangeTime > debounceTime) { lastState = currentState; lastChangeTime = millis(); Serial.printf("Occupancy state changed: %s\r\n", currentState ? "OCCUPIED" : "UNOCCUPIED"); } } return lastState; }配合 HoldTime 示例使用时,真实 PIR 的"最后一次检测后保持 HoldTime 时长再切回无人"的行为逻辑完全一致——simulatedHWOccupancySensor()仅提供状态输入,HoldTime 保持/过期逻辑无需改动。
PIR 使用小贴士(来自示例 README 的排障建议):
- 部分 PIR 模块需要 5V 供电;
- 上电后预留 30–60 秒让传感器稳定;
- 可通过灵敏度与延时电位器调节检测范围;
- 对误触发问题优先在软件中加入消抖。
六、智能家居生态集成与配网
设备烧录并启动后,使用 Matter 兼容中枢(如 Apple HomePod、Google Nest Hub、Amazon Echo)即可配网。
Apple Home:打开 Home App → "+" → Add Accessory → 扫描串口输出的二维码,或选择 "I Don't Have a Code or Cannot Scan" 手动输入配对码。配网完成后设备以占用传感器(Occupancy Sensor)形态出现在 Home App 中,可基于占用状态创建自动化(如有人时开灯)。
Amazon Alexa:Alexa App → More → Add Device → Matter → 扫码或手动输码完成设置,随后可查看占用读数并创建 Routine。
Google Home:Google Home App → "+" → Set up device → New device → Matter device → 扫码或输码,之后可查看占用读数并创建自动化。
配网失败时可长按 BOOT 键 5 秒解除配网(Matter.decommission()),或在 Arduino IDE 中开启 "Erase All Flash Before Sketch Upload" 擦除整片 flash 后重试。
支持的目标芯片
| SoC | Wi-Fi | Thread | BLE 配网 | 状态 |
|---|---|---|---|---|
| ESP32 | ✅ | ❌ | ❌ | 完整支持 |
| ESP32-S2 | ✅ | ❌ | ❌ | 完整支持 |
| ESP32-S3 | ✅ | ❌ | ✅ | 完整支持 |
| ESP32-C3 | ✅ | ❌ | ✅ | 完整支持 |
| ESP32-C5 | ❌ | ✅ | ✅ | 支持(仅 Thread) |
| ESP32-C6 | ✅ | ❌ | ✅ | 完整支持 |
| ESP32-H2 | ❌ | ✅ | ✅ | 支持(仅 Thread) |
配网注意事项:
- ESP32 与 ESP32-S2 不支持 BLE 配网,必须在代码中显式提供 WiFi 凭据;
- ESP32-C6 虽支持 Thread,但 Arduino Matter 库预编译版本仅启用 Wi-Fi;若要 Thread 专用模式,需将 Arduino 作为 ESP-IDF 组件构建并禁用 Matter Wi-Fi station 特性;
- ESP32-C5 预编译版本仅启用 Thread;若要 Wi-Fi 模式,需以 ESP-IDF 组件方式构建并仅保留 Wi-Fi station 网络。
七、底层实现原理:HoldTime 是如何工作的
从 MatterOccupancySensor.cpp 可以看出 HoldTime 机制的实现细节:
属性动态创建:HoldTime 与 HoldTimeLimits 是 Matter 1.4+ 引入、由 CHIP server 内部管理(MANAGED_INTERNALLY)的属性,
occupancy_sensor::create()不会自动创建它们。begin()中通过 esp-matter 的create_hold_time()/create_hold_time_limits()在 Occupancy Sensing 集群上补充创建,且 HoldTimeLimits 仅在 HoldTime 创建成功后才创建。自定义属性访问接口:类内定义了
OccupancySensingAttrAccessWrapper,继承chip::app::AttributeAccessInterface并注册到AttributeAccessInterfaceRegistry。读取操作委托给标准OccupancySensing::Instance;写入操作则先解码新值,对照GetHoldTimeLimitsForEndpoint()获取的 HoldTimeLimits 做 ConstraintError 校验,再调用用户回调(回调返回false同样返回ConstraintError),最后调用OccupancySensing::SetHoldTime()并同步内部成员。事件循环调度:
setHoldTime()/setHoldTimeLimits()内部通过SystemLayer().ScheduleLambda()把属性更新调度到 Matter 事件循环线程执行,这是因为MatterReportingAttributeChangeCallback()必须在 Matter 事件循环上下文中调用,否则会出现栈锁错误——这也是文档强调"必须在Matter.begin()之后调用"的根本原因。内部状态一致性:
setHoldTimeLimits()在调度成功后才会提交成员变量(holdTimeMin/Max/Default_seconds),失败时保持不变;若当前 HoldTime 超出新范围,会计算adjustedHoldTime并一次性调度"设限制 + 调 HoldTime",确保属性与内部状态始终一致。
八、常见问题排查
- 设备配网时不可见:确认 Wi-Fi 或 Thread 连接配置正确(参考上文芯片支持表与注意事项);
- 占用读数不更新:确认模拟函数被正确调用;真实传感器场景检查接线与库初始化;
- 状态不变化:模拟传感器每 2 分钟(120000ms)切换一次,耐心等待或缩短
occupancyTimeout便于测试; - HoldTime 不生效:确认
setHoldTimeLimits()与setHoldTime()均在Matter.begin()之后调用,并在串口检查报错信息; - HoldTime 重启后丢失:确认 Preferences 已初始化且回调正确执行
putUShort(),观察串口 "HoldTime changed" 日志; - PIR 检测不到移动:检查 VCC/GND/OUT 接线、供电电压(3.3V/5V)、预留 30–60 秒稳定时间、调节灵敏度电位器、确保检测区域无遮挡,并可先直接在串口打印 GPIO 值验证;
- 配网失败:长按按键解除配网后重试,或开启 "Erase All Flash Before Sketch Upload" 擦除 flash;
- 无串口输出:确认波特率 115200 与 USB 连接。
九、进一步阅读
- Matter 总览文档:matter.rst
- Matter 端点基类说明:matter_ep.rst
- 其他传感器端点文档:温湿度(ep_temperature_sensor.rst)、光照(ep_light_sensor.rst)、接触(ep_contact_sensor.rst)等均可参考同一套 API 风格
- 类声明:MatterOccupancySensor.h
- 类实现:MatterOccupancySensor.cpp
【免费下载链接】arduino-esp32Arduino core for the ESP32 family of SoCs项目地址: https://gitcode.com/GitHub_Trending/ar/arduino-esp32
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考