目录

一、设计背景和意义

1.1设计背景

1.2设计意义

二、实物效果展示

2.1实物图片

2.2实物演示视频

三、硬件功能简介

3.1项目功能详解

3.2元器件清单

四、主框图与软件流程图

五、硬件PCB展示

六、软件程序设计

七、项目资料包内容

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


一、设计背景和意义

1.1设计背景

        随着城市化进程的加快和人们生活节奏的加快,居住环境的安全性、舒适性与智能化水平日益成为公众关注的焦点。家庭作为人们日常生活最主要的空间,其环境质量直接关系到居民的身体健康和生活质量。大量研究表明,室内空气污染物(如PM2.5、可燃性气体、烟雾等)对人体健康危害极大,尤其对儿童、老人、孕妇及呼吸系统疾病患者影响更为明显。此外,温度和湿度的不合理也容易引发不适甚至诱发疾病。在这种背景下,建设一个能够实时监测家庭环境、智能识别风险并自动联动处理的系统显得尤为重要。

        传统的家庭环境监控设备往往存在功能单一、价格昂贵、缺乏远程控制能力、无法个性化配置等诸多问题,无法满足普通用户对高性价比、可拓展、智能化环境控制系统的需求。尤其是在现今物联网技术迅猛发展的背景下,越来越多的用户希望通过智能手机远程查看家庭环境状况,甚至实现自动响应与干预。因此,将嵌入式系统、无线通信技术与云平台管理结合,构建一个功能集成、操作简便、具备自动响应能力的家庭环境检测系统,具有广阔的应用前景和研究价值。        

1.2设计意义

        本课题基于STM32F103C8T6单片机,结合DHT11温湿度传感器、PM2.5空气质量传感器、MQ-2烟雾传感器等环境采集模块,能够实现对家庭环境的全面监控。同时,结合ESP8266 WiFi模块接入“机智云”平台,使用户能够通过手机APP远程查看当前环境数据,控制风扇、加湿器、步进电机和声光报警等设备。在自动模式下,系统还可根据设定阈值实现智能判断与响应,无需人工干预,从而有效提升家庭环境的安全性与舒适性。

        本课题的研究不仅具备明确的现实意义,还具有良好的技术引导价值。一方面,它通过综合应用嵌入式开发、传感器技术、通信协议、云平台交互等知识体系,全面锻炼了学生的工程实践能力与系统集成能力;另一方面,它紧密结合智能家居、物联网等前沿热点,为今后从事智能控制系统开发、环境感知系统设计等方向奠定良好基础。因此,该课题既契合当前社会发展对智慧生活的需求,又贴合计算机专业本科毕业设计对综合能力培养的目标,是一个具有理论价值与实践意义的研究项目。

二、实物效果展示

2.1实物图片

2.2实物演示视频

【STM32开源】智能家庭环境监测系统

三、硬件功能简介

3.1项目功能详解

  1. 传感器检测:检测烟雾、PM2.5、温湿度等等数据
  2. 数据显示:0.96OLED屏幕显示全部的传感器数据以及传感器的阈值等数据。
  3. 执行机构:控制风扇、加湿器、步进电机(窗户)
  4. 接入云平台:系统通过ESP8266 WIFI联网后,接入机智云平台。
  5. App远程监控:通过App远程监控全部传感器数据
  6. 阈值数据设定:系统通过按键设定阈值,也可以通过手机App远程设定。
  7. 模式切换:可以通过按键或者手机App实现自动/手动模式的切换。
  8. 手动模式:通过手机App远程控制风扇、加湿器、步进电机(窗户)
  9. 自动模式:检测的温度超过温度阈值自动打开风扇,反之关闭;检测到的环境湿度低于湿度阈值自动打开加湿器;检测到的烟雾浓度高于阈值会自动开启声光报警;检测到的PM2.5浓度高于阈值,自动开启风扇和窗户并声光报警;
  10. 历史数据记录:采集的传感器数据上传并记录在机智云平台,可以在云平台后台查看历  史数据(手机App不具备此功能)。

3.2元器件清单

  1. 主控STM32F103C8T6最小系统板
  2. 0.96OLED显示屏幕
  3. DHT11温湿度传感器
  4. MQ-2烟雾传感器
  5. PM2.5传感器
  6. ESPP8266联网
  7. 继电器+风扇
  8. 继电器+加湿器
  9. 步进电机
  10. 按键部分

四、主框图与软件流程图

主框图

流程图

五、硬件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();
}

七、项目资料包内容

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

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