【STM32项目开源】基于STM32的智能家居环境监测系统
本文介绍了一款基于STM32的智能家庭环境监测系统。该系统通过DHT11温湿度传感器、PM2.5传感器、MQ-2烟雾传感器等模块实时采集室内环境数据,并通过OLED屏幕显示。用户可通过按键或手机APP设置环境阈值,实现自动控制风扇、加湿器、步进电机(模拟窗户)等设备。系统支持手动/自动模式切换,并通过ESP8266 WiFi模块接入机智云平台,实现远程监控和数据记录。硬件部分包含STM32主控板、
目录
一、设计背景和意义
1.1设计背景
随着城市化进程的加快和人们生活节奏的加快,居住环境的安全性、舒适性与智能化水平日益成为公众关注的焦点。家庭作为人们日常生活最主要的空间,其环境质量直接关系到居民的身体健康和生活质量。大量研究表明,室内空气污染物(如PM2.5、可燃性气体、烟雾等)对人体健康危害极大,尤其对儿童、老人、孕妇及呼吸系统疾病患者影响更为明显。此外,温度和湿度的不合理也容易引发不适甚至诱发疾病。在这种背景下,建设一个能够实时监测家庭环境、智能识别风险并自动联动处理的系统显得尤为重要。
传统的家庭环境监控设备往往存在功能单一、价格昂贵、缺乏远程控制能力、无法个性化配置等诸多问题,无法满足普通用户对高性价比、可拓展、智能化环境控制系统的需求。尤其是在现今物联网技术迅猛发展的背景下,越来越多的用户希望通过智能手机远程查看家庭环境状况,甚至实现自动响应与干预。因此,将嵌入式系统、无线通信技术与云平台管理结合,构建一个功能集成、操作简便、具备自动响应能力的家庭环境检测系统,具有广阔的应用前景和研究价值。
1.2设计意义
本课题基于STM32F103C8T6单片机,结合DHT11温湿度传感器、PM2.5空气质量传感器、MQ-2烟雾传感器等环境采集模块,能够实现对家庭环境的全面监控。同时,结合ESP8266 WiFi模块接入“机智云”平台,使用户能够通过手机APP远程查看当前环境数据,控制风扇、加湿器、步进电机和声光报警等设备。在自动模式下,系统还可根据设定阈值实现智能判断与响应,无需人工干预,从而有效提升家庭环境的安全性与舒适性。
本课题的研究不仅具备明确的现实意义,还具有良好的技术引导价值。一方面,它通过综合应用嵌入式开发、传感器技术、通信协议、云平台交互等知识体系,全面锻炼了学生的工程实践能力与系统集成能力;另一方面,它紧密结合智能家居、物联网等前沿热点,为今后从事智能控制系统开发、环境感知系统设计等方向奠定良好基础。因此,该课题既契合当前社会发展对智慧生活的需求,又贴合计算机专业本科毕业设计对综合能力培养的目标,是一个具有理论价值与实践意义的研究项目。
二、实物效果展示
2.1实物图片

2.2实物演示视频
【STM32开源】智能家庭环境监测系统
三、硬件功能简介
3.1项目功能详解
- 传感器检测:检测烟雾、PM2.5、温湿度等等数据
- 数据显示:0.96OLED屏幕显示全部的传感器数据以及传感器的阈值等数据。
- 执行机构:控制风扇、加湿器、步进电机(窗户)
- 接入云平台:系统通过ESP8266 WIFI联网后,接入机智云平台。
- App远程监控:通过App远程监控全部传感器数据
- 阈值数据设定:系统通过按键设定阈值,也可以通过手机App远程设定。
- 模式切换:可以通过按键或者手机App实现自动/手动模式的切换。
- 手动模式:通过手机App远程控制风扇、加湿器、步进电机(窗户)
- 自动模式:检测的温度超过温度阈值自动打开风扇,反之关闭;检测到的环境湿度低于湿度阈值自动打开加湿器;检测到的烟雾浓度高于阈值会自动开启声光报警;检测到的PM2.5浓度高于阈值,自动开启风扇和窗户并声光报警;
- 历史数据记录:采集的传感器数据上传并记录在机智云平台,可以在云平台后台查看历 史数据(手机App不具备此功能)。
3.2元器件清单
- 主控STM32F103C8T6最小系统板
- 0.96OLED显示屏幕
- DHT11温湿度传感器
- MQ-2烟雾传感器
- PM2.5传感器
- ESPP8266联网
- 继电器+风扇
- 继电器+加湿器
- 步进电机
- 按键部分
四、主框图与软件流程图
主框图

