当前位置: 首页 > news >正文

【STM32项目开源】基于STM32的智能家居环境(空气质量)检测系统

目录

一、设计背景和意义

1.1设计背景

1.2设计意义

二、实物效果展示

2.1实物图片

2.2实物演示视频

三、硬件功能简介

3.1项目功能详解

3.2元器件清单

四、主框图与软件流程图

五、硬件PCB展示

六、软件程序设计

七、项目资料包内容

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


一、设计背景和意义

1.1设计背景

        近年来,随着城市化进程加快以及工业活动日益频繁,环境污染问题日益严重,尤其是在空气质量方面的隐患愈发突出。诸如PM2.5颗粒物、二氧化碳、甲醛、氨气等有害气体的浓度升高,不仅影响人们的日常生活与工作效率,更对人体健康构成了潜在威胁。同时,随着人们生活品质的不断提升,公众对于居住和工作环境中的空气质量、温湿度、光照等指标提出了更高要求。传统的环境检测手段多依赖人工采集或单一传感器监测,存在信息滞后、响应不及时、功能单一和缺乏远程交互等显著不足,难以满足现代社会“智能化”“互联化”的发展趋势。

1.2设计意义

        本课题的研究不仅有助于提高环境感知技术在智能家居场景中的普及度与实用性,也为计算机与电子信息工程专业学生提供一个涵盖嵌入式开发、传感器应用、物联网通信与云平台交互的综合实践平台。其实现过程充分锻炼了项目分析、系统设计、软硬件调试、逻辑控制与通信编程等多方面能力,具有重要的学习价值与推广意义。未来,该系统还可根据需求扩展更多功能,如数据可视化分析、联动控制多种设备,为构建更加智能、绿色、安全的室内环境提供可行技术路径与应用基础。

二、实物效果展示

2.1实物图片

2.2实物演示视频

【开源】基于STM32的智能环境监测系统

三、硬件功能简介

3.1项目功能详解

1)传感器检测:空气质量、光照强度、温湿度、PM2.5粉尘传感器、CO2浓度传感器
2)数据显示:0.96OLED屏幕
3)执行机构:控制风扇、声光报警
4)接入云平台:系统通过ESP8266 WIFI联网后,接入机智云平台
5)App远程监控:通过App远程监控全部传感器数据
6)阈值设定:系统通过按键设定阈值,也可以通过手机App远程设定
7)自动模式:当空气质量、PM2.5、CO2、温湿度等数据超过阈值,自动打开风扇并且开启声光报警

