基于stm32设计的环境检测设备

DS小龙哥      2022-02-16     563

关键词:

1. 前言

随着人们生活质量的提高,对于生活环境的问题,人们的关注度进一步提高,同时政府部门采取了许多措施来改善环境状况。但是总体上来说我国的环境监测技术水平比较落后,传统上的监测手段比较单一,监测数据也不够准确,耗尽了大量的人力和财力,却成效不高。

针对上述缺点,当前文章综合了嵌入式处理技术、传感器技术、无线网络通信等技术,设计了一个基于STM32的无线环境监测系统,系统主要实现了对湿度、温度、有毒气体、烟雾浓度、空气质量等参数进行实时监测的功能。为了实现无线数据传输功能,采用了无线wifi技术。系统的测试分析表明系统整体数据采集性能良好,数据传输稳定性可靠,到达了预期目标。

系统与传统的监测技术相比,具有监测数据准确,监测范围广,智能化高等特点。且系统具有一定的创新性,在实际的工程运用和理论研究上体现出了一定的研究价值最后通过实物的调试,各项参数及功能符合设计要求,能达到预期的目的。

设计以STM32微控制器为平台,采用DHT11温湿度传感器、烟雾传感器MQ-2、易燃气体传感器MQ-4、空气质量检测传感器MQ-135对室内温湿度和危险气体进行采集。通过wifi无线网络将数据传送给微控制器,STM32微控制器处理数据后,由自带oled液晶屏显示。当室内温度达到预警值或有危险气体时,系统将会自动警报并将警报信息通过wifi网络传输给客户手机。且每隔一段时间会通过wifi自动发送监测信息到手机,从而实现对室内环境的监测及报警功能。

软件源码完整下载地址: 基于STM32设计的环境监测项目源码.zip_stm32f103zet6项目-嵌入式文档类资源-CSDN下载

视频演示地址: 基于STM32设计的环境监测项目-CSDN直播

基于STM32设计的环境监测项目

2. 实现功能与整体框架图

开发板采用STM32最小系统板,主控CPU采用STM32F103C8T6,其他传感器采用模块的形式连接到开发板。

主要实现以下功能实现: 1、通过DHT11温湿度传感器、烟雾传感器MQ-2、易燃气体传感器MQ-4、空气质量检测传感器MQ-135对室内温湿度和危险气体进行采集。 2、通过传感器用ADC模拟数字的转换,采集到的数据显示在oled屏幕上。 3、当检测到的数据超过设定的安全值时,屏幕上会显示警报。 4、检测到的数据能定时通过ESP8266 wifi无线传输发送到所连接的用户的手机上,实现监测功能。

系统框架图如下:

3. 硬件特点介绍

(1) 温湿度传感器 温湿度传感器采用DHT11,这是一款直接输出数字信号的温湿度传感器;其精度湿度±5%RH, 温度±2℃,量程湿度5~95%RH, 温度-20~+60℃。通过单总线时序输出,占用的IO口也比较少,工作电压3V~5V,单片机连接控制很方便。

(2) MQ系列的气体检测传感器 烟雾传感器MQ-2、易燃气体传感器MQ-4、空气质量检测传感器MQ-135,这些传感器都是输出模拟信号。 配置好STM32的ADC采集接口,采集数据进行处理即可。

(3) ESP8266 WIFI 联网的模块采用ESP8266 WIFI,ESP8266在物联网里使用非常多,有很多成熟的案例.WIFI本身也支持二次开发,默认集成的SDK支持AT指令控制,单片机可以通过串口方式控制ESP8266完成网络通信,非常方便.

(4) OLED显示屏 OLED显示屏采用中景园电子的0.96寸OLED,分辨率是128x64,使用的SPI引脚接口屏幕,刷屏速度很快,控制简单

(5) 上位机设计

手机APP和PC端没有单独设计精美的界面,只是简单的展示了数据显示。

4. 核心源码

4.1 DHT11温湿度代码

