基于STM32的MQ系列传感器检测并显示

2025年4月2日 2点热度 0人点赞

这是"基于STM32的智能家用可燃气泄露报警器项目"的天然气监测部分的讲解(用的是天然气检测性能比较好的MQ9传感器),有兴趣的可以看整体项目哦,整体项目的讲解链接放在结尾处了哦。如果想要MQ9传感器的单独测试代码源程序和MQ传感器技术文档的可以去结尾处的GITHUB网址中直接下载哦!觉得代码还可以的给博主点个赞吧!(„ಡωಡ„)栓Q

总体项目实物图:

一、天然气检测传感器(MQ9)介绍

MQ-9气体传感器所使用的气敏材料是在清洁空气中电导率较低的二氧化锡(SnO2)。采用高低温循环检测方式低温(1.5V加热)检测一氧化碳,传感器的电导率随空气中一氧化碳气体浓度增加而增大,高温(5.0V加热)检测可燃气体甲烷、丙烷并清洗低温时吸附的杂散气体。使用简单的电路即可将电导率的变化,转换为与该气体浓度相对应的输出信号。 MQ-9气体传感器对一氧化碳、甲烷、液化气的灵敏度高,这种传感器可检测多种含一氧化碳及可燃性的气体,是一款适合多种应用的低成本传感器。

(1)工作原理

MQ系列气体传感器属于二氧化锡半导体气敏材料,属于表面离子式N型半导体。处于200-300摄氏度时,二氧化锡吸附空气中的氧,形成氧的负离子吸附,使半导体中的电子密度减少,从而使其电阻值增加。当与某种气体接触时,如果晶粒间界处的势垒收到某种气体的调至而变化,就会引起表面导电率的变化。利用这一点就可以获得这种气体存在的信息,某种气体的浓度越大,导电率越大,输出电阻越低,则输出的模拟信号就越大,再经过模数转换电路,公式换算,便可以得到具体的气体浓度。

(2)传感器特性描述

图1.1 传感器典型的灵敏度特性曲线

图1.1中纵坐标为传感器的电阻比(Rs/R0),横坐标为气体浓度。Rs表示传感器在不同浓度气体中的电阻值,R0表示传感器在洁净空气中的电阻值。图中所有测试都是在标准试验条件下完成的。

图1.2 传感器典型的温度、湿度特性曲线

图1.2中纵坐标是传感器的电阻比(Rs/Rso)。Rs表示在含150ppm一氧化碳、不同温/湿度下传感器的电阻值。Rso表示在150ppm一氧化碳、20℃/55%RH环境条件下传感器的电阻。

图1.3敏感特性曲线

图1.3表示传感器在不同浓度的一氧化碳气氛中对应的VRL值。所用负载(RL)为4.7KΩ,图中所有测试都是在标准试验条件下完成的。

图1.4响应恢复特性曲线

图1.4表示传感器先被放入检测气氛中,然后再从该气氛中移走,这个过程中传感器的VRL值变化情况。

图1.5长期稳定性

图1.5中所有测试都是在标准试验条件下完成的,横坐标为观察时间,纵坐标VRL值。

表1.1 MQ9引脚

编号

名称

功能

1

VCC

电源正

2

GND

电源地

3

DO

数字量输出引脚

4

AO

模拟量输出引脚

图1.6 MQ9测试电路图

说明:图1.6为MQ-9传感器的基本测试电路。该传感器需要施加2个电压:加热器电压(VH)和测试电压(VC)。其中VH用于为传感器提供特定的工作温度, 可用直流电源或交流电源,该型号要求VH在传感器检测一氧化碳时要处于1.5V±0.1V的低电压状态,而在非检测状态(恢复阶段)及测试甲烷浓度时处于5V±0.1V状态。VRL是传感器串联的负载电阻(RL)上的电压。VC是为负载电阻RL提供测试的电压,须用直流电源。

(3)注意事项

①必须避免的情况

