目录
一、设计背景和意义
1.1设计背景
近年来,随着城市化进程加快和基础设施建设的高速发展,城市施工工地数量显著增加。工地在建设过程中不可避免地会产生大量扬尘、噪声等污染物,对大气质量、城市环境和周边居民的日常生活构成了严重影响。尤其在气候干燥或风力较大的地区,工地扬尘问题尤为严重,不仅影响施工人员的身体健康,还对城市的整体空气质量造成了显著负面作用。与此同时,工地作业产生的持续噪声也给周边居民带来了噪声污染,成为亟需解决的环境管理问题。
1.2设计意义
从国家政策角度看,我国近年来高度重视环境污染治理。多项政策文件如《大气污染防治行动计划》《关于推进建筑施工扬尘治理的指导意见》等,均提出应加快工地环境监测与治理的智能化、数据化、实时化方向,推动传统施工模式向绿色低碳转型。在此背景下,开发一套集成多种环境监测功能、支持自动控制、可远程管理的监测系统,正是顺应政策趋势与行业发展的现实需求。
从技术层面看,课题所采用的STM32微控制器、PM2.5/噪声/温湿度传感器、ESP8266通信模块、物联网云平台(如机智云)等,都是当前物联网嵌入式系统设计中的常见组件。系统设计兼顾了传感、处理、通信与控制的完整闭环,具备典型的智能硬件应用结构,适合推广至其他类似场景,如工厂车间、仓储物流中心、学校实验区等,对提升环境安全水平具有较强的推广价值。
二、实物效果展示
2.1实物图片

2.2实物演示视频
【开源】基于STM32的工地环境监测系统
三、硬件功能简介
3.1项目功能详解
- 传感器数据:工地环境温湿度、PM2.5粉尘颗粒浓度、噪声检测
- 数据显示:0.96OLED显示屏
- 执行机构:通风扇、加湿器
- 接入云平台:通过ESP8266 WIFI联网后,接入机智云平台
- App远程监控:App远程监控数据,控制执行机构
- 阈值设定:按键或APP设定阈值
- 模式切换:按键或App实现自/手动模式的切换
- 手动模式:通过手机App或者按键控制电风扇、加湿器
- 自动模式:检测到PM2.5粉尘浓度超过阈值,自动开启风扇和加湿器;检测到噪声模拟值超过阈值,自动开启蜂鸣器报警;当环境温度过高自动开启加湿器。
3.2元器件清单
- 主控STM32F103C8T6最小系统板
- 0.96OLED显示屏幕
- ESP8266联网WiFi(ESP01S)
- DHT11温湿度传感器
- 噪声检测
- PM2.5粉尘浓度检测
- 继电器+加湿器
- 继电器+风扇
- 蜂鸣器
- 按键
四、主框图与软件流程图
主框图

流程图

五、硬件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();
}
七、项目资料包内容
