基于 CC2530 ZigBee、STM32F103 与 Qt 的多节点智能家居环境监测与灯光控制系统。
CC2530 · ZigBee · STM32F103 · FreeRTOS · Qt 5 · QtCharts · UART · PWM
本项目在毕业设计阶段已完成实物系统联调与演示。当前仓库保留了各节点工程与上位机源码,但存在控制帧长度不一致、光照上报处于调试输出状态等问题,尚未对当前版本完成全链路复现验证,详见第 8 章。
系统面向室内环境监测与灯光控制场景:传感器终端采集温湿度与烟雾数据,经 ZigBee 协调器转发至 Qt 上位机;STM32 控制节点采集光照并驱动三路 PWM,通过独立的 CC2530 灯控终端接入无线网络。
Qt 负责环境数据显示、温度曲线及控制命令生成,STM32 负责灯光执行与自动调光,CC2530 负责无线通信和串口桥接。
- 多节点系统集成:一个 CC2530 协调器连接传感器终端和灯控通信终端。
- FreeRTOS 任务化控制:STM32 将串口解析、光照采集与灯光控制拆分为独立任务。
- ZigBee + UART 通信链路:连接嵌入式采集节点、控制节点和 Qt 上位机。
- 自定义二进制协议:通过命令字、长度字段和累加校验组织数据与控制参数。
- Qt 数据可视化:串口缓存解析、环境数值显示、环境报警状态显示及实时温度曲线。
- 多传感器与灯光策略:DHT11、MQ-2、BH1750 采集,支持手动灯控、自动调光和报警联动逻辑。
- 实物项目经历:毕业设计阶段完成多节点软硬件联调与演示。
graph LR
Qt[Orange Pi Zero2 / Qt] <-->|UART| Coordinator[CC2530 协调器]
Coordinator <-->|ZigBee| Sensor[CC2530 传感器终端]
Coordinator <-->|ZigBee| Control[CC2530 灯控通信终端]
Sensor --- DHT11[DHT11 温湿度]
Sensor --- MQ2[MQ-2 烟雾]
Control <-->|UART| STM32[STM32F103 / FreeRTOS]
STM32 --- BH1750[BH1750 光照]
STM32 -->|三路 PWM| LED[RGB LED]
图中表示系统设计链路;当前源码的控制转发和光照上报限制见第 8.5 节。
DHT11 / MQ-2 → CC2530 传感器终端 → ZigBee → 协调器 → UART → Qt
传感器终端以约 1 秒周期加随机抖动采集并发送温度、湿度、烟雾数字量、烟雾模拟量及报警位。Qt 更新数值、报警提示与温度曲线。
BH1750 → STM32 → UART → CC2530 灯控终端 → ZigBee → 协调器 → UART → Qt
源码保留了 9 字节光照二进制发帧函数,但当前采集任务仅输出光照调试文本,尚未启用这条完整上报链路。
Qt → UART → 协调器 → ZigBee → CC2530 灯控终端 → UART → STM32 → PWM LED
Qt 生成开关灯、自动模式和报警联动命令;STM32 通过串口接收并执行。当前中间 CC2530 节点仍采用不同的控制帧长度,需要统一后验证端到端控制。
| 节点 / 平台 | 硬件组成 | 软件职责 |
|---|---|---|
| Orange Pi Zero2 / Qt | Orange Pi Zero2、串口连接 | 串口收发、协议解析、环境数据显示、温度曲线和命令下发 |
| CC2530 Coordinator | CC2530 协调器 | ZigBee 组网、接收无线数据并转发至串口、转发下行控制数据 |
| CC2530 Sensor Node | CC2530、DHT11、MQ-2 | 传感器采集、报警位生成、环境数据打包与周期上传 |
| CC2530 Control Node | CC2530 灯控通信终端 | 在 ZigBee 与 STM32 UART 之间转发数据 |
| STM32F103 控制节点 | STM32F103、BH1750、RGB LED | FreeRTOS 任务调度、光照采集、命令执行、三路 PWM 控制 |
STM32 使用软件 I²C 访问 BH1750;当前引脚宏定义为 PB6 / PB7。USART1 使用 PA9 / PA10,TIM2 三路 PWM 使用 PA0 / PA1 / PA2,颜色映射为 R / B / G。部分旧注释与引脚定义不一致,接线应以实际配置和硬件为准。
- 传感器终端 / 灯控终端 ↔ 协调器:ZigBee。
- 协调器 ↔ Qt:UART,115200 baud,8N1,无流控。
- 灯控终端 ↔ STM32:UART,115200 baud,8N1,无流控。
CC2530 应用基于 Z-Stack SampleApp 和 OSAL 事件机制,通过 AF_DataRequest() 发送应用数据。
环境上报、光照上报,以及 Qt 生成和 STM32 接收的控制帧采用以下格式:
AA | 地址(2B) | CMD(1B) | LEN(1B) | DATA(NB) | SUM(1B) | 55
| 字段 | 说明 |
|---|---|
AA |
固定帧头 0xAA |
| 地址 | 两字节,高字节在前 |
CMD |
命令字 |
LEN |
DATA 的字节数 N,整帧长度为 N + 7 |
DATA |
对应命令的数据或控制参数 |
SUM |
地址、CMD、LEN、DATA 各字节累加,取低 8 位 |
55 |
固定帧尾 0x55 |
当前 CC2530 下行控制转发仍按 8 字节帧处理,与上述 9 字节控制帧不一致。此格式尚未在所有节点统一。
环境帧填写传感器节点的 ZigBee 短地址;光照帧与 Qt 控制帧中的地址固定为 0x0002。协调器当前采用广播下发控制数据,帧内地址不代表已经实现按该地址单播路由。
| CMD | 功能 | DATA 内容 | 整帧长度 |
|---|---|---|---|
0x01 |
环境数据上报 | 温度、湿度、MQ-2 DO、MQ-2 AO 高字节、AO 低字节、报警位 | 13 字节 |
0x02 |
光照数据上报 | 光照整数值高字节、低字节 | 9 字节 |
0x10 |
灯光控制 | 子命令、参数 | 9 字节(Qt / STM32 端) |
环境报警位:bit 0 表示温度超过 28 ℃,bit 1 表示 MQ-2 AO 超过 50。以上为当前代码阈值,烟雾 AO 是采样值,未换算为经过标定的浓度单位。
光照帧仅包含光照值,当前未定义灯光执行状态、控制模式或设备在线状态反馈。
| 子命令 | 功能 | 参数 0x00 |
参数 0x01 |
|---|---|---|---|
0x01 |
手动开关灯 | 关灯 | 开灯 |
0x02 |
自动模式 | 关闭自动调光 | 开启自动调光 |
0x03 |
报警联动 | 解除报警并关灯 | 进入报警并关闭自动模式 |
例如,Qt 生成的开灯命令为:
AA 00 02 10 02 01 01 16 55
串口 readyRead → 追加缓存 → 查找 0xAA → 读取 LEN
→ 等待完整帧 → 检查 0x55 → 提取并按 CMD 解析 → 更新界面
实现位于 qt_upper_computer/widget.cpp。缓存支持跨次接收保留半包,并循环提取连续帧;帧尾不匹配时移除一个字节后重新查找。
当前接收路径未验证 SUM,环境帧长度检查也尚未严格匹配 LEN=6、总长 13 字节。按钮样式反映本地发送操作,不代表设备已经确认执行。
业务任务主要定义在 stm32_node/Core/Src/main.c,使用 FreeRTOS 原生 API 与 CMSIS-RTOS2 API。
| 任务 | 入口 | 职责 |
|---|---|---|
| 串口解析任务 | vUartParseTask() |
等待线程标志,解析控制子命令并更新灯光 / 模式状态 |
| 光照采集任务 | vSensorTask() |
周期读取 BH1750,当前输出 BH1750_Lux=... lx 调试文本 |
| 灯光控制任务 | vLEDTask() |
根据报警、自动模式状态执行红灯闪烁或光照调光 |
此外,freertos.c 保留了 CubeMX 生成的默认任务,其循环仅执行延时。
USART1 单字节接收中断
→ rx_buf 累积 9 字节
→ 校验帧尾与 SUM
→ osThreadFlagsSet(..., 0x01)
→ 串口解析任务被唤醒并读取命令
接收实现位于 Core/Src/usart.c。当前 ISR 与任务共用接收缓冲区,尚未采用消息队列保存连续到达的完整帧。
Drivers/BSP/led/led.c 使用 TIM2 CH1 / CH2 / CH3 驱动 RGB 通道。当前控制逻辑按低电平点亮处理,比较值越小越亮,999 为关闭输出亮度;RGB_Set_Color() 统一设置三路比较值。
开灯调用 RGB_On(),输出预设暖色;关灯调用 RGB_Off(),将三路比较值置为 999。
手动命令不会自动退出自动模式。当前 RGB_Off() 中更新 g_RGB_State 的语句被注释,因此自动模式下的关灯行为仍需完善。
开启自动模式时先开灯,再由灯光任务读取 BH1750 并调用 RGB_Set_Warm_By_Lux():
- 光照值在 10~2500 lx 范围内映射到 PWM,采用平方系数调整暖色亮度。
- 光照达到 2300 lx 时关闭灯光,下降至 1800 lx 时允许恢复调光,形成回差。
- 小于 5 lx 的变化跳过亮度更新,减少频繁调整。
关闭自动模式仅停止自动调整,保留当时输出。当前光照采集任务与自动调光任务均会访问 BH1750,共享软件 I²C 的同步仍需完善。
Qt 将环境帧中任意非零报警状态视为异常,在状态切换时发送报警或解除命令。因此联动既可能由温度触发,也可能由烟雾 AO 触发。
STM32 灯光任务优先处理报警,红灯按周期交替亮灭。进入报警时关闭自动模式;解除报警时关灯,不会自动恢复报警前的模式和亮度。端到端联动仍受当前控制帧不一致问题影响。
毕业设计阶段已完成实物联调与演示。以下按当前源码整理验证方法与现状;本次文档整理未进行编译、烧录或硬件复测,表中预期结果不等同于当前已验证结果。
| 测试项目 | 测试方法 | 预期结果 | 当前结果 / 源码状态 |
|---|---|---|---|
| ZigBee 组网 | 启动协调器与终端,观察入网状态 | 终端入网后开始通信 | 有组网与状态事件处理代码,未硬件复测 |
| 环境数据上传 | 改变温湿度或 MQ-2 输入,抓取上报帧 | 收到字段对应的 13 字节环境帧 | 有采集与打包实现,未硬件复测 |
| UART 上行转发 | 比较协调器无线输入与串口输出 | 二进制数据一致 | 接收回调直接转发,未硬件复测 |
| Qt 环境解析 | 注入完整帧、拆分帧与连续帧 | 数值和报警提示更新 | 有缓存解析实现,未运行注入测试;SUM 未校验 |
| 温度曲线 | 连续注入不同温度的环境帧 | 曲线追加并滚动显示 | 有 QtCharts 实现,未运行验证 |
| 光照上报 | 检查 STM32 串口输出与 Qt 光照值 | 二进制光照帧到达 Qt | 当前仅输出调试文本,未启用二进制上传 |
| PWM 输出 | 向 STM32 注入有效命令并测量三路波形 | 开关灯、自动调光与报警输出符合策略 | 有 PWM 与命令处理实现,未硬件复测 |
| 控制命令下发 | 抓取 Qt、协调器、灯控终端与 STM32 各段数据 | 同一控制帧到达并执行 | 已发现 8 / 9 字节不一致,需修正后验证 |
ZigBee-SmartHome-System/
├── cc2530_coordinator/ # 协调器:IAR 工程、OSAL 应用、串口转发
├── cc2530_terminal/
│ ├── sensor_node/ # 环境终端:DHT11、MQ-2、数据打包
│ └── light_node/ # 灯控通信终端:ZigBee / UART 桥接
├── qt_upper_computer/ # Qt Widgets、串口解析与温度曲线
├── stm32_node/
│ ├── Core/ # 初始化、业务任务、UART 中断
│ ├── Drivers/BSP/ # BH1750、软件 I²C、LED 等
│ ├── Middlewares/ # FreeRTOS
│ └── MDK-ARM/ # Keil 工程
└── README.md
| 模块 | 工具 / 依赖 | 工程入口 |
|---|---|---|
| Qt 上位机 | Qt 5、Qt Creator、Widgets、SerialPort、Charts,C++11 | qt_upper_computer/demo40youhua.pro |
| CC2530 | IAR Embedded Workbench for 8051、配套 Z-Stack SDK | 各节点 CC2530DB/SampleApp.eww |
| STM32 | Keil MDK、STM32 HAL、FreeRTOS / CMSIS-RTOS2 | stm32_node/MDK-ARM/stm32_node.uvprojx |
| 上位机运行平台 | Orange Pi Zero2,需匹配目标系统的 Qt 运行环境 | Qt 可执行程序 |
CC2530 工程引用了仓库外的 Z-Stack Components、Tools 和库文件路径,仓库未包含完整 SDK。构建前需准备匹配的 SDK 并修正路径;具体工具和 SDK 版本仍需结合原开发环境核对。
以下为工程打开与部署步骤;全链路复现前需先处理第 8.5 节问题。
在 IAR 中打开 cc2530_coordinator/CC2530DB/SampleApp.eww,配置 Z-Stack 依赖路径,选择协调器构建目标并编译,下载至协调器 CC2530。将其 UART 连接至上位机。
分别打开 cc2530_terminal/sensor_node/CC2530DB/SampleApp.eww 与 cc2530_terminal/light_node/CC2530DB/SampleApp.eww,配置依赖并选择终端目标,编译后下载至对应 CC2530。
核对各节点信道、PAN ID 等组网配置。按驱动引脚连接 DHT11、MQ-2;灯控终端 UART 与 STM32 USART1 交叉连接 TX / RX,并共地。
打开 stm32_node/MDK-ARM/stm32_node.uvprojx,检查目标芯片、包含路径与下载器配置,编译并下载。按第 3 章接线,先分别核对 BH1750 读数、PWM 输出和串口命令接收。
验证完整光照上报前,需要恢复 vSensorTask() 对二进制发帧逻辑的调用,并检查通信串口中的调试输出。
使用带 Widgets、SerialPort、Charts 模块的 Qt 5 打开 qt_upper_computer/demo40youhua.pro,选择匹配运行平台的 Kit 后构建。
运行程序,选择协调器对应串口并打开,串口参数固定为 115200、8N1、无流控。在 Orange Pi Zero2 上运行时,需具备对应 Qt 库、图形环境和串口访问权限。当前程序启动时扫描串口。
- 当前版本复现状态:保留毕业设计实物成果说明,但未与演示时固件逐项比对,未完成当前仓库的全链路复测。
- 控制帧不一致:Qt 与 STM32 使用 9 字节控制帧,协调器和灯控终端按 8 字节处理,当前不能据此保证控制闭环。
- 光照上传为调试输出:
BH1750_Send_Light_Frame()已实现,当前采集任务未调用它。 - Qt 校验不完整:接收未验证 SUM,环境帧长度约束仍需收紧。
- 控制状态与反馈:关灯状态变量未同步;未实现执行确认、设备在线检测和模式状态回传,本地按钮状态不能替代设备反馈。
- 并发与通信健壮性:串口中断与任务共享缓冲区、多个任务访问软件 I²C 的同步,以及连续帧处理仍需完善。
- 构建依赖:CC2530 工程依赖外部 Z-Stack SDK,克隆仓库后仍需配置依赖路径。
- 统一各节点控制帧长度、字段与校验规则,完成端到端抓包验证。
- 恢复光照二进制上传,整理通信串口的调试输出。
- 完善 Qt SUM 校验、长度检查及异常帧恢复。
- 完善灯光模式切换、关灯状态同步与共享资源访问。
- 增加设备在线检测、灯光执行确认和模式状态反馈。
- 增加历史数据存储、历史曲线查询与报警日志。
- 补充工具链版本、硬件接线及可复现的测试记录。
本项目为个人毕业设计实物项目,用于学习、交流与求职项目展示,重点呈现多节点系统集成、无线通信、FreeRTOS 任务设计、Qt 上位机开发和软硬件联调实践。
项目代码可在保留原作者信息的前提下参考使用;随工程提供的第三方组件保留其各自的版权及许可声明。