暴露于可挥发性硅化合物蒸气中:传感器暴露在高浓度的腐蚀性气体(如传感器要避免暴露于硅粘接剂、发胶、硅橡胶、腻子或其它存在可挥发性硅化合物的场所。如果传感器的表面吸附了硅化合物蒸气,传感器的敏感材料会被硅化合物分解形成的二氧化硅包裹,抑制传感器的敏感性,并且不可恢复。

高腐蚀性的环境:传感器暴露在高浓度的腐蚀性气体(如H2S,SO2,Cl2,HCl 等)中,不仅会引起加热材料及传感器引线的腐蚀或破坏,并会引起敏感材料性能发生不可逆的劣变。

碱、碱金属盐、卤素的污染:传感器被碱金属尤其是盐水喷雾污染后,或暴露在卤素如氟利昂中,也会引起性能劣变。

接触到水:溅上水或浸到水中会造成传感器敏感特性下降。

结冰:水在传感器敏感材料表面结冰会导致敏感层碎裂而丧失敏感特性。

施加电压过高:如果给传感器或加热器施加的电压高于规定值,即使传感器没有受到物理损坏或破坏,也会造成引线和/或加热器损坏,并引起传感器敏感特性下降。

电压加错管脚(仅限于旁热式系列):对6脚型的传感器,2、5为加热电极,(1、3)/(4、6)为测试用电极,1和3导通,4和6导通。如果电压加在 1、3 或 4、6 管脚会导致引线烧断,加在2、4管脚上则取不到信号。

②尽可能避免的情况

凝结水:在室内使用条件下,轻微凝结水对传感器性能会产生轻微影响。但是,如果水凝结在敏感层表面并保持一段时间,传感器特性则会下降。

处于高浓度气体中:无论传感器是否通电,在高浓度气体中长期放置,均会影响传感器特性。如用打火机气直接喷向传感器,会对传感器造成极大损害。

长期贮存:传感器在不通电情况下长时间贮存,其电阻会产生可逆性漂移,这种漂移与贮存环境有关。传感器应贮存在不含可挥发性硅化合物的密封袋中。经长期贮存的传感器,在使用前需要更长时间通电以使其达到稳定。贮存时间及对应的老化时间建议如表 所示。

表1.2 贮存时间及对应的老化时间建议表

贮存时间

建议老化时间

1个月以下

不低于48小时

1-6个月

不低于72小时

6个月以上

不低于168小时

长期暴露在极端环境中:无论传感器是否通电,长时间暴露在极端条件下,如高湿、高温或高污染等极端条件,传感器性能将受到严重影响。

二、天然气检测传感器(MQ9)原理图及总体代码逻辑讲解

STM32F407会一直在主函数里检测MQ9的电压,MQ9的电压是通过STM32F407的ADC测量出来的,天然气浓度越高,MQ9的模拟电压越大,STM32F407的ADC将MQ9传输回来的模拟量转化为数字量,最后通过MQ9的特性曲线计算出PPM的值显示在LCD屏幕上。MQ9的特性曲线要先根据环境中PPM值和MQ9内部电阻R0测量出来RL,然后得出特性曲线。

图2.1 MQ9天然气检测模块AD设计原理图

三、天然气检测传感器(MQ9)代码

main.c

#include "sys.h" #include "delay.h" #include "usart.h" #include "led.h" #include "lcd.h" #include "mq9.h" u8 Smog_yu = 30;//CO的阈值 int main(void) { float Smog_ppm = 0; NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2 delay_init(168); //初始化延时函数 uart_init(115200); //初始化串口波特率为115200 MQ2_Init(); LED_Init(); //初始化LED LCD_Init(); //初始化LCD FSMC接口 while(1) { // int a; // a = MQ7_PPM_Calibration(); // LCD_ShowNum(30+64,170,a,2,16); Smog_ppm = Smog_GetPPM(); // printf("烟雾浓度:%.3f 烟雾阈值:%d\n",Smog_ppm, Smog_yu); LCD_ShowString(30,150,200,12,16,"Smog_ppm: . "); LCD_ShowString(30,170,200,12,16,"Smog_yu: "); LCD_ShowNum(30+72,150,Smog_ppm,3,16); //显示烟雾浓度 LCD_ShowNum(30+104,150,(int)(Smog_ppm*1000)%1000,3,16); //显示烟雾浓度 LCD_ShowNum(30+64,170,Smog_yu,2,16); //显示烟雾阈值 LED0=!LED0; delay_ms(100); } } 

mq9.h

#ifndef _MQ2_H #define _MQ2_H //C文件中需要的其他的头文件 #include <stm32f4xx.h> #include "sys.h" #include "delay.h" #include "math.h" #define SMOG_READ_TIMES 10 //定义烟雾传感器读取次数,读这么多次,然后取平均值 //C文件中定义的函数的声明 void MQ2_Init(void); float Smog_Get_Vol(void); //读取MQ7传感器的电压值 float MQ7_PPM_Calibration(void); float Smog_GetPPM(void); #endif 

mq9.c

#include "mq9.h" #define CAL_PPM 10 // 校准环境中PPM值 #define RL 10 // RL阻值 #define R0 97 // R0阻值 void MQ2_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; ADC_CommonInitTypeDef ADC_CommonInitStructure; ADC_InitTypeDef ADC_InitStructure; /* 引脚和ADC的时钟使能 */ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); /* 配置引脚为模拟功能模式 */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN; //模拟功能模式 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ; GPIO_Init(GPIOA, &GPIO_InitStructure); /* ADC的常规配置 */ ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent; //独立模式 ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2; //84MHz/2 = 42MHz ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled; //禁止MDA ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles; //ADC通道采用间隔 ADC_CommonInit(&ADC_CommonInitStructure); /* ADC1 初始化 ****************************************************************/ ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b; //分辨率 ADC_InitStructure.ADC_ScanConvMode = DISABLE; //禁止扫描 ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; //连续转换模式 ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;//不需要外部触发 ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //数据右对齐 ADC_InitStructure.ADC_NbrOfConversion = 1; //一次转换 ADC_Init(ADC1, &ADC_InitStructure); //ADC1的采样通道4放入规则通道1中 ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 1, ADC_SampleTime_3Cycles); /* 使能 ADC1 */ ADC_Cmd(ADC1, ENABLE); } uint32_t MQ2_ADC_Read(void) { /* 启动软件触发检测 */ ADC_SoftwareStartConv(ADC1); //等待转换结束 while( ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET); return ADC_GetConversionValue(ADC1); } //计算平均值 u16 ADC1_Average_Data(u8 ADC_Channel) { u16 temp_val=0; u8 t; for(t=0;t<SMOG_READ_TIMES;t++) //#define SMOG_READ_TIMES 10 定义烟雾传感器读取次数,读这么多次,然后取平均值 { temp_val+=MQ2_ADC_Read(); //读取ADC值 delay_ms(5); } temp_val/=SMOG_READ_TIMES;//得到平均值 return (u16)temp_val;//返回算出的ADC平均值 } //读取MQ7传感器的电压值 float Smog_Get_Vol(void) { u16 adc_value = 0;//这是从MQ-7传感器模块电压输出的ADC转换中获得的原始数字值,该值的范围为0到4095,将模拟电压表示为数字值 float voltage = 0;//MQ-7传感器模块的电压输出,与一氧化碳的浓度成正比 adc_value = ADC1_Average_Data(ADC_Channel_4);//#define SMOG_ADC_CHX ADC_Channel_4 定义烟雾传感器所在的ADC通道编号 delay_ms(5); voltage = (3.3/4096.0)*(adc_value); return voltage; } ///********************* // 传感器校准函数,根据当前环境PPM值与测得的RS电压值,反推出R0值。 // 在空气中运行过后测出R0为26 //float MQ7_PPM_Calibration() //{ // float RS = 0; // float R0 = 0; // RS = (3.3f - Smog_Get_Vol()) / Smog_Get_Vol() * RL;//RL 10 // RL阻值 // R0 = RS / pow(CAL_PPM / 98.322, 1 / -1.458f);//CAL_PPM 10 // 校准环境中PPM值 // return R0; //} //**********************/ // 计算Smog_ppm float Smog_GetPPM() { float RS = (3.3f - Smog_Get_Vol()) / Smog_Get_Vol() * RL; float ppm = 98.322f * pow(RS/R0, -1.458f); return ppm; } 

代码文档库:GitHub - moluqitu/Based-on-the-STM32-MQ-series-sensors-and-display at 8c138430344ed41d554d7f09e341a3d6a0989341

PS:有不懂的或者有什么建议都可以私聊我哦,如果觉得我写的对你有帮助那给我点个赞吧 ❛‿˂̵✧