基于STM32的空气质量监测系统简单案例

  • 系统简介
  • 软硬件介绍
    • STM32F103开发板
    • MQ135空气质量传感器
    • DS18B20温度传感器
  • 设计流程
    • 硬件连接
    • 涉及内容
    • 效果显示
  • 项目源码
    • ADC部分
    • DS18B20
    • RTC部分
    • main部分

系统简介

系统使用正点原子的STM32F103 Mini开发板,通过MQ135空气质量传感器,实现简单的空气质量监测案例。
部分代码参考正点原子实验板代码。

软硬件介绍

软件:Keil 5
硬件:
1. STM32F103开发板(正点原子Mini板)
2. MQ135空气质量传感器
3. DS18B20温度传感器

STM32F103开发板

MQ135空气质量传感器


DS18B20温度传感器

设计流程

硬件连接

MQ135模块使用5V进行驱动,D0输出数字信号,A0输出模拟型号。
D0输出就相当一个开关电源,到了设定值进行跳转,并会亮绿灯。
如果你要做一个气体上限报警装置可以使用D0引脚。
我们这里使用的A0引脚进行模拟信号的输入和输出,来计算出对应的有害气体浓度。
连线:
5V+ 接开发板正极5V
5V- 接开发板负极GND
D0 接板载要开启ADC的引脚 我这里是GPIOA1

DS18B20温度传感器在正点原子的Mini开发板有直接对应的引脚。

涉及内容

主要涉及内容有:STM32的ADC功能,用于将MQ135读取的数据转化为对应的有害空气浓度;STM32 的内部实时时钟(RTC),实现日期时间显示;单总线技术,通过它来实现 STM32 和外部温度传感器(DS18B20)的通信。

效果显示

将获取的有害空气质量浓度转化为对应的空气质量等级。显示日期和时间。空气质量正常时,LED绿灯闪烁,字体为蓝色。当空气质量异常时,LED红灯闪烁,字体为红色。
通过打火机喷气,可看出相应的状态变化。

项目源码

ADC部分

 #include "adc.h"#include "delay.h"//初始化ADC
//这里我们仅以规则通道为例
//我们默认将开启通道0~3
void  Adc_Init(void)
{   ADC_InitTypeDef ADC_InitStructure; GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |RCC_APB2Periph_ADC1 , ENABLE );   //使能ADC1通道时钟RCC_ADCCLKConfig(RCC_PCLK2_Div6);   //设置ADC分频因子6 72M/6=12,ADC最大时间不能超过14M//PA1 作为模拟通道输入引脚                         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;        //模拟输入引脚GPIO_Init(GPIOA, &GPIO_InitStructure);  ADC_DeInit(ADC1);  //复位ADC1,将外设 ADC1 的全部寄存器重设为缺省值ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;    //ADC工作模式:ADC1和ADC2工作在独立模式ADC_InitStructure.ADC_ScanConvMode = DISABLE;    //模数转换工作在单通道模式ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;  //模数转换工作在单次转换模式ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //转换由软件而不是外部触发启动ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //ADC数据右对齐ADC_InitStructure.ADC_NbrOfChannel = 1;  //顺序进行规则转换的ADC通道的数目ADC_Init(ADC1, &ADC_InitStructure);  //根据ADC_InitStruct中指定的参数初始化外设ADCx的寄存器   ADC_Cmd(ADC1, ENABLE);  //使能指定的ADC1ADC_ResetCalibration(ADC1);  //使能复位校准  while(ADC_GetResetCalibrationStatus(ADC1));   //等待复位校准结束ADC_StartCalibration(ADC1);    //开启AD校准while(ADC_GetCalibrationStatus(ADC1));  //等待校准结束// ADC_SoftwareStartConvCmd(ADC1, ENABLE);     //使能指定的ADC1的软件转换启动功能}
//获得ADC值
//ch:通道值 0~3
u16 Get_Adc(u8 ch)
{//设置指定ADC的规则组通道,一个序列,采样时间ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_239Cycles5 );  //ADC1,ADC通道,采样时间为239.5周期                   ADC_SoftwareStartConvCmd(ADC1, ENABLE);     //使能指定的ADC1的软件转换启动功能    while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));//等待转换结束return ADC_GetConversionValue(ADC1); //返回最近一次ADC1规则组的转换结果
}u16 Get_Adc_Average(u8 ch,u8 times)
{u32 temp_val=0;u8 t;for(t=0;t<times;t++){temp_val+=Get_Adc(ch);delay_ms(5);}return temp_val/times;
}

