MQ-2烟雾传感器模块功能实现(STM32)

article/2025/8/27 19:08:05

认识MQ-2模块与其工作原理

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

        与MQ-7一样,MQ-2一共有4个引脚,分别是GND、DOUT、AOUT和VCC。VCC是电源引脚,用于给模块供电,可以理解为正极,一般接3.3V或者5V。GND连接模块的地线,可以理解为是负极,通常是0V。DOUT是数字输出引脚,用于输出数字信号。AOUT是模拟输出引脚,用于输出模拟信号。我们一般使用AOUT引脚也就是读取模块输出的模拟信号。

        32单片机可以通过模数转换器(ADC)读取传感器输出的模拟电压信号,而我们需要做的则是根据传感器特性曲线函数将电压值转换为烟雾浓度值。

MQ-2传感器特性曲线

        如图,假如说要测量CH4的ppm, 则可以取对应的坐标点,然后作成函数。

CH4_ppm20050080010001100
Rs/Ro32.21.91.81.4

模块与32单片机的连接

        这里我使用的单片机型号为STM32F407ze,上面也说过,要获得MQ-2测量的数据就要使用模数转换器(ADC),所以需要选择具有ADC功能的引脚,哪一个引脚拥有ADC功能可以通过查阅单片机的资料可知。

        通过查阅资料,我选择具有ADC功能的PA4引脚,PA4与CAMERA的第5引脚相连,所以只需要将MQ-7的AOUT引脚通过杜邦线接到CAMERA的第5引脚即可。剩下的就是接电源线了,随便找两个满足要求的引脚即可。

 具有ADC功能的引脚

 硬件连接

代码功能实现

        本次使用MQ-2传感器监测CH4的浓度。32单片机通过ADC(模数转换器)读取MQ-2传感器输出的模拟电压信号。首先可以先获取ADC在一定时间内的平均值,其次,可以利用公式将ADC的平均值转化为MQ-2的输出电压值,接着根据这个电压信号和传感器特性曲线(即上图中的带黄色三角形的折线)计算出CH4的浓度。例如,定义Smog_Get_Vol()函数用于读取MQ-2传感器的电压值。它使用了STM32的ADC模块来获取模拟信号,并将其转换为数字值。接着,函数将模拟电压值转换为数字值,并将其除以4096.0,以获得0到3.3V范围内的电压值。最后,函数返回电压值,该值与CH4的浓度成正比。然后再定义Smog_GetPPM()函数用于计算MQ-2传感器检测到的CH4浓度。在这个函数里先通过调用Smog_Get_Vol()函数来获取MQ-2传感器的电压值。然后,计算MQ-2传感器的电阻值(RS),该值基于传感器的电压值和电路中的电阻值。在这里,电路中的电阻值(RL)和空气中的CH4浓度下MQ-2传感器的电阻值(R0)是预先确定的常量。最后,该函数计算CH4的浓度(ppm),并返回该值。

模块部分

        本次将ADC部分代码与MQ-2融合到一起写:

        MQ2.c

#include "mq2.h"#define CAL_PPM  10  // 校准环境中PPM值
#define RL	     10  // RL阻值
#define R0	     26  // 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 = 42MHzADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;	//禁止MDAADC_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;
}

        mq2.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

主函数部分

        main.c

#include <stm32f4xx.h>
#include "sys.h"
#include <stdio.h>
#include "delay.h"
#include "uart.h"
#include "mq7.h"//重定向fputc函数
int fputc(int ch, FILE *F)
{//通过串口1发送数据到PCUSART_SendData(USART1, ch);while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);//等待发送数据完毕return ch;
}u8 Smog_yu = 30;//CO的阈值	int main(void)
{float Smog_ppm = 0;//确定系统定时器的工作频率  内核的工作频率/8 = 168MHz/8 = 21MHzSysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);UART1_Config();//配置串口MQ2_Init();while(1){Smog_ppm = Smog_GetPPM();printf("烟雾浓度:%.3f  烟雾阈值:%d\n",Smog_ppm, Smog_yu);}return 0;
}


