构建一个房间监控系统
这是一个基于STM32 Blue Pill的房间监控系统,内置六个FreeRTOS任务、DHT22温湿度传感器、LDR光敏电阻、PIR运动传感器、旋转编码器、SSD1306 OLED显示屏和PWM蜂鸣器。
该模拟房间监控器采用STM32F103C8 Blue Pill芯片,用于测量温度、湿度、相对光照强度和运动状态。通过旋转编码器在SSD1306 OLED上切换四个页面之一。500 Hz的PWM输出用于提示温度低于18°C或高于30°C时的状态。当连续15秒无运动输入后,显示屏将自动清屏;PIR检测到活动后,系统将恢复为“活跃”状态。
我将其用于BCA182实验课作业1,以演示模块化FreeRTOS设计、周期性传感器采样、任务间通信、状态管理以及可重复的仿真验证功能。
动力
我选择了一个房间监控的场景,因为这能让实验室中FreeRTOS的相关概念变得具体可感:周期性传感、并发任务、任务间通信以及影响用户界面的状态变化。在Wokwi上运行它,让我可以在尝试实际硬件之前,反复测试传感器和输入场景,并观察显示效果和报警行为。
功能特点
显示器从DHT22传感器获取温度和湿度数据,从LDR传感器获取相对亮度。其OLED屏幕可通过旋转编码器选择显示“温度、湿度、光照”和“运动”页面。PIR输入开关可在“活动”与“非活动”状态之间切换,当15秒内无运动时,显示屏将自动关闭。当温度低于18°C或高于30°C时,500 Hz的PWM蜂鸣器会发出提示音。
组件
•1 个 STM32F103C8 蓝色芯片
•1 个 DHT22 温湿度传感器
•1 个 5.1 kΩ 的 DHT22 数据线上拉电阻
•1 个光敏电阻模块(LDR)
•1 个 PIR 运动传感器
•1 个 KY-040 旋转编码器
•1 个 SSD1306 I2C OLED 显示屏
•1 个压电蜂鸣器
•软件与工具:PlatformIO、STM32Cube HAL、FreeRTOS、Unity 和 Wokwi。
完整的电路图和引脚映射见源码仓库中的 diagram.json 文件。连接方式如下:PB12 用于 DHT22 数据,PA0 用于 LDR 模拟输出,PB13 用于 PIR 输出,PA1/PA2 用于编码器的时钟/数据信号,PB6/PB7 用于 I2C OLED,PB8 用于 TIM4 蜂鸣器 PWM,PA9 用于 USART1 故障诊断。
FreeRTOS 架构
系统由六个任务共同完成工作:SensorTask 每两秒采样一次 DHT22 和 LDR;DisplayTask 负责 OLED 显示;InputTask 处理编码器事件;MotionTask 采集 PIR 信号;StateTask 管理设备的“活动”或“静止”状态;AlarmTask 判断温度并控制蜂鸣器。
SensorTask 将每个新的 SensorData 值发布到分别属于 DisplayTask 和 AlarmTask 的单元素队列中,确保两个消费者都能获取最新的读数。事件组位表示运动、活动和报警状态。一个互斥锁用于串行化来自不同任务的 USART1 日志;DisplayTask 是唯一的 OLED 使用者。
vTaskDelayUntil() 会从上一次计划唤醒时间开始调度采样,从而限制累计的时间漂移。运动、编码器和状态处理具有优先级3;传感器和报警处理使用优先级2;较慢的OLED操作使用优先级1。任务在定时延迟、队列或工作之间的事件上会阻塞。
系统架构
STM32 Blue Pill 是电路的中心。DHT22 数据线使用 PB12,LDR 模拟输出 PA0,PIR 输出 PB13,以及 KY-040 编码器 PA1/PA2。SSD1306 OLED 通过 I2C 接口连接在 PB6/PB7 上,压电蜂鸣器由 TIM4 PWM 通过 PB8 控制;USART1 在 PA9 上用于传输诊断日志。传感器读数传送到显示屏并触发报警判断,而运动和编码器输入则更新显示器状态和所选页面。上述 FreeRTOS 架构展示了调度器如何对这些任务进行划分与同步。
它是如何运作的
DHT22 传感器驱动器将 PB12 设置为输入上拉模式,并在每个数据位的上升沿后 40 微秒采样一次。在发布读数前,它会验证校验和。LDR 的 ADC 值被转换为相对亮度百分比,而非校准后的勒克斯(lux)。编码器方向可选择温度、湿度、光照或运动,双向循环计数。TIM4 渠道 3 以约 500 Hz 的频率生成蜂鸣波形。
“Light” 页面以百分比形式报告相对亮度,未进行勒克斯校准。
演示
1. 克隆源代码仓库,并在已安装 PlatformIO 和 Wokwi 的 VS Code 中打开它。
2. 使用以下命令构建 Blue Pill 目标:pio run -e bluepill_f103c8
3. 启动 Wokwi:启动模拟器。电路定义在 diagram.json 中,固件路径位于 wokwi.toml 中。
4. 更改DHT22和光敏电阻的控制参数,双向旋转编码器,并触发PIR传感器。验证记录中描述了每项刺激及观察到的结果。
测试与验证
固件构建通过。所有15个Unity原生测试均通过,涵盖报警阈值、编码器切换与绕圈、活动状态转换以及亮度端点等场景。PlatformIO静态分析未发现高严重性或中等严重性的问题;仅在STM32 HAL或FreeRTOS宏调用位置发现了16条低严重性C语言类型转换问题。
Wokwi运行了经过验证且校验和有效的DHT22读数,包括改变LDR输出、四个OLED页面、PIR激活/非激活状态切换,以及两种带绕圈的编码器序列。顺时针顺序为:温度、湿度、光照、运动,再回到温度;逆时针顺序为:温度、运动、光照、湿度,再回到温度。
当温度为33.1°C、相对湿度为66.0%时,OLED显示“ALARM”提示,Wokwi蜂鸣器的活动指示灯亮起。在32°C时保留的PB8逻辑波形频率约为500 Hz,占空比为50%;恢复波形显示PB8在正常温度采样后返回低电平。这些是模拟器观测结果,而非对声级的独立测量。
来自32°C Wokwi报警运行的PB8波形:平均频率为499.8 Hz,占空比为50.0%。
故障实验表明,在观察到的运行期间,移除MotionTask的延迟或提高其优先级会抑制传感器输出。绕过UART互斥锁后,在短时捕获中未出现明显的线路交织现象,因此该竞态条件未能被重现。
演示
上述OLED和串行捕获显示了读数、页面切换、运动心率以及完成的DHT22读取;32°C运行显示的是报警状态,而PB8波形记录了约499.8 Hz的频率,占空比为50.0%。链接的验证记录列出了刺激内容及观测结果。这些结果来自Wokwi仿真;该项目尚未在实际电路板上进行验证。
挑战与经验教训
一个带两个消费者的单个传感器队列会将更新信息分配给显示和报警任务,因此需要分别设置一个单条消息的邮箱以保持两个消费者的数据同步。DHT22脉冲定时需要一个短时中断屏蔽的事务;采用硬件定时器输入捕获实现可降低该延迟成本。压电蜂鸣器需要定时PWM信号,而不是恒定的GPIO电平。
局限性与未来工作
本项目已在Wokwi中验证,但尚未在实际电路板上进行测试,也未进行独立的蜂鸣器声音水平测量。物理电压电平、上拉电阻、定时裕度、传感器校准以及声学输出均需通过硬件测试。未来的改进包括为DHT脉冲提供定时器输入捕获、校准光照测量、任务延迟测量,以及明确的传感器故障报警功能。
本文编译自hackster.io