DS18B20

#include "ds18b20.h"
#include "delay.h"    //复位DS18B20
void DS18B20_Rst(void)
{                 DS18B20_IO_OUT(); //SET PA0 OUTPUTDS18B20_DQ_OUT=0; //拉低DQdelay_us(750);    //拉低750usDS18B20_DQ_OUT=1; //DQ=1 delay_us(15);     //15US
}
//等待DS18B20的回应
//返回1:未检测到DS18B20的存在
//返回0:存在
u8 DS18B20_Check(void)
{   u8 retry=0;DS18B20_IO_IN();//SET PA0 INPUT  while (DS18B20_DQ_IN&&retry<200){retry++;delay_us(1);};    if(retry>=200)return 1;else retry=0;while (!DS18B20_DQ_IN&&retry<240){retry++;delay_us(1);};if(retry>=240)return 1;      return 0;
}
//从DS18B20读取一个位
//返回值:1/0
u8 DS18B20_Read_Bit(void)            // read one bit
{u8 data;DS18B20_IO_OUT();//SET PA0 OUTPUTDS18B20_DQ_OUT=0; delay_us(2);DS18B20_DQ_OUT=1; DS18B20_IO_IN();//SET PA0 INPUTdelay_us(12);if(DS18B20_DQ_IN)data=1;else data=0;   delay_us(50);           return data;
}
//从DS18B20读取一个字节
//返回值:读到的数据
u8 DS18B20_Read_Byte(void)    // read one byte
{        u8 i,j,dat;dat=0;for (i=1;i<=8;i++) {j=DS18B20_Read_Bit();dat=(j<<7)|(dat>>1);}                          return dat;
}
//写一个字节到DS18B20
//dat:要写入的字节
void DS18B20_Write_Byte(u8 dat)     {             u8 j;u8 testb;DS18B20_IO_OUT();//SET PA0 OUTPUT;for (j=1;j<=8;j++) {testb=dat&0x01;dat=dat>>1;if (testb) {DS18B20_DQ_OUT=0;// Write 1delay_us(2);                            DS18B20_DQ_OUT=1;delay_us(60);             }else {DS18B20_DQ_OUT=0;// Write 0delay_us(60);             DS18B20_DQ_OUT=1;delay_us(2);                          }}
}
//开始温度转换
void DS18B20_Start(void)// ds1820 start convert
{                                          DS18B20_Rst();      DS18B20_Check();  DS18B20_Write_Byte(0xcc);// skip romDS18B20_Write_Byte(0x44);// convert
}
//初始化DS18B20的IO口 DQ 同时检测DS的存在
//返回1:不存在
//返回0:存在
u8 DS18B20_Init(void)
{GPIO_InitTypeDef  GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);  //使能PORTA口时钟 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;                //PORTA0 推挽输出GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);GPIO_SetBits(GPIOA,GPIO_Pin_0);    //输出1DS18B20_Rst();return DS18B20_Check();
}
//从ds18b20得到温度值
//精度:0.1C
//返回值:温度值 (-550~1250)
short DS18B20_Get_Temp(void)
{u8 temp;u8 TL,TH;short tem;DS18B20_Start ();                    // ds1820 start convertDS18B20_Rst();DS18B20_Check();   DS18B20_Write_Byte(0xcc);// skip romDS18B20_Write_Byte(0xbe);// convert        TL=DS18B20_Read_Byte(); // LSB   TH=DS18B20_Read_Byte(); // MSB  if(TH>7){TH=~TH;TL=~TL; temp=0;//温度为负  }else temp=1;//温度为正          tem=TH; //获得高八位tem<<=8;    tem+=TL;//获得底八位tem=(float)tem*0.625;//转换     if(temp)return tem; //返回温度值else return -tem;
}

RTC部分