http://chatgpt.dhexx.cn/article/Uv8NRrZl.shtml

相关文章

MQ-2烟雾浓度传感器

文章目录 一、模块简介二、工作原理三、程序设计 本实验将采集到的传感器数据利用ADC转换&#xff0c;将转换后的电压值显示在串口调试助手上 一、模块简介 MQ-2烟雾传感器所使用的气敏材料是在清洁空气中电导率较低的二氧化锡(SnO2)。当烟雾传感器所处环境中存在可燃气体时&a…

python杨辉三角输出指定行_python杨辉三角输出指定行_使用python打印十行杨辉三角过程详解...

如何用python输出杨辉三角 程序输出需要实现如下效果&#xff1a; [1] [1,1] [1,2,1] [1,3,3,1] .. 方法&#xff1a;迭代&#xff0c;生成器 123456789101112131415161718192021 def triangles() L [1] while True: yiled L L [1] [L[i] L[I1] for i in range(len(L)-1)] …

蓝桥杯 python 杨辉三角

欢迎使用Markdown编辑器 你好&#xff01; 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果你想学习如何使用Markdown编辑器, 可以仔细阅读这篇文章&#xff0c;了解一下Markdown的基本语法知识。 新的改变 我们对Markdown编辑器进行了一些功能拓展与语法支持&#x…

python杨辉三角 简单方法

何为杨辉三角&#xff0c;杨辉三角就是&#xff0c;第一行与第二行分别为1和1,1 再往后第三行就有规律了&#xff0c;除了开头和结尾的数&#xff08;都是1&#xff09;&#xff0c;每个数都是自己左上角和右上角的和。如图&#xff1a; 如何用编程把它实现呢&#xff1f;我们…

Python 杨辉三角

前言&#xff1a;我在学习Python的时候&#xff0c;正好学到列表推导式&#xff0c;于是这里尝试运用列表推导式来写一个杨辉三角。如果能点出其中不足或提出优化建议&#xff0c;感激不尽。 杨辉三角&#xff1a;杨辉三角左右两侧的数字都是1&#xff0c;而里面的数字等于它肩…

python杨辉三角

题目 杨辉三角形&#xff0c;也称帕斯卡三角&#xff0c;其定义为&#xff1a;顶端是 1,视为(row0).第1行(row1)(1&1)两个1,这两个1是由他们上头左右两数之和 (不在三角形内的数视为0).依此类推产生第2行(row2):011;112;101.第3行(row3):011;123; 213;101. 循此法可以产生以…

Python程序:输出杨辉三角的几种办法

文章目录 一、问题描述二、问题分析三、第一种方法1、具体代码2、运行结果3、程序的改进 四、第二种方法1、具体代码2、运行结果 五、总结分析 一、问题描述 给定一个非负整数 n&#xff0c;生成「杨辉三角」的前 n行。 在「杨辉三角」中&#xff0c;每个数是它左上方和右上方…

用python实现杨辉三角的几种不同方式

杨辉三角的概念 比较详细的知识可以看这里&#xff0c;在杨辉三角中&#xff0c;每个数是它左上方和右上方的数的和。 1/ \1 1/ \ / \1 2 1/ \ / \ / \1 3 3 1/ \ / \ / \ / \1 4 6 4 1/ \ / \ / \ / \ / \ 1 5 10 10 5 1解法1&#xff1a;动态规…

【杨辉三角python】

文章目录 杨辉三角实现方法&#xff08;Python&#xff09; 一、杨辉三角是什么&#xff1f;二、杨辉三角解法 杨辉三角实现方法&#xff08;Python&#xff09; 一、杨辉三角是什么&#xff1f; 杨辉三角&#xff0c;是二项式系数在三角形中的一种几何排列&#xff0c;中国南…

Python实现杨辉三角(2种实现方案)

杨辉三角形&#xff0c;又称贾宪三角形、帕斯卡三角形&#xff0c;是二项式系数在三角形中的一种几何排列。 下图显示了杨辉三角的前 7 行&#xff1a; 递归打印杨辉三角 杨辉三角形中的数&#xff0c;正是(xy)的 N 次方幂展开式各项的系数&#xff0c;下面以递归的方法来打印…

