15 分钟搞定:ESP32-C6 打造低功耗 Zigbee 光照传感器
【免费下载链接】arduino-esp32Arduino core for the ESP32 family of SoCs项目地址: https://gitcode.com/GitHub_Trending/ar/arduino-esp32
用 arduino-esp32 仓库里的现成示例,你只需要一块 ESP32-C6 或 H2 开发板加一个光敏电阻,就能做出一个标准 ESP32 Zigbee 光照传感器。它是 Arduino Zigbee 终端设备,入网后自动向协调器上报 lux 值,平台里直接看到光照曲线。
成果速览
成品行为是这样的:传感器加入 Zigbee 网络后,每秒读一次光照,lux 值变化超过阈值就上报一次,串口里滚动打印原始值与换算结果,平台侧自动识别为 illuminance 实体。接线只有四根线,光敏电阻和 10kΩ 下拉电阻构成分压:
[ESP32-C6] [光敏电阻模块] 3V3 ------------ VCC GND ------------ GND GPIO6 ---------- OUT GND ------------ 下拉电阻另一端GPIO6 是模拟输入引脚,代码里可以改。
备料:硬件清单与 IDE 配置
硬件清单如下:
| 类别 | 规格 | 说明 |
|---|---|---|
| 主控 | ESP32-C6 / ESP32-H2 开发板 | 二者都支持 Zigbee 3.0 |
| 传感器 | GL5528 光敏电阻 | 模拟输出型 |
| 电阻 | 10kΩ 下拉电阻 | 与光敏电阻构成分压 |
| 电源 | MicroUSB 5V 数据线 | 烧录与调试共用 |
软件侧在 Arduino IDE 里完成两件事。第一,安装开发板包:文件 > 首选项添加 esp32 包索引网址,然后工具 > 开发板 > 开发板管理器搜索esp32安装:
第二,四个关键选项一次设好:
| 菜单项 | 选择值 | 作用 |
|---|---|---|
| 开发板 | ESP32C6 Dev Module(或 ESP32H2 Dev Module) | 选中板子 |
| Zigbee 模式 | Zigbee ED (end device) | 终端设备模式,编译期校验 |
| 分区方案 | Zigbee 4MB with spiffs | Zigbee 专用分区 |
| USB CDC On Boot | Enabled | 串口监视器可用 |
Zigbee 库在仓库的 libraries/Zigbee/ 目录里,跟随开发板包一起就位,装好后检查 Zigbee.h 是否存在即可。
固件三处关键代码走查
示例代码在 Zigbee_Illuminance_Sensor.ino,打开它重点看三处。
1)端点注册与启动(第 38、40、79-107 行)
端点(Endpoint)是 Zigbee 设备里的"房间号",协调器靠它找你要数据。下面代码做了四件事:把 GPIO6 定义为传感器引脚,创建端点对象,注册进 Zigbee 核心,启动并等入网。哪里可以改:端点号、厂商名、量程上下限。
// Zigbee_Illuminance_Sensor.ino 第38、40、79-107行(节选) uint8_t illuminance_sensor_pin = 6; ZigbeeIlluminanceSensor zbIlluminanceSensor = ZigbeeIlluminanceSensor(ZIGBEE_ILLUMINANCE_SENSOR_ENDPOINT); // 端点号 9 // setup() 内: zbIlluminanceSensor.setManufacturerAndModel("Espressif", "ZigbeeIlluminanceSensor"); zbIlluminanceSensor.setMinMaxValue(0, 50000); Zigbee.addEndpoint(&zbIlluminanceSensor); if (!Zigbee.begin()) { ESP.restart(); } while (!Zigbee.connected()) { delay(100); }2)ADC 采集与 ADC 值换算成 lux 公式(第 46-61 行)
12 位 ADC 读出 0-4095 的原始值。先线性映射到 Zigbee 量程 0-50000,再套 ZCL(Zigbee Cluster Library,Zigbee 的标准化"数据字典")公式:lux = pow(10, raw / 10000.0) - 1。这个对数换算好比把米制刻度换算成摄氏度,输入是协议值,输出才是人能读的 lux。哪里可以改:map() 的两个区间,就是你的校准旋钮。
// Zigbee_Illuminance_Sensor.ino 第46-61行(节选) int lsens_analog_raw = analogRead(illuminance_sensor_pin); // 0-4095 int lsens_illuminance_raw = map(lsens_analog_raw, 0, 4095, 0, 50000); int lsens_illuminance_lux = round(pow(10, (lsens_illuminance_raw / 10000.0)) - 1); // lux zbIlluminanceSensor.setIlluminance(lsens_illuminance_raw); // 上报原始值3)上报策略(第 113-119 行)
setReporting()的三个参数是:最小间隔 1 秒、最大间隔 0 秒(禁用定时上报)、变化量阈值 1000。含义是"值变化超过 1000 才上报,且最多每秒一次",这是低功耗 Zigbee 节点省流量的关键。注意配网时协调器可能用它的默认值覆盖这个策略。
// Zigbee_Illuminance_Sensor.ino 第119行 zbIlluminanceSensor.setReporting(1, 0, 1000);Zigbee 入网与联调 3 步
协调器是 Zigbee 网络的管理者,负责开门收人。你可以用另一块 C6/H2 刷 Zigbee_Coordinator 示例自制,或直接用商业网关。
- 确认协调器网络开放。协调器重启或烧录后默认关闭入网,需要在它的固件里保持开放状态,传感器才能进得去。
- 传感器首次上电,自动进入配网流程,不用按任何键。
- 看串口输出,出现入网成功日志与 Short Address 即完成:
[Illuminance Sensor] raw analog value: 2048 [Illuminance Sensor] lux value: 99 lux [Zigbee] Network joined successfully! [Zigbee] Short Address: 0x5A3B入网失败怎么办?长按 BOOT 键 3 秒,固件会执行工厂重置(Factory Reset,把设备里存的"家门钥匙"删掉,让它重新认网)并重启。还不行就在 IDE 里把Erase All Flash Before Sketch Upload设为 Enabled,整个闪存清空后重烧。
进阶与收口
- 深度睡眠:想更省电,参考 Zigbee_Temp_Hum_Sensor_Sleepy 的睡眠唤醒写法,让节点大部分时间睡大觉。
- 接入 Home Assistant:装好 Zigbee2MQTT 并连上协调器,设备入网后自动识别为 illuminance_sensor,仪表板直接显示。注意一个细节:示例代码按 ZCL 公式减 1 换算 lux,Zigbee2MQTT 用的是不减 1 的版本,读数会有微小差异,属正常现象。
- OTA 升级:固件跑起来之后,用仓库里的 tools/espota.py 工具无线刷固件,不用再插 USB。
FAQ
- lux 读数不准怎么办?按传感器实际响应调整
map()的参数区间,这就是校准。 - 串口完全没输出?检查 USB CDC On Boot 是否为 Enabled,换一根带数据线的 USB 线。
- 持续入网失败?长按 BOOT 3 秒工厂重置,配合"上传前擦除全部闪存"重烧一次。
资源清单
- 完整示例代码:Zigbee_Illuminance_Sensor.ino
- 芯片数据手册:ESP32-C6 Datasheet(Espressif 官网)
- API 文档:docs/en/zigbee/
【免费下载链接】arduino-esp32Arduino core for the ESP32 family of SoCs项目地址: https://gitcode.com/GitHub_Trending/ar/arduino-esp32
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考