#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "rtc.h"
//Mini STM32开发板
//RTC实时时钟 驱动代码
//正点原子@ALIENTEK
//2010/6/6_calendar_obj calendar;//时钟结构体 static void RTC_NVIC_Config(void)
{   NVIC_InitTypeDef NVIC_InitStructure;NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQn;     //RTC全局中断NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //先占优先级1位,从优先级3位NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //先占优先级0位,从优先级4位NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;        //使能该通道中断NVIC_Init(&NVIC_InitStructure);        //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
}//实时时钟配置
//初始化RTC时钟,同时检测时钟是否工作正常
//BKP->DR1用于保存是否第一次配置的设置
//返回0:正常
//其他:错误代码u8 RTC_Init(void)
{//检查是不是第一次配置时钟u8 temp=0;RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);  //使能PWR和BKP外设时钟   PWR_BackupAccessCmd(ENABLE);  //使能后备寄存器访问  if (BKP_ReadBackupRegister(BKP_DR1) != 0x5050)        //从指定的后备寄存器中读出数据:读出了与写入的指定数据不相乎{                BKP_DeInit();   //复位备份区域    RCC_LSEConfig(RCC_LSE_ON);  //设置外部低速晶振(LSE),使用外设低速晶振while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET)   //检查指定的RCC标志位设置与否,等待低速晶振就绪{temp++;delay_ms(10);}if(temp>=250)return 1;//初始化时钟失败,晶振有问题     RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);     //设置RTC时钟(RTCCLK),选择LSE作为RTC时钟    RCC_RTCCLKCmd(ENABLE);    //使能RTC时钟  RTC_WaitForLastTask();   //等待最近一次对RTC寄存器的写操作完成RTC_WaitForSynchro();      //等待RTC寄存器同步  RTC_ITConfig(RTC_IT_SEC, ENABLE);     //使能RTC秒中断RTC_WaitForLastTask();    //等待最近一次对RTC寄存器的写操作完成RTC_EnterConfigMode();/// 允许配置 RTC_SetPrescaler(32767); //设置RTC预分频的值RTC_WaitForLastTask(); //等待最近一次对RTC寄存器的写操作完成RTC_Set(2020,5,5,12,59,00);  //设置时间    RTC_ExitConfigMode(); //退出配置模式  BKP_WriteBackupRegister(BKP_DR1, 0X5050);   //向指定的后备寄存器中写入用户程序数据}else//系统继续计时{RTC_WaitForSynchro(); //等待最近一次对RTC寄存器的写操作完成RTC_ITConfig(RTC_IT_SEC, ENABLE);  //使能RTC秒中断RTC_WaitForLastTask();    //等待最近一次对RTC寄存器的写操作完成}RTC_NVIC_Config();//RCT中断分组设置                              RTC_Get();//更新时间   return 0; //ok}
//RTC时钟中断
//每秒触发一次
//extern u16 tcnt;
void RTC_IRQHandler(void)
{        if (RTC_GetITStatus(RTC_IT_SEC) != RESET)//秒钟中断{                          RTC_Get();//更新时间   }if(RTC_GetITStatus(RTC_IT_ALR)!= RESET)//闹钟中断{RTC_ClearITPendingBit(RTC_IT_ALR);       //清闹钟中断        }                                                 RTC_ClearITPendingBit(RTC_IT_SEC|RTC_IT_OW);       //清闹钟中断RTC_WaitForLastTask();
}
//判断是否是闰年函数
//月份   1  2  3  4  5  6  7  8  9  10 11 12
//闰年   31 29 31 30 31 30 31 31 30 31 30 31
//非闰年 31 28 31 30 31 30 31 31 30 31 30 31
//输入:年份
//输出:该年份是不是闰年.1,是.0,不是
u8 Is_Leap_Year(u16 year)
{             if(year%4==0) //必须能被4整除{ if(year%100==0) { if(year%400==0)return 1;//如果以00结尾,还要能被400整除     else return 0;   }else return 1;   }else return 0;
}
//设置时钟
//把输入的时钟转换为秒钟
//以1970年1月1日为基准
//1970~2099年为合法年份
//返回值:0,成功;其他:错误代码.
//月份数据表
u8 const table_week[12]={0,3,3,6,1,4,6,2,5,0,3,5}; //月修正数据表
//平年的月份日期表
const u8 mon_table[12]={31,28,31,30,31,30,31,31,30,31,30,31};
u8 RTC_Set(u16 syear,u8 smon,u8 sday,u8 hour,u8 min,u8 sec)
{u16 t;u32 seccount=0;if(syear<1970||syear>2099)return 1;       for(t=1970;t<syear;t++)    //把所有年份的秒钟相加{if(Is_Leap_Year(t))seccount+=31622400;//闰年的秒钟数else seccount+=31536000;           //平年的秒钟数}smon-=1;for(t=0;t<smon;t++)      //把前面月份的秒钟数相加{seccount+=(u32)mon_table[t]*86400;//月份秒钟数相加if(Is_Leap_Year(syear)&&t==1)seccount+=86400;//闰年2月份增加一天的秒钟数     }seccount+=(u32)(sday-1)*86400;//把前面日期的秒钟数相加 seccount+=(u32)hour*3600;//小时秒钟数seccount+=(u32)min*60;     //分钟秒钟数seccount+=sec;//最后的秒钟加上去RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);  //使能PWR和BKP外设时钟  PWR_BackupAccessCmd(ENABLE);   //使能RTC和后备寄存器访问 RTC_SetCounter(seccount);   //设置RTC计数器的值RTC_WaitForLastTask();  //等待最近一次对RTC寄存器的写操作完成   RTC_Get();return 0;
}
//得到当前的时间
//返回值:0,成功;其他:错误代码.
u8 RTC_Get(void)
{static u16 daycnt=0;u32 timecount=0; u32 temp=0;u16 temp1=0;     timecount=RTC_GetCounter();   temp=timecount/86400;   //得到天数(秒钟数对应的)if(daycnt!=temp)//超过一天了{     daycnt=temp;temp1=1970; //从1970年开始while(temp>=365){              if(Is_Leap_Year(temp1))//是闰年{if(temp>=366)temp-=366;//闰年的秒钟数else {temp1++;break;}  }else temp-=365;      //平年 temp1++;  }   calendar.w_year=temp1;//得到年份temp1=0;while(temp>=28)//超过了一个月{if(Is_Leap_Year(calendar.w_year)&&temp1==1)//当年是不是闰年/2月份{if(temp>=29)temp-=29;//闰年的秒钟数else break; }else {if(temp>=mon_table[temp1])temp-=mon_table[temp1];//平年else break;}temp1++;  }calendar.w_month=temp1+1; //得到月份calendar.w_date=temp+1;     //得到日期 }temp=timecount%86400;          //得到秒钟数        calendar.hour=temp/3600;        //小时calendar.min=(temp%3600)/60;   //分钟    calendar.sec=(temp%3600)%60;   //秒钟calendar.week=RTC_Get_Week(calendar.w_year,calendar.w_month,calendar.w_date);//获取星期   return 0;
}
//获得现在是星期几
//功能描述:输入公历日期得到星期(只允许1901-2099年)
//输入参数:公历年月日
//返回值:星期号
u8 RTC_Get_Week(u16 year,u8 month,u8 day)
{   u16 temp2;u8 yearH,yearL;yearH=year/100;   yearL=year%100; // 如果为21世纪,年份数加100  if (yearH>19)yearL+=100;// 所过闰年数只算1900年之后的  temp2=yearL+yearL/4;temp2=temp2%7; temp2=temp2+day+table_week[month-1];if (yearL%4==0&&month<3)temp2--;return(temp2%7);
}

main部分

#include "led.h"
#include "delay.h"
#include "sys.h"
#include "usart.h"
#include "lcd.h"
#include "adc.h"
#include "math.h"
#include "ds18b20.h"
#include "rtc.h"int main(void){ u16 adcx;float temp,quality;short temperature; u8 t;  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);// 设置中断优先级分组2 delay_init();           //延时函数初始化    uart_init(9600);       //串口初始化为9600LED_Init();                 //初始化与LED连接的硬件接口LCD_Init();Adc_Init();             //ADC初始化    POINT_COLOR=BLACK; LCD_DrawLine(0,80,240,80);LCD_DrawLine(120,80,120,240);LCD_DrawLine(0,240,240,240);LCD_DrawLine(0,280,240,280);LCD_DrawLine(120,120,120,240);LCD_DrawLine(120,160,240,160); LCD_ShowString(40,20,230,16,16,"AIR MONITIRING SYSTEM");LCD_ShowString(76,40,230,16,16,"BASED ON RTOS");LCD_ShowString(10,100,230,16,16,"AIR QUALITY:");LCD_ShowString(130,90,230,16,16,"HARMFUL GAS");LCD_ShowString(125,110,230,16,16,"CONCENTRATION:");LCD_ShowString(150,130,230,16,16,"     PPM");  LCD_ShowString(130,170,230,16,16,"TEMPERATURE:");  LCD_ShowString(150,190,230,16,16,"   . C");     //LCD_ShowString(10,250,200,16,16,"2020-4-30 16:00"); LCD_ShowString(10,290,200,16,16,"STM32F103,MQ135,DS18B20");   while(DS18B20_Init())   //DS18B20初始化    {LCD_ShowString(150,210,200,16,16,"DS18B20 Error");delay_ms(200);LCD_Fill(60,130,239,130+16,WHITE);delay_ms(200);}while(RTC_Init())      //RTC初始化    ,一定要初始化成功{ LCD_ShowString(10,250,200,16,16,"RTC ERROR!   ");   delay_ms(800);LCD_ShowString(10,250,200,16,16,"RTC Trying...");   }                                   //显示时间               LCD_ShowString(10,250,200,16,16,"    -  -  ");      LCD_ShowString(100,250,200,16,16,"  :  :  ");      //显示提示信息//LCD_ShowString(60,130,200,16,16,"ADC_CH1_VAL:");          //LCD_ShowString(60,150,200,16,16,"ADC_CH1_VOL:0.000V");    //LCD_ShowString(60,170,200,16,16,"KQ_ZHILIANG:    ppm"); while(1){adcx=Get_Adc_Average(ADC_Channel_1,10);//LCD_ShowxNum(156,130,adcx,4,16,0);//显示ADC的值temp=(float)adcx*(3.3/4096);quality=pow((11.5428 * 35.904 * temp )/(25.5 - 5.1 * temp),1.0/0.6549);adcx=temp;//LCD_ShowxNum(156,150,adcx,1,16,0);//显示电压值temp-=adcx;//temp*=1000;//LCD_ShowxNum(172,150,temp,3,16,0X80);LCD_ShowxNum(150,130,quality,4,16,0);//显示转化后的PPM值//根据有害气体浓度判断空气质量if(0<= quality && quality <=75)LCD_ShowString(20,150,200,16,24,"NORMAL");  else if(quality<=150)LCD_ShowString(20,150,200,16,24,"MILD  ");else if(quality<=500)LCD_ShowString(20,150,200,16,24,"MIDDLE");else LCD_ShowString(20,150,200,16,24,"SEVERE");temperature=DS18B20_Get_Temp(); if(temperature<0){LCD_ShowChar(60+40,150,'-',16,0);           //显示负号temperature=-temperature;                    //转为正数}else LCD_ShowChar(60+40,150,' ',16,0);            //去掉负号LCD_ShowNum(150+8,190,temperature/10,2,16);  //显示正数部分        LCD_ShowNum(150+32,190,temperature%10,1,16);   //显示小数部分//LCD_ShowString(170,190,290,16,16,"26");//显示温度if(quality>=150) //当到达中度污染时红灯闪烁报警{LED1=1;LED0=!LED0;POINT_COLOR=RED;//设置字体为红色 }else{LED0=1;LED1=!LED1;  //正常时绿灯闪烁POINT_COLOR=BLUE;//设置字体为蓝色 }//显示时间if(t!=calendar.sec){POINT_COLOR=BLACK;//设置字体为黑色t=calendar.sec;LCD_ShowNum(10,250,calendar.w_year,4,16);                                      LCD_ShowNum(50,250,calendar.w_month,2,16);                                      LCD_ShowNum(74,250,calendar.w_date,2,16);  LCD_ShowNum(100,250,calendar.hour,2,16);                                     LCD_ShowNum(124,250,calendar.min,2,16);                                     LCD_ShowNum(148,250,calendar.sec,2,16);switch(calendar.week){case 0:LCD_ShowString(170,250,200,16,16,"Sunday");break;case 1:LCD_ShowString(170,250,200,16,16,"Monday");break;case 2:LCD_ShowString(170,250,200,16,16,"Tuesday");break;case 3:LCD_ShowString(170,250,200,16,16,"Wednesday");break;case 4:LCD_ShowString(170,250,200,16,16,"Thursday");break;case 5:LCD_ShowString(170,250,200,16,16,"Friday");break;case 6:LCD_ShowString(60,148,200,16,16,"Saturday ");break;  }}delay_ms(200); }
}   