#include "dht11.h"
#include "delay.h"
​
//复位DHT11
void DHT11_Rst(void)       
                 
      DHT11_IO_OUT();   //SET OUTPUT
    DHT11_DQ_OUT=0;     //拉低DQ
    DelayMs(20);        //拉低至少18ms
    DHT11_DQ_OUT=1;     //DQ=1 
      delay_us(30);         //主机拉高20~40us

//等待DHT11的回应
//返回1:未检测到DHT11的存在
//返回0:存在
u8 DHT11_Check(void)       
   
    u8 retry=0;
    DHT11_IO_IN();//SET INPUT    
    while (DHT11_DQ_IN&&retry<100)//DHT11会拉低40~80us
    
        retry++;
        delay_us(1);
    ;   
    if(retry>=100)return 1;
    else retry=0;
    while (!DHT11_DQ_IN&&retry<100)//DHT11拉低后会再次拉高40~80us
    
        retry++;
        delay_us(1);
    ;
    if(retry>=100)return 1;     
    return 0;

//从DHT11读取一个位
//返回值:1/0
u8 DHT11_Read_Bit(void)              

    u8 retry=0;
    while(DHT11_DQ_IN&&retry<100)//等待变为低电平
    
        retry++;
        delay_us(1);
    
    retry=0;
    while(!DHT11_DQ_IN&&retry<100)//等待变高电平
    
        retry++;
        delay_us(1);
    
    delay_us(40);//等待40us
    if(DHT11_DQ_IN)return 1;
    else return 0;         

​
//从DHT11读取一个字节
//返回值:读到的数据
u8 DHT11_Read_Byte(void)    
        
    u8 i,dat;
    dat=0;
    for (i=0;i<8;i++) 
    
        dat<<=1; 
        dat|=DHT11_Read_Bit();
                               
    return dat;

​
​
//从DHT11读取一次数据
//temp:温度值(范围:0~50°)
//humi:湿度值(范围:20%~90%)
//返回值:0,正常;1,读取失败
u8 DHT11_Read_Data(u8 *temp,u8 *humi)    
        
    u8 buf[5];
    u8 i;
    DHT11_Rst();
    //printf("------------------------\r\n");
    if(DHT11_Check()==0)
    
        for(i=0;i<5;i++)//读取40位数据
        
            buf[i]=DHT11_Read_Byte();
        
        if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4])
        
            *humi=buf[0];
            *temp=buf[2];
        
    else return 1;
    return 0;       

​
​
//初始化DHT11的IO口 DQ 同时检测DHT11的存在
//返回1:不存在
//返回0:存在         
u8 DHT11_Init(void)

    RCC->APB2ENR|=1<<2;    //使能PORTG口时钟 
    GPIOA->CRL&=0XFF0FFFFF;//PORTG.11 推挽输出
    GPIOA->CRL|=0X00300000;
    GPIOA->ODR|=1<<5;      //输出1                    
    DHT11_Rst();
    return DHT11_Check();

4.2 ESP8266代码

#include "esp8266.h"
extern u8  USART3_RX_BUF[USART3_MAX_RECV_LEN];      //接收缓冲,最大USART3_MAX_RECV_LEN字节
extern u8  USART3_TX_BUF[USART3_MAX_SEND_LEN];      //发送缓冲,最大USART3_MAX_SEND_LEN字节
extern vu16 USART3_RX_STA;                                              //接收数据状态
​
/// 
//用户配置区
​
//连接端口号:8086,可自行修改为其他端口.
const u8 portnum[]="8089";       
​
//WIFI STA模式,设置要去连接的路由器无线参数,请根据你自己的路由器设置,自行修改.
const u8 wifista_ssid[]="wbyq1";            //路由器SSID号
const u8 wifista_encryption[]="wpa2_aes";   //wpa/wpa2 aes加密方式
const u8 wifista_password[]="123456789";    //连接密码
​
//WIFI AP模式,模块对外的无线参数,可自行修改.
const u8 wifiap_ssid[]="Cortex_M3";           //对外SSID号
const u8 wifiap_encryption[]="wpawpa2_aes"; //wpa/wpa2 aes加密方式
const u8 wifiap_password[]="12345678";        //连接密码 
​
​
/*
函数功能:向ESP82668266发送命令
函数参数:
                cmd:发送的命令字符串
                ack:期待的应答结果,如果为空,则表示不需要等待应答
                waittime:等待时间(单位:10ms)
返 回 值:
                 0,发送成功(得到了期待的应答结果)
         1,发送失败
*/
u8 ESP8266_SendCmd(u8 *cmd,u8 *ack,u16 waittime)

    u8 res=0; 
    USART3_RX_STA=0;
    UsartStringSend(USART3,cmd);//发送命令
    if(ack&&waittime)       //需要等待应答
    
        while(--waittime)   //等待倒计时
        
            DelayMs(10);
            if(USART3_RX_STA&0X8000)//接收到期待的应答结果
            
                if(ESP8266_CheckCmd(ack))
                
                    res=0;
                    //printf("cmd->ack:%s,%s\r\n",cmd,(u8*)ack);
                    break;//得到有效数据 
                
                    USART3_RX_STA=0;
             
        
        if(waittime==0)res=1; 
    
    return res;

