【STM32开源项目】智能环境监测
目录
一、项目概述
这次分享的是一个基于STM32F103C8T6做的智能环境监测小项目,能测空气质量、温湿度、PM2.5、甲醛和一氧化碳,超标了会自动开风扇报警,还能连Wi-Fi用手机远程看数据。
硬件方面用了一块STM32F103C8T6最小系统板做主控,外接0.96寸OLED屏幕显示数据,DHT11测温湿度,PM2.5粉尘传感器测颗粒物,三合一传感器测甲醛,MQ-7测一氧化碳,ESP8266连Wi-Fi,继电器控制风扇,再加个蜂鸣器和LED做报警。软件上把各传感器的驱动调通,OLED能正常显示,接入机智云平台实现手机远程查看和控制,本地按键和手机都能改报警值,超标自动触发风扇和报警,数据还会存到阿里云方便以后查历史。
整体代码不复杂,注释也都写清楚了,适合刚接触STM32和物联网的同学参考。实际跑起来效果挺稳定,数据准,联网也可靠,做个宿舍或家里的小型环境监测终端完全够用
二、实现功能
1、功能详解:
-
传感器检测:实时采集空气质量、光照强度、温湿度、PM2.5粉尘、三合一甲醛等环境数据。
-
数据显示:通过0.96寸OLED屏幕直观显示全部传感器数据及对应阈值信息。
-
执行机构:联动控制风扇与声光报警模块。
-
接入云平台:通过ESP8266 Wi-Fi联网,接入机智云平台。
-
App远程监控:通过手机App远程查看全部传感器数据。
-
阈值数据设定:可通过本地按键设定阈值,也可通过手机App远程设定。
-
自动模式:当空气质量、PM2.5、甲醛等数据超标时,自动开启风扇通风并触发声光报警。
-
历史数据记录:传感器数据上传并存储于阿里云平台,支持在云平台后台查看历史数据
-
2、项目清单:
-
主控STM32F103C8T6 最小系统板
-
OLED 显示屏
-
DHT11 温湿度传感器
-
ESP8266 WiFi 模块
-
三合一甲醛传感器
-
PM2.5 粉尘传感器
-
MQ-7 一氧化碳传感器
-
继电器
-
风扇模块
-
有源蜂鸣器
-
LED 指示灯
-
3、演示视频:
三、硬件介绍
-
PCB硬件设计:
-


