【STM32项目开源】基于STM32的工地环境监测系统

目录

一、设计背景和意义

1.1设计背景

1.2设计意义

二、实物效果展示

2.1实物图片

2.2实物演示视频

三、硬件功能简介

3.1项目功能详解

3.2元器件清单

四、主框图与软件流程图

五、硬件PCB展示

六、软件程序设计

七、项目资料包内容

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


一、设计背景和意义

1.1设计背景

近年来,随着城市化进程加快和基础设施建设的高速发展,城市施工工地数量显著增加。工地在建设过程中不可避免地会产生大量扬尘、噪声等污染物,对大气质量、城市环境和周边居民的日常生活构成了严重影响。尤其在气候干燥或风力较大的地区,工地扬尘问题尤为严重,不仅影响施工人员的身体健康,还对城市的整体空气质量造成了显著负面作用。与此同时,工地作业产生的持续噪声也给周边居民带来了噪声污染,成为亟需解决的环境管理问题。

1.2设计意义

从国家政策角度看,我国近年来高度重视环境污染治理。多项政策文件如《大气污染防治行动计划》《关于推进建筑施工扬尘治理的指导意见》等,均提出应加快工地环境监测与治理的智能化、数据化、实时化方向,推动传统施工模式向绿色低碳转型。在此背景下,开发一套集成多种环境监测功能、支持自动控制、可远程管理的监测系统,正是顺应政策趋势与行业发展的现实需求。

从技术层面看,课题所采用的STM32微控制器、PM2.5/噪声/温湿度传感器、ESP8266通信模块、物联网云平台(如机智云)等,都是当前物联网嵌入式系统设计中的常见组件。系统设计兼顾了传感、处理、通信与控制的完整闭环,具备典型的智能硬件应用结构,适合推广至其他类似场景,如工厂车间、仓储物流中心、学校实验区等,对提升环境安全水平具有较强的推广价值。

二、实物效果展示

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粉尘浓度超过阈值,自动开启风扇和加湿器;检测到噪声模拟值超过阈值,自动开启蜂鸣器报警;当环境温度过高自动开启加湿器。

3.2元器件清单

  1. 主控STM32F103C8T6最小系统板
  2. 0.96OLED显示屏幕
  3. ESP8266联网WiFi(ESP01S)
  4. DHT11温湿度传感器
  5. 噪声检测
  6. PM2.5粉尘浓度检测
  7. 继电器+加湿器
  8. 继电器+风扇
  9. 蜂鸣器
  10. 按键

四、主框图与软件流程图

主框图

流程图

五、硬件PCB展示

六、软件程序设计

cpp 复制代码
#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"
/****  数据变量  ****/
int humi_door = 70;   		//湿度阈值解析
int sound_door = 3000;		//噪声阈值解析
int temp_door = 40;    		//温度阈值解析
int pm25_door = 300;		//pm2.5阈值解析

int auto_mode = 0;  //auto_mode = 0;表示为手动模式
						//auto_mode = 1;表示为自动模式
int wind_status = 0;			//风扇状态
int water_status = 0;			//加湿器状态

uint8_t beep_flag= 0;

/****  菜单变量  ****/
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引脚初始化
	while(1)	
	{
		if(Time_Period[1]>1000)		//Time_Period[1] 在定时器中累加
		{
			get_all_sensor_data();	//传感器数据采集
			Time_Period[1] = 0;
		}	     
		if(page_num == 1){			//屏幕更新
			OLED_Show_FirstPage();
		}else if(page_num == 2){
			OLED_Show_SecondPage();
		}else if(page_num == 3){
			OLED_Show_ThirdPage();
		}

		Key_event_handle();			//按键监测
		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>2){
					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++;
				else if(option==2)humi_door++;
				else if(option==3)sound_door+=15;
				else if(option==4)pm25_door+=5;
			}else if(page_num == 3){
				if(auto_mode==0){
					if(option==1){
						Wind = 1;
						wind_status = 1;
					}else if(option==2){
						Water = 1;
						water_status = 1;
					}
				}
			}
			break;
		case 3:		//按键3按下
			if(page_num==1){
				auto_mode = 0;
			}else if(page_num == 2){		//阈值选择
				if(option==1)temp_door--;
				else if(option==2)humi_door--;
				else if(option==3)sound_door-=15;
				else if(option==4)pm25_door-=5;
			}else if(page_num == 3){
				if(auto_mode==0){
					if(option==1){
						Wind = 0;
						wind_status = 0;
					}else if(option==2){
						Water = 0;
						water_status = 0;
					}
				}
			}
			break;
		case 4:		//按键4按下

			break;
	}
}