​
​
/*
函数功能:ESP8266发送命令后,检测接收到的应答
函数参数:str:期待的应答结果
返 回 值:0,没有得到期待的应答结果
                 其他,期待应答结果的位置(str的位置)
*/
u8* ESP8266_CheckCmd(u8 *str)

    char *strx=0;
    if(USART3_RX_STA&0X8000)  //接收到一次数据了
     
        USART3_RX_BUF[USART3_RX_STA&0X7FFF]=0;//添加结束符
        strx=strstr((const char*)USART3_RX_BUF,(const char*)str); //查找是否应答成功
        printf("RX=%s",USART3_RX_BUF);
    
    return (u8*)strx;

​
/*
函数功能:向ESP8266发送指定数据
函数参数:
                data:发送的数据(不需要添加回车)
                ack:期待的应答结果,如果为空,则表示不需要等待应答
                waittime:等待时间(单位:10ms)
返 回 值:0,发送成功(得到了期待的应答结果)luojian
*/
u8 ESP8266_SendData(u8 *data,u8 *ack,u16 waittime)

    u8 res=0; 
    USART3_RX_STA=0;
    UsartStringSend(USART3,data);//发送数据
    if(ack&&waittime)       //需要等待应答
    
        while(--waittime)   //等待倒计时
        
            DelayMs(10);
            if(USART3_RX_STA&0X8000)//接收到期待的应答结果
            
                if(ESP8266_CheckCmd(ack))break;//得到有效数据 
                USART3_RX_STA=0;
             
        
        if(waittime==0)res=1; 
    
    return res;

    
    
​
/*
函数功能:ESP8266退出透传模式
返 回 值:0,退出成功;
         1,退出失败
*/
u8 ESP8266_QuitTrans(void)

    while((USART3->SR&0X40)==0);    //等待发送空
    USART3->DR='+';      
    DelayMs(15);                    //大于串口组帧时间(10ms)
    while((USART3->SR&0X40)==0);    //等待发送空
    USART3->DR='+';      
    DelayMs(15);                    //大于串口组帧时间(10ms)
    while((USART3->SR&0X40)==0);    //等待发送空
    USART3->DR='+';      
    DelayMs(500);                   //等待500ms
    return ESP8266_SendCmd("AT","OK",20);//退出透传判断.

​
​
/*
函数功能:获取ESP82668266模块的AP+STA连接状态
返 回 值:0,未连接;1,连接成功
*/
u8 ESP8266_ApStaCheck(void)

    if(ESP8266_QuitTrans())return 0;              //退出透传 
    ESP8266_SendCmd("AT+CIPSTATUS",":",50); //发送AT+CIPSTATUS指令,查询连接状态
    if(ESP8266_CheckCmd("+CIPSTATUS:0")&&
         ESP8266_CheckCmd("+CIPSTATUS:1")&&
         ESP8266_CheckCmd("+CIPSTATUS:2")&&
         ESP8266_CheckCmd("+CIPSTATUS:4"))
        return 0;
    else return 1;