【Python实现杨辉三角】

目录 什么是杨辉三角 杨辉三角解法 1. 定义法 2. 计算杨辉三角 补0法 3. 杨辉三角&#xff0c;对称法 4. 杨辉三角&#xff0c;单列表方法 5.列表嵌套&#xff08;二维数组&#xff09; 6. 新旧两行&#xff0c;一次性开辟新行 7.yield函数 8.zip函数 参考资料链接&…

c++自定义函数

对于小型应用程序来说不设计自定义函数完全可行&#xff0c;但随着程序越来越大&#xff0c;越来越复杂&#xff0c;实现的功能越来越多&#xff0c;如果不使用函数&#xff0c;main函数将变的越来越复杂越来越雍肿越来越令人难懂&#xff0c;而在更改程序的每一个功能的时候&a…

C++ 自定义函数

C的函数分两种&#xff1a; 今天&#xff0c;我们就来讲一下自定义函数。 好了&#xff0c;自定义函数讲完了&#xff0c;若想了解其他关于自定义函数的内容&#xff0c;请点击下面方框&#xff1a; C递归算法_闪耀的天狼星的博客-CSDN博客_c递归算法汉诺塔大家都玩过吧&#…

C语言:自定义函数实现对字符串的复制

#include <stdio.h> void f(char*str1,char*str2)//函数名为f&#xff0c;自定义字符串连接函数 {int i0;while(str2[i]!0) {str1[i]str2[i];//把b复制到a中i;}str1[i]\0;//添加字符串结束符 } int main() {char a[100],b[100];puts("请输入字符串:\n");gets…

C语言之自定义函数(综合)

//设定一个函数&#xff0c;来比较两个数之间的较大值 int get_max(int x, int y) {int z 0;if (x > y)z x;elsez y;return z;} int main() {int a 10;int b 20;int maxget_max(a, b);printf("%d", max);return 0; } //函数返回类型的地方写出&#xff1a;vo…

[C语言] 函数:库函数--自定义函数--函数的调用--练习--详解<个人>------(1)

文章目录 前言一. 函数是什么&#xff1f;二. C语言中函数的分类三. 库函数四. 自定义函数五. 函数的调用六. 练习总结 前言 本节内容主要记录函数的相关内容&#xff0c;其中包括&#xff1a;库函数&#xff0c;自定义函数&#xff0c;函数的调用&#xff0c;函数的习题练习。…

C语言中的函数 | 库函数和自定义函数

写在前面: 今天我们需要学习和了解的是C语言中的函数,其中C语言的函数划分为库函数和自定义函数两种.接下来我们一起探究两者之间的关系. 一.C语言中函数的分类 库函数自定义函数 二.库函数 库函数到底是什么呢? 顾名思义,可以通俗的理解为库里面的函数.这些函数都是频繁使…

c++自定义函数简单介绍

大家好&#xff0c; 今天给大家介绍一下自定义函数。 如有错误请在评论区指出 正文&#xff1a; 1.简单介绍&#xff1a; 函数是一组一起执行一个任务的语句。每个 C 程序都至少有一个函数&#xff0c;即主函数 main() &#xff0c;所有简单的程序都可以定义其他额外的函数…

C语言入门系列 - 自定义函数

C语言入门系列 - 自定义函数 第一节 C 语言基础以及基本数据类型 第二节 C 语言运算符 第三节 C 语言控制语句 第四节 C 语言自定义函数 第五节 C 语言修饰变量的关键字 第六节 C 语言构造数据类型–数组 第七节 C 语言字符串 第八节 C 语言指针 第九节 指针与函数、指针函数、…

C语言-函数(自定义函数)

C语言中函数的分类&#xff1a; 1 库函数 2 自定义函数 自定义函数 如果库函数能干所有的事情&#xff0c;那还要程序员做什么&#xff1f; 所以更重要的是自定义函数 函数的组成&#xff1a; ret_type fun_name (part1) { statement; //语句项 &#xff08;函数体&…