基于STM32的空气质量监测系统简单案例相关推荐

  1. arduino读取水位传感器的数据显示在基于i2c的1602a上_构建Arduino的LoRa远程智能空气质量监测系统...

    背景知识视频教程 Arduino分步指南:完整指南 - 国外课栈​viadean.com Arduino微控制器:学习Arduino制作项目 - 国外课栈​viadean.com 通过构建实际应用程序 ...

  2. stm32毕业设计 空气质量检测系统

    文章目录 1 简介 2 系统设计概述 3 系统总体方案 4 硬件设计方案 4.1 stm32 主控 4.2 温度采集模块 4.3 甲醛浓度检测模块 4.4 PM2. 5 浓度检测模块 4.5 液晶显示 ...

  3. 【毕业设计】基于STM32的空气质量检测仪 - 环境检测盒子 - 单片机 物联网

    文章目录 1 简介 2 系统设计概述 3 系统总体方案 4 硬件设计方案 4.1 stm32 主控 4.2 温度采集模块 4.3 甲醛浓度检测模块 4.4 PM2. 5 浓度检测模块 4.5 液晶显示 ...

  4. 空气质量监测系统的组成和应用

    空气质量监测系统产品简介 网格化微型空气质量站是一种集数据采集.存储.传输和管理于一体的无人值守的环境监测系统,能全天候.连续.自动地监测环境,在提供PM10.PM2.5. SO2. NO2.CO.O ...

  5. 基于STM32单片机的水质监测系统(Proteus仿真+程序)

    编号:14 基于STM32单片机的水质监测系统 功能描述: 14.基于STM32单片机的水质监测系统 本设计由STM32F103单片机最小系统+AMPIRE12864液晶显示模块+两路A/D转换模块组 ...

  6. 基于stm32的空气质量检测净化系统,检测温湿度和pm10和 pm2.5,资料包含(设计文档,源码,pcb电路)。

    基于stm32的空气质量检测净化系统,检测温湿度和pm10和 pm2.5,资料包含(设计文档,源码,pcb电路).

  7. 什么是网格化空气质量监测系统?

    什么是网格化空气质量监测站监测系统呢?对于这个词大家应该显示不是太熟悉,那么我来为大家介绍下. 首先它是一种集数据采集.存储.传输和管理于一体的无人值守的环境监测系统,能全天候.连续.自动地监测环境, ...

  8. STM32单片机开发实例 基于STM32单片机的温室大棚监测系统

    一.系统设计 通过STM32单片机进行主控,通过光敏电阻模块进行大棚内的光照强度的采集,通过DHT11数字温湿度传感器进行温湿度的采集,通过气压模块进行大棚气压强度的采集,通过水滴模块进行土壤湿度的采 ...

  9. 基于webgis的空气质量监管系统

    对站点数据进行实时展示,理论上,监测数据更新频率为一小时.对各个站点监测要素历史数据进行检索查看.同时对各个站点各个要素数据进行月统计分析,以折线图进行展示. 地图预警展示"模块进入后是各个 ...

  10. STM32开发实例 基于STM32单片机的温室监测系统

    一.系统设计 由 STM32F103C8T6单片机最小系统 + DHT11温湿度检测 +MQ-135二氧化碳浓度传感器+水滴模块(检测土壤湿度)+光敏电阻模块+ESP8266无线传输模块.通过温湿度. ...