​
​
/*
函数功能:获取ESP8266模块的连接状态
返 回 值:0,未连接;1,连接成功.
*/
u8 ESP8266_ConstaCheck(void)

    u8 *p;
    u8 res;
    if(ESP8266_QuitTrans())return 0;              //退出透传 
    ESP8266_SendCmd("AT+CIPSTATUS",":",50); //发送AT+CIPSTATUS指令,查询连接状态
    p=ESP8266_CheckCmd("+CIPSTATUS:"); 
    res=*p;                                                                 //得到连接状态    
    return res;

​
/*
函数功能:获取ip地址
函数参数:ipbuf:ip地址输出缓存区
*/
void ESP8266_GetWanip(u8* ipbuf)

      u8 *p,*p1;
        if(ESP8266_SendCmd("AT+CIFSR\r\n","OK",50))//获取WAN IP地址失败
        
            ipbuf[0]=0;
            return;
               
        p=ESP8266_CheckCmd("\"");
        p1=(u8*)strstr((const char*)(p+1),"\"");
        *p1=0;
        sprintf((char*)ipbuf,"%s",p+1); 

​
/*
函数功能:将收到的AT指令应答数据返回给电脑串口
参    数:mode:0,不清零USART3_RX_STA;
                             1,清零USART3_RX_STA;
*/
void ESP8266_AtResponse(u8 mode)

    if(USART3_RX_STA&0X8000)        //接收到一次数据了
     
        USART3_RX_BUF[USART3_RX_STA&0X7FFF]=0;//添加结束符
        printf("%s",USART3_RX_BUF); //发送到串口
        if(mode)USART3_RX_STA=0;
     

​
​
/*
函数功能:ESP8266 AP模式+TCP服务器模式测试
*/
void ESP8266_APorServer(void)

    u8 p[100];
    u8 ipbuf[20];
    
    
    while(ESP8266_SendCmd("AT\r\n","OK",20))//检查WIFI模块是否在线
    
        ESP8266_QuitTrans();//退出透传
        ESP8266_SendCmd("AT+CIPMODE=0\r\n","OK",200);  //关闭透传模式 
        printf("未检测到模块,正在尝试连接模块...\r\n");
        DelayMs(800);
    
    printf("ESP8266模块检测OK!\r\n");
    
    while(ESP8266_SendCmd("ATE0\r\n","OK",20)); //关闭回显
    
    printf("请用设备连接WIFI热点:%s,%s,%ss\r\n",(u8*)wifiap_ssid,(u8*)wifiap_encryption,(u8*)wifiap_password);
    
    /*1. 设置WIFI AP模式 */
    ESP8266_SendCmd("AT+CWMODE=2\r\n","OK",50);
    
    /*2. 重启模块 */
    ESP8266_SendCmd("AT+RST\r\n","OK",20);
    
    /*3. 延时3S等待重启成功*/
    DelayMs(1000);            
    DelayMs(1000);
    DelayMs(1000);
    
    /*5. 配置模块AP模式无线参数*/
    sprintf((char*)p,"AT+CWSAP=\"%s\",\"%s\",1,4\r\n",wifiap_ssid,wifiap_password); 
    ESP8266_SendCmd(p,"OK",1000);
    
    /*4. 设置多连接模式:0单连接,1多连接(服务器模式必须开启)*/
    ESP8266_SendCmd("AT+CIPMUX=1\r\n","OK",20); 
    
    /*5. 开启Server模式(0,关闭;1,打开),端口号为portnum */
    sprintf((char*)p,"AT+CIPSERVER=1,%s\r\n",(u8*)portnum);
    ESP8266_SendCmd(p,"OK",50);
    
    /*6. 获取当前模块的IP*/
    ESP8266_GetWanip(ipbuf);//
    printf("IP地址:%s 端口:%s",ipbuf,(u8*)portnum);
  
    USART3_RX_STA=0; //清空串口的接收标志位