void get_all_sensor_data()
{
	DHT11_Read_Data(&temp,&hum);    //获取温湿度数据
	Get_Sound_Value(&Sound_Value);  //获取烟雾数据
	Get_PM25_Value(&PM25_Value);	//获取PM2.5,粉尘浓度
}


void Sensor_Data_Handle()
{
	//自动模式
	if(auto_mode == 1)  //如果开启了自动模式则可以实现根据数据的自动控制
	{
		//温度、pm2.5粉尘浓度超过阈值打开加湿器
		if(PM25_Value>pm25_door||temp>temp_door){
			Water = 1;
			water_status = 1;
		} else {
			Water = 0;
			water_status = 0;
		}
		//pm2.5粉尘浓度超过阈值打开风扇
		if(PM25_Value>pm25_door){
			Wind = 1;
			wind_status = 1;
		} else {
			Wind = 0;
			wind_status = 0;
		}
		//噪声超过阈值,蜂鸣器报警提醒
		if(Sound_Value>sound_door){
			beep_flag = 1;
		}		
		
	}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) 甲(23) 烷(24) 风(25) 扇(26) 加(27) 湿(28) 器(29) 开(30)
 关(31) 噪(32) 声(33) 值(34)
*/
void OLED_Show_FirstPage(){

	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*0,16,1,16,1);		//	"湿"
	OLED_ShowChinese(16*1,16,2,16,1);		//	"度"
	OLED_ShowChar(16*2,16,':',16,1);		//	":"     
	OLED_ShowNum(16*2+8,16,hum,2,16,1);		//	hum
	OLED_ShowString(16*3+8,16,"%RH",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,32,16,1);		//噪
	OLED_ShowChinese(16*1,48,33,16,1);		//声
	OLED_ShowChinese(16*2,48,34,16,1);		//值
	OLED_ShowChar(16*3,48,':',16,1);		//	":"
	OLED_ShowNum(16*3+8,48,Sound_Value,4,16,1);	//	Soil_Value

	if(auto_mode == 1){
		OLED_ShowChinese(16*6,0,8,16,1);			//	"自"
		OLED_ShowChinese(16*7,0,10,16,1);			//	"动"
	}else if(auto_mode == 0){
		OLED_ShowChinese(16*6,0,9,16,1);			//	"手"
		OLED_ShowChinese(16*7,0,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,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,humi_door,3,16,b);		//	hum_door_value

	OLED_ShowChinese(16*0,32,32,16,1);		//	"噪"
	OLED_ShowChinese(16*1,32,33,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,sound_door,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,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,25,16,1);	//风
	OLED_ShowChinese(16*1,0,26,16,1);	//扇
	OLED_ShowChar(16*2,0,':',16,1);		
	if(wind_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,27,16,1);	//加
	OLED_ShowChinese(16*1,16,28,16,1);	//湿
	OLED_ShowChinese(16*2,16,29,16,1);	//器
	OLED_ShowChar(16*3,16,':',16,1);		
	if(water_status==1)OLED_ShowChinese(16*3+8,16,30,16,b);	//开
	else OLED_ShowChinese(16*3+8,16,31,16,b);	//关

	OLED_Refresh();
}

七、项目资料包内容

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

相关推荐
速易达网络4 小时前
树莓派点亮LED灯
单片机·嵌入式硬件
straw_hat.4 小时前
PCB学习——STM32F103VET6-STM32主控部分
stm32·嵌入式硬件·学习
hazy1k6 小时前
K230基础-显示画面
stm32·单片机·嵌入式硬件·k230
A9better12 小时前
嵌入式开发学习日志31——stm32之外部中断与定时器中断的差别与选择
stm32·单片机·学习
沐欣工作室_lvyiyi12 小时前
基于物联网的个人健康管理系统(论文+源码)
单片机·物联网·毕业设计·健康管理
蒋楼丶13 小时前
stm32和Zynq的中断抢占机制
stm32·单片机·嵌入式硬件
xyx-3v13 小时前
已知三极管的类型(NPN/PNP)和基极引脚,如何区分集电极(c)和发射极(e)
单片机·嵌入式硬件·学习
随机惯性粒子群14 小时前
STM32控制开发学习笔记【基于STM32 HAL库】
笔记·stm32·嵌入式硬件·学习
来生硬件工程师15 小时前
CH582 GPIO
c语言·开发语言·单片机