四、程序设计
#include "delay.h"
#include "sys.h"
#include "bmp.h"
#include "usart.h"
#include "dht11.h"
#include "control.h"
#include "adc.h"
#include "IoData.h"
#include "key.h"
#include "kqm2800.h"
#include "timer.h"
#include "oled.h"
/**** 数据变量 ****/
int temp_door_value = 30; //温度阈值解析
int hum_door_value = 20; //湿度阈值解析
int smoke_door_value = 500; //烟雾阈值解析
int co2_door_value = 700; //co2阈值解析
int pm25_door_value = 300; //pm2.5阈值解析
int light_door_value = 3000; //光照阈值解析
int auto_mode = 0; //工作模式
/**** 菜单变量 ****/
uint8_t keu_num = 0;
uint8_t page_num = 1; //页面ID
uint8_t option = 0; //阈值选项
/**** 功能函数声明 ****/
void All_Pin_Init(void); //系统初始化函数
void get_all_sensor_data(); //传感器数据采集
void Sensor_Data_Handle(); //不同模式下控制效果
void Key_event_handle(void); //按键功能函数
void OLED_Show_FirstPage(); //第一屏显示内容
void OLED_Show_SecondPage(); //第二屏显示内容
void OLED_Show_ThirdPage(); //第三屏显示内容
void OLED_Show_FourthPage(); //第四屏显示内容
void All_Pin_Init(void)
{
delay_init(); //系统延时函数初始化
OLED_Init(); //屏幕初始化
uart3_init(115200); //串口3初始化,波特率115200
uart1_init(115200); //串口1初始化,波特率115200
uart2_init(9600); //串口2初始化,波特率9600,CO2
DHT11_Init(); //DHT11温湿度初始化
Control_Init(); //声光报警,照明初始化
Adc_Init(); //烟雾浓度、pm2.5浓度、光照强度初始化
TIME_Config(); //定时器初始化
KEY_Init(); //按键初始化
PM25_Init(); //PM2.5led引脚初始化
}
int main(void)
{
All_Pin_Init();
while(1)
{
if(Time_Period[1]>1000) //Time_Period[1] 在定时器中累加
{
get_all_sensor_data(); //传感器数据采集
Time_Period[1] = 0;
}
Key_event_handle(); //按键监测
Sensor_Data_Handle(); //数据处理
if(page_num == 1){ //屏幕更新
OLED_Show_FirstPage();
}else if(page_num == 2){
OLED_Show_SecondPage();
}else if(page_num == 3){
OLED_Show_ThirdPage();
}
}
}
void Key_event_handle(void)
{
keu_num = KEY_Scan(0); //按键扫描赋值
switch(keu_num)
{
case 1: //按键1按下
page_num++;option = 0;
if(page_num == 1){
OLED_Clear();OLED_Show_FirstPage();
}else if(page_num == 2){
OLED_Clear();OLED_Show_SecondPage();
}else if(page_num == 3){
OLED_Clear();OLED_Show_ThirdPage();
}else if(page_num == 4){
page_num = 1;
OLED_Clear();OLED_Show_FirstPage();
}
break;
case 2: //按键2按下
if(page_num == 2){ //阈值选择
option++;
if(option == 5)option = 1;
OLED_Show_SecondPage();
}else if(page_num==1){
auto_mode = !auto_mode;
}else if(page_num == 3){
option++;
if(option == 3)option = 1;
OLED_Show_ThirdPage();
}
break;
case 3: //按键3按下
if(page_num == 2){
if(option == 1){
temp_door_value += 1;
}else if(option == 2){
hum_door_value += 1;
}else if(option ==3){
smoke_door_value += 15;
}else if(option ==4){
pm25_door_value += 5;
}
OLED_Show_SecondPage();
}else if(page_num == 3){
if(option==1)co2_door_value += 15;
else if(option==2)light_door_value += 15;
OLED_Show_ThirdPage();
}else Wind = !Wind;
break;
case 4: //按键4按下
if(page_num == 2){
if(option == 1){
temp_door_value -= 1;
}else if(option == 2){
hum_door_value -= 1;
}else if(option ==3){
smoke_door_value -= 15;
}else if(option ==4){
pm25_door_value -= 5;
}
OLED_Show_SecondPage();
}else if(page_num == 3){
if(option==1)co2_door_value -= 15;
else if(option==2)light_door_value -= 15;
OLED_Show_ThirdPage();
}else if(page_num==1){
}
break;
}
}
void get_all_sensor_data()
{
DHT11_Read_Data(&temp,&hum); //获取温湿度数据
Get_MQ_Value(&MQ_Value); //获取烟雾数据
Get_PM25_Value(&PM25_Value); //获取PM2.5
Get_Light_Value(&Light_Value); //获取光照强度
Get_CO2_Data(); //获取CO2浓度
}
void Sensor_Data_Handle()
{
//自动模式
if(auto_mode == 1) //如果开启了自动模式则可以实现根据数据的自动控制
{
//温度、湿度、烟雾浓度、pm2.5浓度、CO2浓度、光照强度,超过阈值蜂鸣器报警
if(temp>temp_door_value||hum>hum_door_value||MQ_Value>smoke_door_value||PM25_Value>pm25_door_value||Kqzl.CO2>co2_door_value||Light_Value>light_door_value){
Beep = 1;
} else {
Beep = 0;
}
//温度、湿度、烟雾浓度、pm2.5浓度、CO2浓度,超过阈值打开风扇通风
if(temp>temp_door_value||hum>hum_door_value||MQ_Value>smoke_door_value||PM25_Value>pm25_door_value||Kqzl.CO2>co2_door_value){
Wind = 1;
} else {
Wind = 0;
}
}else{
//手动模式下,关闭蜂鸣器
Beep = 0;
}
}
/*
温(0) 湿(1) 度(2) 烟(3) 雾(4) 浓(5) 度(6) ℃(7) 自(8) 手(9) 动(10) 模(11) 式(12) 阈(13) 值(14) 空(15)
气(16) 质(17) 量(18) 光(19) 照(20) 强(21) 度(22)
*/
void OLED_Show_FirstPage(){
OLED_ShowString(16*0,0,"T:",16,1);
OLED_ShowNum(16*1,0,temp,2,16,1); // temp
OLED_ShowChinese(16*2,0,7,16,1); // “℃”
OLED_ShowString(16*3+8,0,"PM2.5:",16,1); // “:”
OLED_ShowNum(16*6+8,0,PM25_Value,3,16,1); //
OLED_ShowString(16*0,16,"H: %RH",16,1);
OLED_ShowNum(16*1,16,hum,2,16,1); // hum
OLED_ShowString(16*4,16,"CO2:",16,1);
OLED_ShowNum(16*6,16,Kqzl.CO2,4,16,1); // hum
OLED_ShowChinese(16*0,32,19,16,1); //光
OLED_ShowChinese(16*1,32,20,16,1); //照
OLED_ShowChinese(16*2,32,21,16,1); //强
OLED_ShowChinese(16*3,32,22,16,1); //度
OLED_ShowChar(16*4,32,':',16,1); // “:”
OLED_ShowNum(16*4+8,32,Light_Value,4,16,1);
OLED_ShowChinese(16*0,48,15,16,1); //空
OLED_ShowChinese(16*1,48,16,16,1); //气
OLED_ShowChinese(16*2,48,17,16,1); //质
OLED_ShowChinese(16*3,48,18,16,1); //量
OLED_ShowChar(16*4,48,':',16,1); // “:”
OLED_ShowNum(16*4+8,48,MQ_Value,4,16,1); // Soil_Value
if(auto_mode == 1){
OLED_ShowChinese(16*7,32,8,16,1); // “自”
OLED_ShowChinese(16*7,48,10,16,1); // “动”
}else if(auto_mode == 0){
OLED_ShowChinese(16*7,32,9,16,1); // “手”
OLED_ShowChinese(16*7,48,10,16,1); // “动”
}
OLED_Refresh();
}
void OLED_Show_SecondPage(){
uint8_t a,b,c,d;
if(option==1){a=0;b=1;c=1;d=1;}
else if(option==2){a=1;b=0;c=1;d=1;}
else if(option==3){a=1;b=1;c=0;d=1;}
else if(option==4){a=1;b=1;c=1;d=0;}
else{a=1;b=1;c=1;d=1;}
OLED_ShowChinese(16*0,0,0,16,1); // “温”
OLED_ShowChinese(16*1,0,2,16,1); // “度”
OLED_ShowChinese(16*2,0,13,16,1); // “阈”
OLED_ShowChinese(16*3,0,14,16,1); // “值”
OLED_ShowChar(16*4,0,':',16,1); // “:”
OLED_ShowNum(16*4+8,0,temp_door_value,3,16,a); // temp_door_value
OLED_ShowChinese(16*0,16,1,16,1); // “湿”
OLED_ShowChinese(16*1,16,2,16,1); // “度”
OLED_ShowChinese(16*2,16,13,16,1); // “阈”
OLED_ShowChinese(16*3,16,14,16,1); // “值”
OLED_ShowChar(16*4,16,':',16,1); // “:”
OLED_ShowNum(16*4+8,16,hum_door_value,3,16,b); // hum_door_value
OLED_ShowChinese(16*0,32,15,16,1); // “空”
OLED_ShowChinese(16*1,32,16,16,1); // “气”
OLED_ShowChinese(16*2,32,13,16,1); // “阈”
OLED_ShowChinese(16*3,32,14,16,1); // “值”
OLED_ShowChar(16*4,32,':',16,1); // “:”
OLED_ShowNum(16*4+8,32,smoke_door_value,4,16,c); // hum_door_value
OLED_ShowChar(8*0,48,'P',16,1); // “P”
OLED_ShowChar(8*1,48,'M',16,1); // “M”
OLED_ShowChar(8*2,48,'2',16,1); // “2”
OLED_ShowChar(8*3,48,'.',16,1); // “.”
OLED_ShowChar(8*4,48,'5',16,1); // “5”
OLED_ShowChinese(8*5,48,13,16,1); // “阈”
OLED_ShowChinese(8*5+16,48,14,16,1); // “值”
OLED_ShowChar(8*5+16*2,48,':',16,1); // “:”
OLED_ShowNum(8*6+16*2,48,pm25_door_value,4,16,d); // PM25_Value
OLED_Refresh();
}
void OLED_Show_ThirdPage(){
uint8_t a,b,c,d;
if(option==1){a=0;b=1;c=1;d=1;}
else if(option==2){a=1;b=0;c=1;d=1;}
else if(option==3){a=1;b=1;c=0;d=1;}
else if(option==4){a=1;b=1;c=1;d=0;}
else{a=1;b=1;c=1;d=1;}
OLED_ShowString(16*0,0,"CO2",16,1); //“:”
OLED_ShowChinese(16*1+8,0,13,16,1); // “阈”
OLED_ShowChinese(16*2+8,0,14,16,1); // “值”
OLED_ShowChar(16*3+8,0,':',16,1); // “:”
OLED_ShowNum(16*4,0,co2_door_value,4,16,a); // hum
OLED_ShowChinese(16*0,16,19,16,1); // “光”
OLED_ShowChinese(16*1,16,20,16,1); // “照”
OLED_ShowChinese(16*2,16,13,16,1); // “阈”
OLED_ShowChinese(16*3,16,14,16,1); // “值”
OLED_ShowChar(16*4,16,':',16,1); // “:”
OLED_ShowNum(16*4+8,16,light_door_value,4,16,b); // hum_door_value
OLED_Refresh();
}
五、项目成品效果图