//  while(1)
//  
//      key=GetKeyVal(1);//退出测试
//      if(key==1)
//       
//      printf("退出测试!\r\n");            
//          ESP8266_QuitTrans();    //退出透传
//          ESP8266_SendCmd("AT+CIPMODE=0","OK",20);   //关闭透传模式
//          break;                                               
//      
//      else if(key==2) //发送数据 
//      
//              ESP8266_SendCmd("AT+CIPSEND=0,12\r\n","OK",200); //设置发送数据长度为12个
//              ESP8266_SendData("ESP8266测试!","OK",100);       //发送指定长度的数据
//              DelayMs(200);
//      
//      t++;
//      DelayMs(10);
//      if(USART3_RX_STA&0X8000)          //接收到一次数据了
//       
//          rlen=USART3_RX_STA&0X7FFF;  //得到本次接收到的数据长度
//          USART3_RX_BUF[rlen]=0;        //添加结束符 
//          printf("接收的数据: rlen=%d,%s",rlen,USART3_RX_BUF); //发送到串口   
//          USART3_RX_STA=0;
//          if(constate!=3)t=1000;        //状态为还未连接,立即更新连接状态
//          else t=0;                   //状态为已经连接了,10秒后再检查
//      
//      if(t==1000)//连续10秒钟没有收到任何数据,检查连接是不是还存在.
//      
            constate=ESP8266_ConstaCheck();//得到连接状态
            if(!constate)printf("连接失败!\r\n");
//          t=0;
//      
//      if((t%20)==0)LED2=!LED2;
//      ESP8266_AtResponse(1);
//  
   

8★☆基于stm32的小区环境检测系统√★☆(代码片段)

8、★☆基于STM32的小区环境检测系统√★☆文章目录8、★☆基于STM32的小区环境检测系统√★☆Introduction引言1、系统概述1.1、设计任务1.2、设计要求2、方案设计与论证2.1、芯片选择方案2.2、系统概述2.3、设计要求2.4、系统总体... 查看详情

基于stm32和阿里云的环境检测系统设计

一、主要实现功能1、STM32采集温湿度,二氧化碳浓度在本地OLED进行数据显示2、STM32通过串口将数据发送给ESP8266,然后将数据上传到阿里云3、手机app进行远程查看数据+远程控制开关的打开状态4、温度高于设置的阈值... 查看详情

基于stm32和阿里云的环境检测系统设计

一、主要实现功能1、STM32采集温湿度,二氧化碳浓度在本地OLED进行数据显示2、STM32通过串口将数据发送给ESP8266,然后将数据上传到阿里云3、手机app进行远程查看数据+远程控制开关的打开状态4、温度高于设置的阈值... 查看详情

基于stm32单片机项目设计目录-加油吧√

★♥基于STM32单片机项目设计目录√♥※目录★♥基于STM32单片机项目设计目录√♥※1、基于STM32的音乐喷泉2、STM32的智能浇水补光系统3、基于STM32的手机通过wifi控LED灯4、基于STM32的电子打铃器5、基于STM32的智能手环6、基于STM32... 查看详情

基于stm32单片机项目设计目录-加油吧√

★♥基于STM32单片机项目设计目录√♥※目录★♥基于STM32单片机项目设计目录√♥※1、基于STM32的音乐喷泉2、STM32的智能浇水补光系统3、基于STM32的手机通过wifi控LED灯4、基于STM32的电子打铃器5、基于STM32的智能手环6、基于STM32... 查看详情

基于stm32设计的实时心率检测仪(代码片段)

一、开发环境介绍主控芯片: STM32F103ZET6代码编程软件:keil5心率检测模块: PulseSensorWIFI模块:ESP8266--可选的。直接使用串口有线传输给上位机也可以。上位机: C++(QT)设计的。支持PC机电脑、Android手机显示。与上位... 查看详情

毕业设计-基于stm32的空气质量检测仪-环境检测盒子(代码片段)

...f0c;这里是丹成学长,今天向大家介绍一个单片机项目基于STM32的空气质量检测仪大家可用于课程设计或毕业设计技术解答、毕设帮助、开题指导print("Q746876041")2系统设计概述如今人们大约80%的时间是在室内度过的,... 查看详情