3.2元器件清单

  1. 主控STM32F103C8T6最小系统板
  2. OLED显示屏幕
  3. ESP8266联网WiFi模块
  4. DHT11温湿度传感器
  5. MQ-135空气质量传感器
  6. PM2.5粉尘颗粒传感器
  7. 光敏电阻光照传感器
  8. JW01`二氧化碳传感器
  9. 蜂鸣器
  10. 继电器+风扇
  11. 按键

四、主框图与软件流程图

主框图

流程图

五、硬件PCB展示

六、软件程序设计

#include "sys.h"
#include "delay.h"
#include "adc.h"
#include "gpio.h"
#include "OLED_I2C.h"
#include "timer.h"
#include "MQ7.h"
#include "dht11.h"
#include "esp8266.h"
#include "usart2.h"
#include "usart3.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>#define STM32_RX2_BUF       Usart2RecBuf          //串口2接收缓存区
#define STM32_Rx2Counter    Rx2Counter           //串口2接收字节计数
#define STM32_RX2BUFF_SIZE  USART2_RXBUFF_SIZE   //串口2接收缓存大小#define STM32_RX3_BUF       Usart3RecBuf        //串口3接收缓存区
#define STM32_Rx3Counter    Rx3Counter          //串口3接收字节计数
#define STM32_RX3BUFF_SIZE  USART3_RXBUFF_SIZE  //串口3接收缓存大小#define  RATIO  1.0		   //校准系数,选择范围0.1~1.0 (传感器一般不需要校准,选择1.0即可)
u16 PM25_Value = 0;     		//PM2.5
u16 PM25_Value_max = 200;  //PM2.5报警值
u8 pmBuf[5];               //pm2.5数据缓存数组
u8 ch2oBuf[8];            //甲醛数据缓存数组char display[16];
unsigned char setn=0;                //记录设置键按下的次数
unsigned char temperature=0;         //温度变量
unsigned char humidity=0;            //湿度变量
unsigned int  CH2O_mgvalue = 0;      //甲醛变量
unsigned char setTempValue=35;        //温度设置值
unsigned char setHumiValue=75;        //湿度设置值
unsigned int setCH2OValue=10;        //甲醛设置值
unsigned char i=0;unsigned int  co_ppm = 0;                //co值
unsigned int setCoMaxValue=200;          //CO上限bool shuaxin  = 1;              //刷新数据标志
bool shanshuo = 0;              //液晶闪烁标志
bool sendFlag = 1;              //串口发送数据标志void displayOriginalInt(void)  //显示原始页面
{for(i=0;i<2;i++)OLED_ShowCN(i*16+0,0,i+18,0);//显示中文:温度for(i=0;i<2;i++)OLED_ShowCN(i*16+71,0,i+20,0);//显示中文:湿度for(i=0;i<4;i++)OLED_ShowCN(i*16+0,6,i+24,0);//显示中文:一氧化碳for(i=0;i<2;i++)OLED_ShowCN(i*16+0,4,i+4,0);//显示中文:甲醛OLED_ShowStrPm(0, 2, 2,0);OLED_ShowStr(16, 2, "2.5:", 2,0);OLED_ShowChar(64,6,':',2,0);OLED_ShowChar(32,4,':',2,0);OLED_ShowCentigrade(48, 0,0);OLED_ShowChar(119,0,'%',2,0);
}void displaySetValue(void)  //显示设置的值
{if(setn == 1){/*显示温度上限*/OLED_ShowChar(52,4,setTempValue/10+'0',2,0);OLED_ShowChar(60,4,setTempValue%10+'0',2,0);OLED_ShowCentigrade(70, 4,0);}if(setn == 2){/*显示湿度上限*/OLED_ShowChar(52,4,setHumiValue/10+'0',2,0);OLED_ShowChar(60,4,setHumiValue%10+'0',2,0);OLED_ShowChar(68,4,'%',2,0);OLED_ShowChar(76,4,' ',2,0);}if(setn == 3){/*显示甲醛上限*/sprintf(display,"%4.2fmg/m3",(float)setCH2OValue/100);OLED_ShowStr(28, 4, (u8 *)display, 2,0);}if(setn == 4){/*显示PM2.5上限*/sprintf(display,"%03dug/m3 ",PM25_Value_max);OLED_ShowStr(28, 4, (u8 *)display, 2,0);}if(setn == 5){/*显示CO上限*/sprintf(display," %dppm  ",setCoMaxValue); OLED_ShowStr(27, 4, (u8 *)display, 2,0);}
}void keyscan(void)   //按键扫描
{if(KEY1 == 0) //设置按键按下{delay_ms(20);if(KEY1 == 0){while(KEY1 == 0);BEEP=0;setn ++;if(setn == 1){OLED_CLS(0);              //清屏for(i=0;i<4;i++)OLED_ShowCN(i*16+32,0,i+6,0);//显示中文:设置温度		delay_ms(150);}if(setn == 2){for(i=0;i<4;i++)OLED_ShowCN(i*16+32,0,i+10,0);//显示中文:设置湿度  }if(setn == 3){for(i=0;i<4;i++)OLED_ShowCN(i*16+32,0,i+14,0);//显示中文:设置甲醛  }if(setn == 4){for(i=0;i<2;i++)OLED_ShowCN(i*16+24,0,i+14,0);//显示中文:设置OLED_ShowStrPm(56, 0, 2,0);OLED_ShowStr(72, 0, "2.5", 2,0);}if(setn == 5){for(i=0;i<6;i++)OLED_ShowCN(i*16+16,0,i+22,0);//显示中文:设置一氧化碳  }if(setn >= 6)   //设置按键按下6次,退出设置{setn = 0;OLED_CLS(0);              //清屏displayOriginalInt();     //显示主页}displaySetValue();            //显示设置的值}}if(KEY2 == 0) //加键按下{delay_ms(80);if(KEY2 == 0){if(setTempValue<99 && setn==1)setTempValue++;           //温度上限加if(setHumiValue<99 && setn==2)setHumiValue++;           //湿度上限加if(setCH2OValue<999 && setn==3)setCH2OValue++;          //甲醛上限加if(PM25_Value_max<999 && setn==4)PM25_Value_max++;	    //PM2.5上限加if(setCoMaxValue<1000 && setn==5)setCoMaxValue++;       //一氧化碳上限加displaySetValue();                                      //显示设置的值}}if(KEY3 == 0) //减键按下{delay_ms(80);if(KEY3 == 0){if(setTempValue>0 && setn==1)setTempValue--;                //温度上限减if(setHumiValue>0 && setn==2)setHumiValue--;                //湿度上限减if(setCH2OValue>0 && setn==3)setCH2OValue--;                //甲醛上限减if(PM25_Value_max>0 && setn==4)PM25_Value_max--;	        //pm2.5上限减if(setCoMaxValue>0 && setn==5)setCoMaxValue--;              //一氧化碳上限减displaySetValue();                                          //显示设置的值}}
}void UsartSendReceiveData(void)               //串口发送和接收数据,用于和手机APP通信
{unsigned char *dataPtr = NULL;char *str1=0,i;int  setValue=0;char setvalue[5]={0};char SEND_BUF[200];            //发送数据缓存char TEMP_BUF[100];           //临时缓存数组dataPtr = ESP8266_GetIPD(0);   //接收数据if(dataPtr != NULL)           //手机端下发了数据{if(strstr((char *)dataPtr,"temp_max:")!=NULL)    //接收到设置温度上限的指令{BEEP = 1;delay_ms(80);BEEP = 0;str1 = strstr((char *)dataPtr,"temp_max:");while(*str1 < '0' || *str1 > '9')    //判断是不是0到9有效数字{str1 = str1 + 1;delay_ms(10);}i = 0;while(*str1 >= '0' && *str1 <= '9')        //判断是不是0到9有效数字{setvalue[i] = *str1;i ++; str1 ++;if(*str1 == ',')break;            //换行符,直接退出while循环delay_ms(10);}setvalue[i] = '\0';            //加上结尾符setValue = atoi(setvalue);if(setValue>=0 && setValue<=99){setTempValue=setValue;            //设置温度上限displaySetValue();                //显示设置的值}} if(strstr((char *)dataPtr,"humi_max:")!=NULL)       //接收到设置湿度上限的指令{str1 = strstr((char *)dataPtr,"humi_max:");while(*str1 < '0' || *str1 > '9')    //判断是不是0到9有效数字{str1 = str1 + 1;delay_ms(10);}i = 0;while(*str1 >= '0' && *str1 <= '9')        //判断是不是0到9有效数字{setvalue[i] = *str1;i ++; str1 ++;if(*str1 == ',')break;          //换行符,直接退出while循环delay_ms(10);}setvalue[i] = '\0';            //加上结尾符setValue = atoi(setvalue);if(setValue>=0 && setValue<=99){setHumiValue=setValue;        //设置湿度上限displaySetValue();            //显示设置的值}}if(strstr((char *)dataPtr,"chIIo:")!=NULL)  //接收到设置甲醛上限的指令{str1 = strstr((char *)dataPtr,"chIIo:");while(*str1 < '0' || *str1 > '9')        //判断是不是0到9有效数字{str1 = str1 + 1;delay_ms(10);}i = 0;while(*str1 >= '0' && *str1 <= '9')        //判断是不是0到9有效数字{setvalue[i] = *str1;str1 ++;i ++;if(*str1 == '.')break;          //小数点,直接退出while循环delay_ms(10);}if(*str1 == '.'){str1 = str1 + 1;}while(*str1 >= '0' && *str1 <= '9'){setvalue[i] = *str1;i ++; str1 ++;}setvalue[i] = '\0';            //加上结尾符setValue = atoi(setvalue);if(i==2)setValue=setValue*10;if(i==1)setValue=setValue*100;if(setValue>=0 && setValue<=999){setCH2OValue = setValue;    //设置的甲醛上限displaySetValue();          //显示设置的值}}if(strstr((char *)dataPtr,"pm_max:")!=NULL)    //接收到设置pm2.5的指令{str1 = strstr((char *)dataPtr,"pm_max:");while(*str1 < '0' || *str1 > '9')    //判断是不是0到9有效数字{str1 = str1 + 1;delay_ms(10);}i = 0;while(*str1 >= '0' && *str1 <= '9')        //判断是不是0到9有效数字{setvalue[i] = *str1;i ++; str1 ++;if(*str1 == '\r')break;            //换行符,直接退出while循环delay_ms(10);}setvalue[i] = '\0';            //加上结尾符setValue = atoi(setvalue);if(setValue>=0 && setValue<=999){PM25_Value_max=setValue;           //设置pm2.5displaySetValue();                 //显示设置的值}}if(strstr((char *)dataPtr,"co_max:")!=NULL)    //接收到设置CO上限的指令{str1 = strstr((char *)dataPtr,"co_max:");while(*str1 < '0' || *str1 > '9')    //判断是不是0到9有效数字{str1 = str1 + 1;delay_ms(10);}i = 0;while(*str1 >= '0' && *str1 <= '9')        //判断是不是0到9有效数字{setvalue[i] = *str1;i ++; str1 ++;if(*str1 == ',')break;         //换行符,直接退出while循环delay_ms(10);}setvalue[i] = '\0';            //加上结尾符setValue = atoi(setvalue);if(setValue>=0 && setValue<=1000){setCoMaxValue=setValue;   //设置CO上限displaySetValue();         //显示设置的值}}ESP8266_Clear();									//清空缓存}if(sendFlag==1)    //800ms上传一次数据{sendFlag = 0;		memset(SEND_BUF,0,sizeof(SEND_BUF));   			//清空缓冲区memset(TEMP_BUF,0,sizeof(TEMP_BUF));   			//清空缓冲区if(temperature>=setTempValue)strcat(SEND_BUF,"temp_warn,");  if(humidity>=setHumiValue)strcat(SEND_BUF,"humi_warn,");        if(PM25_Value>=PM25_Value_max)strcat(SEND_BUF,"pm2.5_warn,");           if((CH2O_mgvalue/10)>=setCH2OValue)strcat(SEND_BUF,"ch2o_warn,");       if(co_ppm>=setCoMaxValue)strcat(SEND_BUF,"co_warn,");                sprintf(TEMP_BUF,"$temp:%d#,$humi:%d#,$ch2o:%.3f#,$pm2.5:%d#,$co:%d#",temperature,humidity,(float)CH2O_mgvalue/1000,PM25_Value,co_ppm);//发送的数据装载:温度,湿度,甲醛,PM2.5,costrcat(SEND_BUF,TEMP_BUF);ESP8266_SendData((u8 *)SEND_BUF, strlen(SEND_BUF));   //ESP8266模块发送数据到手机端ESP8266_Clear();                                     //清除接收数据的缓存}
}int main(void)
{u16 timeCount=200;bool delay_600ms=1;delay_init();	           //延时函数初始化	 NVIC_Configuration();	   //中断优先级配置KEY_GPIO_Init();        //按键引脚初始化 delay_ms(300); I2C_Configuration();     //IIC初始化OLED_Init();             //OLED液晶初始化OLED_CLS(0);              //清屏KEY_GPIO_Init();        //按键引脚初始化    OLED_ShowStr(0, 2, "   loading...   ", 2,0);//显示加载中while(DHT11_Init()){OLED_ShowStr(0, 2, "  DHT11 Init!  ", 2,0);//显示DHT11初始化!delay_ms(500);}ESP8266_Init();       //ESP8266初始化	delay_ms(1000);Adc_Init();          //ADC初始化OLED_CLS(0);              //清屏USART2_Init(9600);       //串口2初始化USART3_Init(9600);       //串口3初始化displayOriginalInt();   //显示原始界面TIM3_Init(99,719);   //定时器初始化,定时1ms//Tout = ((arr+1)*(psc+1))/Tclk ; //Tclk:定时器输入频率(单位MHZ)//Tout:定时器溢出时间(单位us)while(1){ keyscan();  //按键扫描if(setn == 0)     //不在设置状态下{timeCount ++;if(timeCount >= 180){timeCount = 0;DHT11_Read_Data(&temperature,&humidity);   //读取温湿度}if(shuaxin == 1)        //大概300ms刷新一下{ shuaxin = 0;delay_600ms = !delay_600ms;if(temperature>=setTempValue && shanshuo)    //温度超过上限,液晶闪烁显示{OLED_ShowChar(32,0,' ',2,0);OLED_ShowChar(40,0,' ',2,0);}else{OLED_ShowChar(32,0,temperature/10+'0',2,0);    //显示温度OLED_ShowChar(40,0,temperature%10+'0',2,0);}if(humidity>=setHumiValue && shanshuo)        //湿度超过上限,液晶闪烁显示{OLED_ShowChar(103,0,' ',2,0);OLED_ShowChar(111,0,' ',2,0);}else{OLED_ShowChar(103,0,humidity/10+'0',2,0);      //显示湿度OLED_ShowChar(111,0,humidity%10+'0',2,0);}Get_MQ7_PPM();   //读取一氧化碳值Get_CH2O();      //读取甲醛if((CH2O_mgvalue/10)>=setCH2OValue && shanshuo)//甲醛超过上限,液晶闪烁显示{OLED_ShowStr(46, 4, "     mg/m3", 2,0);} else {sprintf(display,"%.3fmg/m3",(float)CH2O_mgvalue/1000); OLED_ShowStr(46, 4, (u8 *)display, 2,0);       //显示甲醛}if(delay_600ms) {Get_PM2_5();            //读取PM2.5if(PM25_Value>999)PM25_Value=999;}if(PM25_Value>=PM25_Value_max && shanshuo)    //pm2.5超过上限,液晶闪烁显示{OLED_ShowStr(56, 2, "   ug/m3", 2,0);}  else {sprintf(display,"%03dug/m3",PM25_Value);OLED_ShowStr(56, 2, (u8 *)display, 2,0);    //显示PM2.5}if(temperature>=setTempValue || humidity>=setHumiValue || (CH2O_mgvalue/10)>=setCH2OValue || PM25_Value>=PM25_Value_max || co_ppm>=setCoMaxValue){BEEP = 1; RELAY=1;}   //超出上限,蜂鸣器提醒。开启风扇else{BEEP = 0; RELAY=0;}   //关闭风扇和蜂鸣器}}UsartSendReceiveData();   //串口发送接收数据,用于和手机APP通信delay_ms(10);}
}

七、项目资料包内容

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

http://www.dtcms.com/a/453226.html

相关文章:

  • Photoshop - Photoshop 工具栏(8)魔棒工具
  • 虹口专业做网站wordpress分类目录第二页
  • 保险业多模态数据融合与智能化运营架构:技术演进、应用实践与发展趋势
  • AI大模型微调教程7
  • Docker 完整教程(5,6) | 容器编译与编排
  • 网站模板 外贸工厂济宁网站建设是什么
  • pyautocad 发送消息到消息栏 acad.doc.Utility.Prompt
  • 【传奇开心果系列】基于Flet框架实现的分析题型的掌握程度不同题型得分饼图样式示例自定义模板特色和实现原理深度解析
  • 做网站怎么防止被网警查到wordpress 设置登陆
  • 部署MySql8.4.6(Kylinv10sp3、Ubuntu2204、Rocky9.3)
  • 高并发下如何保证 Caffeine + Redis 多级缓存的一致性问题?MySQL、Redis 缓存一致性问题?
  • 吉林省建设厅网站评职称系统手机装wordpress
  • LeetCode 分类刷题:1901. 寻找峰值 II
  • ROS实战中Gazebo的基本使用
  • wordpress网站维护教程wordpress修改管理密码
  • PTA6-1 使用函数求最大公约数(C)
  • 小谈:数字化项目立项成功的方法论
  • HTTPS 真的牢不可破吗?—— 中间人攻击与安全机制解析
  • 广东省城乡建设厅网站seo短视频新地址在哪里?
  • 从 0 到 1 搭建 Python 语言 Web UI自动化测试学习系列 9--基础知识 5--常用函数 3
  • 然后在亚马逊网站上做外贸做网站需要做数据库
  • 接口测试-Postman 断言
  • 网站关键词更换了专业网站建设 公司哪家好
  • 乐观锁 与 悲观锁 笔记251007
  • Linux中select的实现
  • /UI2/CL_JSON=>DESERIALIZE :JSON反序列化
  • MySQL主主复制+Keepalived高可用集群搭建与故障切换实战
  • 幼儿网站源代码室内设计案例去什么网站
  • Spring Framework源码解析——BeanFactoryAware
  • Linux系统--进程通信初解