六、项目总结
这个项目从头到尾做下来,硬件焊接、代码编写、调试联测都走了一遍,最后所有功能都跑通了,总结一下:
-
数据采集显示方面:温湿度、PM2.5、甲醛、一氧化碳都能正常读到数据,OLED屏上实时刷新显示所有数值和设定的报警阈值,看一眼就知道当前环境啥情况。
-
自动控制方面:只要PM2.5、甲醛或者一氧化碳超了设定的值,风扇马上自己转起来通风,蜂鸣器响、LED灯闪,提醒效果到位,反应也挺快的。
-
远程监控方面:ESP8266成功连上了机智云,手机App上所有数据都能看到,在家躺着也能知道房间空气质量咋样。报警值也能在App上直接改,不用蹲在设备前按按键。
-
数据存储方面:数据定时往阿里云上传,后台能看到历史曲线,哪天空气不好一查就知道。
总的来说这个项目从硬件到软件到云端全流程打通了,既有学习价值也能实际用起来,成本不高,感兴趣的话还可以继续往上加功能,比如换更精准的传感器、加个外壳做成产品级的样子等等
七、资料说明
1)本资料免费分享,获取全套资料请看主页,并将告诉助手需要资料的项目编号,助手收到消息后,会发送百度网盘链接。每人限领两份开源资料。
2)需要实物或者定制的小伙伴可以添加工作室微信,发送项目需求,可以按照需求定制项目。定制包含源码、原理图、全套实物、模块参考资料、更详细的参考资料。
3)重点!!!在本工作室定制的项目,提供一年的技术支持和答疑服务,定制功能范围内的代码和原理图工程师一对一解疑答惑!
资料获取:查看主页介绍“充哥单片机设计”
更多推荐



所有评论(0)