最新文章

  1. 后深度学习时代的一大研究热点?论因果关系及其构建思路
  2. R-CNN系列学习笔记
  3. 打破你的认知,数字除以 0 一定会崩溃吗?
  4. matlab knn,MATLAB K近邻算法 — knnsearch() 函数 | 学步园
  5. 关于MySql5“data too long for column”问题的探解
  6. 配置web工程的过程
  7. C/C++回调方式系列之二class接口回调和lambda程式
  8. ps保存psd后图层全没了_ps保存成psd格式后,再打开就是一张图片而不显图层,怎么办啊??急!!...
  9. 微信+html5+播放音频+自动播放,html5音频实现微信语音播放效果
  10. 数据时代建设医疗数据,主要有哪些意义?
  11. html 图片左中右排列,详解css布局实现左中右布局的5种方式
  12. Swift中MVP、Moya、模型设计
  13. 并不对劲的bzoj1095:p2056:[ZJOI2007]捉迷藏
  14. springboot集成阿里OSS上传文件
  15. 【备份】git命令行
  16. DNS递归和迭代查询
  17. RHEL 8.2 镜像
  18. 邮件群发为什么容易被拦截?怎么避免?
  19. 为什么说要学习全新的原生 JavaScript?
  20. 计算机网络基础概念与重要定义汇总

热门文章

  1. 中文核心期刊投稿指南
  2. c语言实验编码sdut,C语言实验一(1)
  3. C语言 实验六 函数
  4. 尝试用朴素贝叶斯分析借款信用等级
  5. 斐讯K2刷不死breed与第三方固件教程
  6. Arcgis操作系列一:shp矢量数据的面积计算
  7. C/C++全局钩子实现,手把手
  8. html公差符号输入,CAD特殊符号输入:公差符号、直径符号等
  9. Mac下安装Eclipse
  10. Linux如何查看端口