流程图

五、硬件PCB展示

六、软件程序设计
#include "delay.h"
#include "sys.h"
#include "bmp.h"
#include "usart.h"
#include "dht11.h"
#include "control.h"
#include "adc.h"
#include "key.h"
#include "timer.h"
#include "oled.h"
#include "uln2003.h"
/**** 数据变量 ****/
int hum_door_value = 70; //湿度阈值
int smoke_door_value = 3000; //烟雾阈值
int temp_door_value = 30; //温度阈值
int light_door_value = 3000; //光照阈值
int pm25_door_value = 300; //pm2.5阈值
uint8_t water_status = 0; //加湿器状态
uint8_t wind_status = 0; //风扇状态
uint8_t curtain_status = 0; //窗帘状态
uint8_t curtain_flag = 0; //窗户控制
uint8_t auto_mode = 0; //自动模式开关 0关闭 1开启
/**** 菜单变量 ****/
uint8_t keu_num = 0; //按键赋值
uint8_t page_num = 1; //页面ID
uint8_t option = 0; //阈值选项
/**** 功能函数声明 ****/
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(); //第三屏显示内容
int main(void)
{
delay_init(); //系统延时函数初始化
OLED_Init(); //屏幕初始化
uart3_init(115200); //串口3初始化,波特率115200
uart1_init(115200); //串口1初始化,波特率115200
uart2_init(9600); //串口2初始化,波特率9600
DHT11_Init(); //DHT11温湿度初始化
Control_Init(); //声光报警,照明初始化
Adc_Init(); //烟雾浓度、pm2.5浓度、光照强度初始化
TIME_Config(); //定时器初始化
KEY_Init(); //按键初始化
PM25_Init(); //PM2.5led引脚初始化
Uln2003_Init(); //步进电机初始化
while(1)
{
if(Time_Period[1]>1000) //Time_Period[1] 在定时器中累加
{
get_all_sensor_data(); //传感器数据采集
Time_Period[1] = 0;
}
Key_event_handle(); //按键监测
if(page_num == 1){ //屏幕更新
OLED_Show_FirstPage();
}else if(page_num == 2){
OLED_Show_SecondPage();
}else if(page_num == 3){
OLED_Show_ThirdPage();
}
Sensor_Data_Handle(); //数据处理
}
}
void Key_event_handle(void)
{
keu_num = KEY_Scan(0); //按键扫描赋值
switch(keu_num)
{
case 1: //按键1按下
if(page_num==1){
page_num=2;
OLED_Clear();OLED_Show_SecondPage();
}else if(page_num==2){
option++;
if(option>4){
option=0;
page_num=3;
OLED_Clear();OLED_Show_ThirdPage();
}else OLED_Show_SecondPage();
}else if(page_num==3){
option++;
if(option>3){
option=0;
page_num=1;
OLED_Clear();OLED_Show_FirstPage();
}else OLED_Show_ThirdPage();
}
break;
case 2: //按键2按下
if(page_num==1){
auto_mode = 1;
}else if(page_num == 2){ //阈值选择
if(option==1)temp_door_value++;
else if(option==2)hum_door_value++;
else if(option==3)smoke_door_value+=25;
else if(option==4)pm25_door_value+=5;
}else if(page_num == 3){
if(auto_mode==0){
if(option==2){
Wind = 1;
wind_status = 1;
}else if(option==3){
Water = 1;
water_status = 1;
}
}
if(option==1){
curtain_flag=1;
curtain_status = 1;
}
}
break;
case 3: //按键3按下
if(page_num==1){
auto_mode = 0;
}else if(page_num == 2){ //阈值选择
if(option==1)temp_door_value--;
else if(option==2)hum_door_value--;
else if(option==3)smoke_door_value-=25;
else if(option==4)pm25_door_value-=5;
}else if(page_num == 3){
if(auto_mode==0){
if(option==2){
Wind = 0;
wind_status = 0;
}else if(option==3){
Water = 0;
water_status = 0;
}
}
if(option==1){
curtain_flag=1;
curtain_status = 0;
}
}
break;
case 4: //按键4按下
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); //获取光照强度
}
void Sensor_Data_Handle()
{
//自动模式
if(auto_mode == 1) //如果开启了自动模式则可以实现根据数据的自动控制
{
//温度或pm2.5浓度超过阈值,打开风扇通风
if(temp>temp_door_value||PM25_Value>pm25_door_value){
Wind = 1;
wind_status=1;
} else {
Wind = 0;
wind_status=0;
}
//烟雾浓度或pm2.5浓度超过阈值蜂鸣器报警
if(MQ_Value>smoke_door_value||PM25_Value>pm25_door_value){
Beep = 1;
} else {
Beep = 0;
}
//pm2.5浓度大于阈值打开窗户通风
if(PM25_Value>pm25_door_value){
if(curtain_status==0){
curtain_flag=1;
curtain_status=1;
}
}
//湿度低于阈值打开加湿器
if(hum<hum_door_value){
Water = 1;
water_status = 1;
} else {
Water = 0;
water_status = 0;
}
}else{
Beep = 0; //手动模式下,关闭蜂鸣器
}
//窗户开关控制
if(curtain_flag==1){
curtain_flag=0;
if(curtain_status==1){
Stepper_RotateByLoop(1,1,1);
}else{
Stepper_RotateByLoop(0,1,1);
}
}
}
/*
温(0) 湿(1) 度(2) 烟(3) 雾(4) 浓(5) 度(6) ℃(7) 自(8) 手(9) 动(10) 模(11) 式(12) 阈(13) 值(14) 空(15)
气(16) 质(17) 量(18) 光(19) 照(20) 强(21) 度(22) 窗(23) 户(24) 风(25) 扇(26) 加(27) 湿(28) 器(29) 开(30)
关(31)
*/
void OLED_Show_FirstPage(){
// OLED_Clear();
OLED_ShowChinese(16*0,0,0,16,1); // “温”
OLED_ShowChinese(16*1,0,2,16,1); // “度”
OLED_ShowChar(16*2,0,':',16,1); // “:”
OLED_ShowNum(16*2+8,0,temp,2,16,1); // temp
// OLED_ShowChinese(16*3+8,0,7,16,1); // “℃”
OLED_ShowChinese(16*4,0,1,16,1); // “湿”
OLED_ShowChinese(16*5,0,2,16,1); // “度”
OLED_ShowChar(16*6,0,':',16,1); // “:”
OLED_ShowNum(16*6+8,0,hum,2,16,1); // hum
// OLED_ShowChar(16*3+8,0,'%',16,1); // “:”
OLED_ShowChinese(16*0,16,19,16,1); //光
OLED_ShowChinese(16*1,16,20,16,1); //照
OLED_ShowChinese(16*2,16,21,16,1); //强
OLED_ShowChinese(16*3,16,22,16,1); //度
OLED_ShowChar(16*4,16,':',16,1); // “:”
OLED_ShowNum(16*4+8,16,Light_Value,4,16,1);
OLED_ShowString(16*0,32,"PM2.5:",16,1); // “:”
OLED_ShowNum(16*3,32,PM25_Value,4,16,1); // Soil_Value
OLED_ShowChinese(16*0,48,3,16,1); //空
OLED_ShowChinese(16*1,48,4,16,1); //气
OLED_ShowChinese(16*2,48,5,16,1); //质
OLED_ShowChinese(16*3,48,6,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,3,16,1); // “烟”
OLED_ShowChinese(16*1,32,4,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_ShowChinese(16*0,0,23,16,1); //窗
OLED_ShowChinese(16*1,0,24,16,1); //户
OLED_ShowChar(16*2,0,':',16,1);
if(curtain_status==1)OLED_ShowChinese(16*2+8,0,30,16,a); //开
else OLED_ShowChinese(16*2+8,0,31,16,a); //关
OLED_ShowChinese(16*0,16,25,16,1); //风
OLED_ShowChinese(16*1,16,26,16,1); //扇
OLED_ShowChar(16*2,16,':',16,1);
if(wind_status==1)OLED_ShowChinese(16*2+8,16,30,16,b); //开
else OLED_ShowChinese(16*2+8,16,31,16,b); //关
OLED_ShowChinese(16*0,32,27,16,1); //加
OLED_ShowChinese(16*1,32,28,16,1); //湿
OLED_ShowChinese(16*2,32,29,16,1); //器
OLED_ShowChar(16*3,32,':',16,1);
if(water_status==1)OLED_ShowChinese(16*3+8,32,30,16,c); //开
else OLED_ShowChinese(16*3+8,32,31,16,c); //关
OLED_Refresh();
}
七、项目资料包内容

资料获取:查看主页介绍“充哥单片机设计”
更多推荐




所有评论(0)