基于stm32设计的健康检测设备(测温心率计步)(代码片段)

1.项目介绍本文介绍的项目是基于STM32设计的健康检测设备,支持体温测量,心率检测,支持运动计步(采用MPU6050陀螺仪实现),支持WIFI传输数据到手机APP打印显示。硬件环境介绍:MCU采用STM32F103C8T6心率传感器采用PulseSenso... 查看详情

基于stm32设计的智能家居控制系统设计_语音+环境检测(onenet)_2022(代码片段)

1.前言如今的智能家居越来越深入人心,越来越受人们的欢迎。智能家居作为与人们日常生活息息相关的科技智能产物,可以给我们的生活带来舒适便利。随着物联网、云计算、无线通信等新技术的发展,智能家居得... 查看详情

9★♥★基于stm32单片机的颜色检测仪设计♥☆(代码片段)

9、★♥★基于STM32单片机的颜色检测仪设计♥☆文章目录9、★♥★基于STM32单片机的颜色检测仪设计♥☆引言1、系统概述1.1、设计任务1.2、设计要求2、方案设计与论证2.1、芯片选择方案2.2、系统概述2.3、设计要求2.4、系统总体... 查看详情

9★♥★基于stm32单片机的颜色检测仪设计♥☆(代码片段)

9、★♥★基于STM32单片机的颜色检测仪设计♥☆文章目录9、★♥★基于STM32单片机的颜色检测仪设计♥☆引言1、系统概述1.1、设计任务1.2、设计要求2、方案设计与论证2.1、芯片选择方案2.2、系统概述2.3、设计要求2.4、系统总体... 查看详情

基于stm32设计的宠物投喂器(代码片段)

1.前言随着物联网技术的快速发展,智能家居已经进入人们的日常生活中,在政策加持的背景下,智能家居企业越来越关注相关技术的研发和应用;但是市场上的宠物投喂装置已经难以满足宠物主人的需求。文章介绍的宠物智能... 查看详情

stm32学习笔记①:环境配置及室内温湿度检测(代码片段)

...第一个项目,在此做下笔记一、项目简介1.项目名称基于STM32的室内温湿度检测2.项目设计思路思路:本项目采用ARM结构中最为代表的Cortex-M4系列的芯片ÿ 查看详情

基于stm32设计的蓝牙健康管理设备(代码片段)

1.前言随着移动通信技术的发展,移动互联网日益普及,传统互联网已经在向移动互联网迁移,智能穿戴设备近年来发展的非常迅速,成为一个热点行业,它通过借助传感器,与人体进行信息交互,是一种在新理念下诞生的智能... 查看详情

stm32峰会2017:半小时开发基于stm32的室内智能环境监测仪

...也越来越广泛,机智云智能硬件开发平台可以为广大空气检测设备厂商提供可靠的智能解决方案,帮助企业快速开发产品推向市场。本文以室内智能环境监测仪为例,利用机智云自助开发平台,只需30分钟即可搭 查看详情

14基于stm32的平衡小车设计

14、基于STM32的平衡小车设计引言1系统概述1.1设计任务1.2设计要求2方案设计与论证2.1芯片选择方案2.2系统概述2.3设计要求2.4系统总体设计思路2.5各功能模块程序实现原理分析2.5.1六轴陀螺仪检测模块2.5.2蓝牙控制模块2.5.4电机驱动... 查看详情

基于stm32+rfid设计的宿舍检修管理系统(代码片段)

1.需求需求:一个寝室一个标签,设备端扫描标签,通过显示屏键入维修成功与否之类的的信息提交到平台系统构架:一个设备端+一个上位机硬件选型:(1)STM32F103RCT6作为设备端的主控MCU(2)RC522作为设备... 查看详情

基于stm32+rfid设计的宿舍检修管理系统(代码片段)

1.需求需求:一个寝室一个标签,设备端扫描标签,通过显示屏键入维修成功与否之类的的信息提交到平台系统构架:一个设备端+一个上位机硬件选型:(1)STM32F103RCT6作为设备端的主控MCU(2)RC522作为设备... 查看详情