CSDN推文_STM32空气质量监测系统
【毕设实战】基于STM32的空气质量监测系统:温湿度+甲醛+PM2.5+CO五合一,ESP8266上云+安卓APP远程控阈值(附完整方案)
一篇把「毕设从0到1」讲透的技术复盘:硬件选型、原理图、驱动移植、通信协议、APP联调、调试踩坑全覆盖。适合嵌入式/物联网方向的毕设、课设、电子竞赛同学直接参考。
一、为什么要做这样一台"空气体检仪"
刚装修完的房子能不能住?办公室里二手烟有没有超标?车里空气干不干净?这些问题,商用空气检测仪动辄大几百上千,而且大多只能本地看数,没法远程盯、没法超限自动处理。
于是毕设选了这个题目:做一台低成本、多参数、能联网、能自动排风报警的空气质量监测终端。最终落地的这套系统,把 5 个空气质量关键参数量化到一块 0.96 寸 OLED 上,同时通过 ESP8266 把数据推到安卓 APP,人不在现场也能看到家里空气到底"脏不脏"。
先放一下最终的功能清单(也是答辩 PPT 里那张"功能列表"):
| 监测参数 | 传感器 | 单位 | 默认报警阈值 |
|---|---|---|---|
| 温度 | DHT11 | ℃ | 35 |
| 湿度 | DHT11 | %RH | 75 |
| 甲醛 CH₂O | 三合一VOC模块 | mg/m³ | 0.10 |
| PM2.5 | 红外粉尘传感器 | μg/m³ | 200 |
| 一氧化碳 CO | MQ-7 | ppm | 200 |
阈值不是写死的——设备上三个按键可以本地改,APP 上也能远程下发,双向同步。
二、系统总体方案
整套系统分三层:感知层 → 主控层 → 应用层。
┌─────────────┐ ┌──────────────────────────────┐ ┌──────────────┐
│ 感知层 │ │ 主控层 STM32 │ │ 应用层 │
│ DHT11温湿度 │──▶│ 采集 → 滤波 → 显示 → 判定 │──▶│ OLED 本地屏 │
│ MQ-7 CO │──▶│ 超限 → 蜂鸣器/继电器排风 │──▶│ 安卓 APP │
│ PM2.5粉尘 │──▶│ 800ms 组帧 → ESP8266 上传 │──▶│ 远程阈值下发 │
│ 甲醛VOC模块 │──▶│ │ │ │
└─────────────┘ └──────────────────────────────┘ └──────────────┘
▲
│ I2C
┌────┴────┐
│ 0.96" │
│ OLED │
└─────────┘
- 主控:STM32F103C8T6 最小系统板(Cortex-M3,72MHz,64KB Flash,毕设性价比之王)
- 通信:ESP8266-01S(串口转 WiFi,透传模式连路由器)
- 执行机构:5V 继电器控制风扇排风 + 有源蜂鸣器声光报警
- 人机交互:0.96 寸 OLED(SSD1306,I2C)+ 3 个独立按键
硬件 BOM、原理图、PCB、Keil5 工程、Android Studio 工程、各模块 datasheet 全部归档在项目里,后面调试时查起来非常方便。
三、硬件选型与接线思路
1. 为什么选这几颗传感器
- DHT11:单总线协议,温湿度一起出,便宜(~5块),精度对毕设足够(温度±2℃、湿度±5%RH)。
- MQ-7:半导体气敏元件,专门测 CO,需要 ADC 采集分压电压,再用经验曲线换算成 ppm。代码里做了 1000ppm 上限截断,防止 ADC 抖跳成负数。
- 红外 PM2.5(类似 GP2Y/SDS011 类):串口输出,9600bps,自带校验和。读 4 个字节,按
(buf[1]*128 + buf[2]) * 校准系数换算成 μg/m³。 - 三合一 VOC/甲醛模块:串口输出 9 字节帧,带字节和校验,直接给 mg/m³ 数值,省去了 VOC 曲线标定的麻烦。
- ESP8266-01S:体积小、够用,AT 指令透传,STM32 通过 USART1 对接。
2. 串口分配(这步最容易踩坑)
| 串口 | 波特率 | 接谁 |
|---|---|---|
| USART1 | 115200 | 调试 printf |
| USART2 | 9600 | 甲醛/VOC 模块 |
| USART3 | 9600 | PM2.5 模块 |
| 另一组 GPIO(软件串口或复用) | 115200 | ESP8266 |
⚠️ 坑点提醒:ESP8266 默认波特率是 115200,但很多出厂固件是 9600。上电第一件事就是串口助手打
AT,看回不回OK,不回就换波特率试,别上来就写驱动。
3. 继电器/蜂鸣器
继电器和蜂鸣器各接一个推挽 GPIO,用 NPN 三极管驱动(5V 继电器线圈电流大,不能直接用 STM32 IO 驱动)。代码里统一用一个 BEEP 和一个 RELAY 宏控,方便移植。
四、软件设计:主循环干了几件事
Keil5 + 标准固件库(StdPeriph_Lib),工程按 User / Driver / System / Libraries 分目录,Driver 目录下放每个模块的 .c/.h:dht11.c / MQ7.c / esp8266.c / OLED_I2C.c / adc.c / timer.c / usart2.c / usart3.c。
主循环的核心逻辑其实就四句话:
while(1)
{
keyscan(); // ① 按键扫描(阈值设置)
if(setn == 0) // ② 非设置页才采集+显示+判定
{
timeCount++;
if(timeCount >= 180) // 每 ~1.8s 读一次 DHT11(它本来就慢)
DHT11_Read_Data(&temperature, &humidity);
if(shuaxin == 1) // TIM3 每 300ms 置位一次,刷新 OLED
{
shuaxin = 0;
Get_MQ7_PPM(); // 读 CO
Get_CH2O(); // 读甲醛
Get_PM2_5(); // 读 PM2.5
/* 刷新 OLED + 超限闪烁 */
if(温度/湿度/甲醛/PM2.5/CO 任一超限) { BEEP = 1; RELAY = 1; }
else { BEEP = 0; RELAY = 0; }
}
}
UsartSendReceiveData(); // ③ 与 ESP8266 收发(APP 通信)
delay_ms(10);
}
定时器 TIM3 做了两件事:
if(timeCount1 >= 300) { shanshuo = !shanshuo; shuaxin = 1; } // 300ms 刷新屏
if(timeCount2 >= 800) { sendFlag = 1; } // 800ms 上传一次
为什么不用阻塞延时? 因为 DHT11 读一次要 ~20ms,PM2.5 和甲醛是异步串口帧,如果都放在主循环里死等,按键就会卡。所以用定时器中断置标志位,主循环看到标志再干活——这是嵌入式里最朴素也最有效的"前后台系统"。
五、WiFi 上云:和安卓 APP 的通信协议
这是整个毕设**最有"物联网味"**的部分,也是答辩老师最爱问的。
1. 设备 → APP(主动上报)
每 800ms 组一帧,格式设计成"键值对 + 特殊分隔符",方便 APP 端正则/字符串截取:
temp_warn,humi_warn,pm2.5_warn,ch2o_warn,co_warn,$temp:26#,$humi:55#,$ch2o:0.035#,$pm2.5:32#,$co:12#
- 前缀部分是报警位:哪个参数超限了,就把对应的
xxx_warn,拼进去;没超限就不拼。APP 一看前缀就知道要不要弹窗。 - 后面 5 个
$key:value#是实时数据。
2. APP → 设备(远程改阈值)
APP 下发字符串,STM32 端用 strstr 匹配关键字:
if(strstr((char *)dataPtr, "temp_max:") != NULL) { /* 解析温度上限 */ }
if(strstr((char *)dataPtr, "humi_max:") != NULL) { /* 解析湿度上限 */ }
if(strstr((char *)dataPtr, "chIIo:") != NULL) { /* 解析甲醛上限 */ }
if(strstr((char *)dataPtr, "pm_max:") != NULL) { /* 解析 PM2.5 上限 */ }
if(strstr((char *)dataPtr, "co_max:") != NULL) { /* 解析 CO 上限 */ }
解析完立刻写回全局变量并刷新 OLED,设备和 APP 两端阈值保持一致——这一点在答辩时被老师夸了一句"通信闭环做完整了"。
工程上小细节:解析数字时先跳过非数字字符,再连续读
0-9,遇到,\r.就停。这样 APP 端不管怎么拼字符串都不容易把 STM32 解析崩。
六、按键设置:三键完成全部参数配置
设备面板上就 3 个按键,没加触摸屏也够用:
- KEY1:切换设置项(温度→湿度→甲醛→PM2.5→CO→退出)
- KEY2:当前项 +1
- KEY3:当前项 -1
进入设置页时 OLED 清空,顶部显示"设置温度/设置湿度/…",第 4 行显示当前值。不用串口助手、不用上位机,现场就能调——这对演示现场特别友好。
七、调试踩坑记录(干货在这)
- DHT11 初始化死等:DHT11 上电后需要 1s 稳定,代码里
while(DHT11_Init())失败就一直刷"DHT11 Init!",如果硬件接线松了会卡在 loading。建议加个超时计数,失败 10 次就跳过,别把整个系统拖死。 - PM2.5 校验和:必须验
(buf[0]+buf[1]+buf[2]) & 0x7F == buf[3],否则串口上偶尔串出来的脏数据会让 PM2.5 跳到 999。 - 甲醛模块字节序:是
buf[4]*256 + buf[5],不是小端,初次读出来差 256 倍,排查了半宿。 - MQ-7 加热特性:MQ-7 需要周期性加热,刚上电前 2~3 分钟读数飘得厉害,演示前一定要提前开机预热,别现场才发现 CO 读数乱跳。
- ESP8266 上电时序:STM32 先跑起来再初始化 ESP8266,要
delay_ms(1000)等模块就绪,否则前几条 AT 指令石沉大海。 - 蜂鸣器和继电器共地:5V 继电器一开,整个电源被拉低,OLED 会闪一下。建议继电器线圈两端加续流二极管,电源入口加大电容。
八、总结
这套毕设我最大的收获,不是焊了多少块板、调通了多少个传感器,而是把**“感知 → 决策 → 执行 → 联网”**这条物联网链路完整跑通了一遍:
- 会用了 GPIO / 单总线 / I2C / ADC / USART / 定时器中断
- 学会了自定义通信协议 + 字符串解析
- 理解了前后台系统、标志位消抖、异步串口帧处理
- 体验了从硬件到 APP 的全栈联调
如果你也在做类似题目,下面这份资料清单可以直接照着搭:
- STM32F103C8T6 最小系统板
- DHT11 / MQ-7 / GP2Y 类 PM2.5 / 三合一甲醛VOC 模块
- ESP8266-01S
- 0.96 寸 OLED(SSD1306, I2C)
- 5V 继电器模块 + 有源蜂鸣器 + 5V 风扇
- Keil5 + STM32F10x 标准库
- Android Studio(APP 用 ESP8266 做 TCP Server,手机连同一个 WiFi 即可)
如果这篇文章对你有帮助,欢迎 点赞 + 收藏 + 关注,后面我会把 OLED 显示驱动、ESP8266 透传配置、安卓 APP 通信这几个子模块单独拆出来写,毕竟毕设这事儿,一个人踩坑不如大家一起趟。有问题评论区聊,看到都会回 👋
标签:STM32 毕业设计 物联网 ESP8266 空气质量监测 嵌入式 Android MQ-7 DHT11 PM2.5 创客
更多推荐


所有评论(0)