环境监测系统--------MQ系列气体检测模块驱动教程(保姆级教程)


⏩ 大家好哇!我是小光,嵌入式爱好者,一个想要成为系统架构师的大三学生。
⏩在环境检测中我们经常会用到检测气体的传感器,检测乙醇、甲烷、一氧化碳、氢气等等,博主呕心沥血对MQ系列传感器做一个史上最详细的使用教程。
⏩感谢你的阅读,不对的地方欢迎指正。
加入小光嵌入式交流群(qq群号:737327353)免费获取博主所有资料哦!


MQ系列

  • 传感器说明
    • 传感器原理
    • 读取传感器数据原理
  • 硬件连接
  • 软件驱动代码
    • ADC驱动代码
    • 模块驱动代码
    • 主函数调用
  • 总结

传感器说明

传感器原理

在这里插入图片描述
MQ气体传感器使用的气敏材料是在清洁空气中电导率较低的二氧化锡(Sno2)。当传感器所处环境中存在可燃气体时,传感器的电导率随空气中可燃气体浓度的增加而增大。使用简单的电路即可将电导率的变化转换为与该气你浓度相对应的输出信号。MQ气体传感器对甲烷的灵敏度高,对丙烷、丁烷也有较好的灵敏度。这种传感器可检测多种可燃性气体,特别是天然气,是一款适合多种营养的低成本传感器。
目前有以下传感器:
在这里插入图片描述
本文包含MQ3、MQ5、MQ7、MQ135传感器的代码。
在这里插入图片描述
电器性能
输入电压:DC5V功耗(电流):150mA
DO输出:TTL数字量0和1(0.1和5V)
AO输出:0.1-0.3V(相对无污染),高浓度电压4V左右
特别提醒:传感器通电后,需要预热20S左右,测量的数据才稳定,传感器发热属于正常现象,因为内部有电热丝。

读取传感器数据原理

MQ-3 气敏元件的结构和外形如下图所示:
在这里插入图片描述
在这里插入图片描述

Rs/R0~ppm特性曲线如下图:
在这里插入图片描述
在这里插入图片描述

Rs/R0~温湿度 特性曲线
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
a=0.5447,b=-0.6785
注意:RL的电阻值是自己测量的,R0的值是根据传感器所处环境测量出的电压进行计算的,这两个变量也是代码中需要更改的,如果使用的。

硬件连接

开发板:STM32F103C8T6最小系统板
传感器:MQ3、MQ5、MQ7、MQ135

/******************引脚接口**************************
MQ3    AO	-PA1	
MQ5    AO	-PA4
MQ7    AO	-PA5
MQ135  AO	-PA7
VCC         -3.3V
GND         -开发板GND
************************************************/

软件驱动代码

ADC驱动代码

ADC模数转换就在这里不详细解答啦,如果使用的引脚不同需要在adc.h中更改相关的定义。
adc.h

#ifndef __ADC_H
#define __ADC_H	
#include "sys.h"							  

//本程序只供学习使用,未经作者许可,不得用于其它任何用途
//STM32F103最小系统板
//MQ传感器驱动代码	   
//技术交流群:737327353
//修改日期:2024/4/21
//版本:V1.0
//版权所有,盗版必究。
//Copyright(C) CSDN 小光学嵌入式					  
/
//对应的ADC通道
#define MQ3_adc_channel ADC_Channel_1
#define MQ5_adc_channel ADC_Channel_4
#define MQ7_adc_channel ADC_Channel_5
#define MQ135_adc_channel ADC_Channel_7
//对应引脚
#define MQ3_Port GPIO_Pin_1
#define MQ5_Port GPIO_Pin_4
#define MQ7_Port GPIO_Pin_5
#define MQ135_Port GPIO_Pin_7#define MQ_GPIOX GPIOA
void Adc_Init(void);
u16  Get_Adc(u8 ch);
u16 Get_Adc_Average(u8 ch,u8 times);#endif 

adc.c

#include  "adc.h"
#include  "delay.h"//初始化ADC
//这里我们仅以规则通道为例
//我们默认将开启通道0~3																	   
void  Adc_Init(void)
{ADC_InitTypeDef ADC_InitStructure;GPIO_InitTypeDef GPIO_InitStruture;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_ADC1,ENABLE);//使能ADC1通道时钟RCC_ADCCLKConfig(RCC_PCLK2_Div6);//shezhiADC分频因子 //PA1 作为模拟通道输入引脚   GPIO_InitStruture.GPIO_Mode = GPIO_Mode_AIN;GPIO_InitStruture.GPIO_Pin = MQ3_Port|MQ5_Port|MQ7_Port|MQ135_Port;GPIO_Init(MQ_GPIOX,&GPIO_InitStruture);ADC_DeInit(ADC1);//复位ADC1ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;//是否持续扫描ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//数据右对齐模式ADC_InitStructure.ADC_ExternalTrigConv =ADC_ExternalTrigConv_None;//外部中断ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;//独立模式;ADC1和ADC2独立ADC_InitStructure.ADC_NbrOfChannel = 5;ADC_InitStructure.ADC_ScanConvMode= DISABLE;//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));	 //等待校准结束
}
u16  Get_Adc(u8 ch)
{//设置指定ADC的规则组通道,一个序列,采样时间ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_239Cycles5);//ADC1,ADC通道,采样通道数量,采样周期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);}return temp_val/times;
}

模块驱动代码

以下都是博主自己编写的驱动程序哦,
注意:RL的电阻值是自己测量的,R0的值是根据传感器所处环境测量出的Vout电压进行计算的。
mq.h

#ifndef _MQ_H
#define _MQ_H
#include "stm32f10x.h"
#include "sys.h"
#include "adc.h"
#include "usart.h"
#include <math.h>
//MQ3 乙醇
//MQ5 甲烷
//MQ7 CO
//MQ135 氢气typedef struct
{int   ID;double adcx;double Vout;double Rs;double R0;}MQ;//各个气体传感器的可调负载电阻的电阻值RL(通过万用表测量A-H端得)
//单位:KΩ
#define MQ3_RL   0.43
#define MQ5_RL   2.15
#define MQ7_RL   2.55
//#define MQ8_RL   2.55
#define MQ135_RL 2.59//各个气体传感器的在洁净空气中的电阻值R0(通过2、3、4公式计算得)
//单位:KΩ
#define MQ3_R0   0.8369
#define MQ5_R0   4.30
#define MQ7_R0   5.0375
//#define MQ8_R0   145
#define MQ135_R0 3.3760#define //功能:将获取到的AO值转化为传感器电阻值
//adcx:ADC获取的值 RL:传感器负载电阻值
double adc_to_R(double Vout,double RL);//测量ADC的值并转化成电阻打印到串口一上
//MQx:传感器型号 ADC_Channel_x:选用的ADC通道x MQx_RL:传感器可调负载电阻值
void MQ_printf(MQ* MQx,u8 ADC_Channel_x,double MQx_RL,double MQx_R0);
#endif
#include "mq.h"double mq3_CH3OH,mq5_CH4,mq7_CO,mq135_H2;
double mq;
//功能:将获取到的AO值转化为传感器电阻值
//adcx:ADC获取的值 RL:传感器负载电阻值
double adc_to_R(double Vout,double RL)
{double temp = 0.0;	double Rs = 0.0;Rs = (3.3 - Vout)/Vout * RL;//敏感体电阻值return Rs;
}//测量ADC的值并转化成电阻打印到串口一上
//MQx:传感器型号 ADC_Channel_x:选用的ADC通道x MQx_RL:传感器可调负载电阻值
void MQ_printf(MQ* MQx,u8 ADC_Channel_x,double MQx_RL,double MQx_R0)
{u8 txbuffer[100];double ppm = 0.0;double x = 0.0,y = 0.0;MQx->adcx = Get_Adc_Average(ADC_Channel_x,10);    //从ADC通道x获取ADC的值MQx->Vout = MQx->adcx*(3.3/4096);
//	printf("Vout:%f\r\n",MQx->Vout);MQx->Rs = adc_to_R(MQx->Vout,MQ3_RL) ;             //通过获取的ADC值求传感器电阻值x = MQx->Rs/MQx_R0;switch(MQx->ID){case 3:mq3_CH3OH=ppm = pow((0.5447/x),1.0/0.6785);break;case 5:mq5_CH4=ppm = pow(43.8499*x,-1.7381);break;case 7:mq7_CO=ppm = pow(98.3224*x,-1.4583);break;case 8:break;case 135:mq135_H2=ppm = pow(3.5314*x,-2.0437);break;}mq = ppm;sprintf((char *)txbuffer,"MQ%d_ppm:%.5f",MQx->ID, ppm);printf("%s",txbuffer);if(MQx->ID == 3) printf("mg/L\r\n\r\n");else printf("ppm\r\n\r\n");
}

主函数调用

main.c

#include "delay.h"
#include "sys.h"
#include "usart.h"#include "mq.h"#include "adc.h"#include "led.h"
//c库
#include "string.h"//本程序只供学习使用,未经作者许可,不得用于其它任何用途
//STM32F103最小系统板
//MQ传感器驱动代码	   
//技术交流群:737327353
//修改日期:2024/4/21
//版本:V1.0
//版权所有,盗版必究。
//Copyright(C) CSDN 小光学嵌入式					  
/
/******************引脚接口**************************
MQ3AO	PA1	
MQ5AO	PA4
MQ7AO	PA5
MQ135AO	PA7
************************************************/int main(void){		u16 timeCount=0;MQ MQ3,MQ5,MQ7,MQ8,MQ135;MQ3.ID = 3;MQ5.ID = 5;MQ7.ID = 7;MQ8.ID = 8;MQ135.ID = 135;delay_init();	    	 //延时函数初始化	  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级uart_init(115200);	 //串口初始化为115200Adc_Init();LED_Init();while(1){//获取MQ3、MQ5、MQ7、MQ135传感器对应气体浓度:乙醇、甲烷、CO、H2MQ_printf(&MQ3,MQ3_adc_channel,MQ3_RL,MQ3_R0);MQ_printf(&MQ5,MQ5_adc_channel,MQ5_RL,MQ5_R0);MQ_printf(&MQ7,MQ7_adc_channel,MQ7_RL,MQ7_R0);MQ_printf(&MQ135,MQ135_adc_channel,MQ135_RL,MQ135_R0);delay_ms(1000);}}

最后展示一下我的ONENET上位机:
在这里插入图片描述

总结

本文针对MQ3进行了详细的教程,MQ5、MQ7、MQ135等MQ系列的计算方法基本上都是一样的,如果有任何问题欢迎指正哦!
加入小光嵌入式交流群(qq群号:737327353)免费获取博主所有资料哦!如果群里没有请咨询群主哦!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/1434.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

网络安全产品---堡垒机

what 在网上搜索 运维审计与风险控制系统就是是堡垒机 我认为的堡垒机就是提供高效运维、认证管理、访问控制、安全审计和报表分析功能的云服务设备 实现高效运维的同时最大程度控制运维风险。 how 能够对运维人员维护过程进行全面跟踪、控制、记录、回放 支持细粒度配置…

政企版 WPS Pro 专业版注册安装教程

政企版 WPS Pro 专业版安装及激活步骤 第 1 步&#xff1a;下载压缩包&#xff08;内含注册码&#xff09;【无解压密码】。 第 2 步&#xff1a;解压缩后&#xff0c;运行 exe 文件&#xff0c;默认步骤安装即可。 第 3 步&#xff1a;安装完成后&#xff0c;新建一个 Word …

【AI面试】工作和面试过程中,经常遇到的其他问题汇总二(持续更新)

本篇是延续第一篇:【AI面试】工作和面试过程中,经常遇到的其他问题汇总一(持续更新) 如果你还没有看过上一篇文章,建议先去看看,尽管这两篇文章没有什么交集。 一、在CNN和transformer的训练过程中,学习率的调整,有什么经验? 在训练卷积神经网络(CNN)和Transform…

使用QQ邮箱进行登录验证

使用场景不多说&#xff0c;接下来直接看实现~ 登录到QQ邮箱&#xff0c;进入设置 打开IMAP/SMTP服务&#xff0c;记得把授权码记录下来&#xff0c;后面配置文件中需要用到 新建application的配置文件 spring:mail:# 指定邮件服务器地址host: smtp.qq.comusername: 你自己的q…

ROS 2边学边练(31)-- 管理大工程

前言 往往现实中的工程都是会包含很多节点很多参数很多主题的那种&#xff0c;如果单独通过各种ros2 run命令进行启动管理&#xff0c;恐怕难以招架&#xff0c;主要还是通过launch文件的方式进行管理&#xff0c;而launch文件也可以像节点那样按功能的不同模块化&#xff0c;最…

【学习】黑盒测试用例设计方法都有哪些

在软件测试中&#xff0c;黑盒测试是一种重要的测试方法&#xff0c;它专注于软件的外部行为&#xff0c;而不关心其内部结构和实现。黑盒测试的目标是确保软件的功能符合需求规格说明书中的要求。为了有效地进行黑盒测试&#xff0c;需要设计合理的测试用例。本文将详细介绍黑…

RocketMQ的设计理念和目标

一、设计理念&#xff1a; RocketMQ设计基于主题的发布与订阅模式&#xff0c;其核心功能包括消息发送、消息存储&#xff08;broker&#xff09;、消息消费&#xff0c;整体设计追求简单与性能统一&#xff0c;主要体现在以下三个方面。 1.1、NameServer设计&#xff0c;摒弃…

excel文件预览: luckyexcel+luckysheet

luckyexcel 使用 npm i luckyexcel --saveluckysheet 使用 luckysheet文档 克隆Luckysheet源码到本地 git clone https://github.com/dream-num/Luckysheet.git安装依赖 npm install npm install gulp -g 开发 npm run dev打包 npm run build本地引入 npm run build 后 …

Ansible 连接受控端sudo超时

最近在装Ansible&#xff0c;有一台受控端负载重&#xff0c;响应慢。当用Ansible连接它时&#xff0c;总是提示超时。 现象 主控端 执行脚本 ansible 192.168.5.37 -m shell -a ip a| grep 192.168.192.168.5.37 | FAILED | rc-1 >> Timeout (12s) waiting for priv…

【Android】Activity task和Instrumentation杂谈

文章目录 activity taskInstrumentation机制参考 Android不仅可以装载众多的系统组件&#xff0c;还可以将它们跨进程组成ActivityTask&#xff0c;这个特性使得每个应用都不是孤立的。 activity task 从数据结构角度看&#xff0c;Task有先后之分&#xff0c;源码实现上采取了…

基于SpringBoot+Vue钢材销售管理系统的设计与实现

系统介绍 为了更好地发挥本系统的技术优势&#xff0c;根据钢材销售管理系统的需求&#xff0c;本文尝试以B/S经典设计模式中的Spring Boot框架&#xff0c;JAVA语言为基础&#xff0c;通过必要的编码处理、钢材销售管理系统整体框架、功能服务多样化和有效性的高级经验和技术…

高级IO简介

一、非阻塞IO 阻塞其实就是进入了休眠状态&#xff0c;交出了 CPU 控制权。 普通文件的读写操作是不会阻塞的&#xff0c;不管读写多少个字节数据&#xff0c; read() 或 write() 一定会在有限的时间内返回&#xff0c;所以普通文件一定是以非阻塞的方式进行 I/O 操作&…

【Visual Studio 2012中文版】下载安装以及使用方法

文章目录 前言一、下载安装包二、安装步骤1.双击VS2012_ULT_chs.iso文件打开2.双击vs_ultimate.exe打开安装程序3.选择要安装的功能4.软件正在安装&#xff0c;请耐心等待10分钟5.安装成功&#xff0c;点击“启动”6.激活码&#xff08;产品密钥&#xff09; 三、VS2012使用&am…

CRMEB Pro版营销功能规则解读

现在&#xff0c;无论是中小型企业拓宽渠道&#xff0c;还是传统企业转型&#xff0c;基本都在考虑布局线上&#xff0c;做微商城是一大趋势&#xff0c;相比传统第三方电商平台&#xff0c;独立部署的商城系统自主性更强&#xff0c;功能开发也更灵活。其中&#xff0c;作为电…

Java基础----字节流和字符流

1.使用字节流拷贝文件夹 import java.io.*;public class Tset01 {public static void main(String[] args) throws IOException {//拷贝一个文件夹&#xff0c;考虑子文件夹//E:\hello -> E:\aaaFile srcnew File("E:\\hello");File destnew File("E:\\dest…

英语写作中available容易忽略的用法

Available 的一般用法没有问题&#xff0c;但它的下面用法容易被我们忽略。 比较下面两句&#xff1a; There is no water. There is no water available. 这两句都翻译为“没有水”&#xff0c;但上一句的意思就是“没有水”&#xff0c;而下一句意味着“需要水但没有水”…

vue3 -- 项目使用自定义字体font-family

在Vue 3项目中使用自定义字体(font-family)的方法与在普通的HTML/CSS项目中类似。可以按照以下步骤进行操作: 引入字体文件: 首先,确保你的字体文件(通常是.woff、.woff2、.ttf等格式)位于项目中的某个目录下,比如src/assets/font/。 在全局样式中定义字体: 在你的全局…

[阅读笔记25][WebArena]A Realistic Web Environment for Building Autonomous Agents

这篇论文提出了WebArena这个环境与测试基准&#xff0c;在24年1月发表。 之前的agent都是在一些简化过的合成环境中测试的&#xff0c;这会导致与现实场景脱节。这篇论文构建了一个高度逼真、可复现的环境。该环境涉及四个领域&#xff1a;电子商务、论坛讨论、软件开发和内容管…

多种情况下合并单元格(S-Table+Vue3)

合并单元格(S-TableVue3) 跨行合并&#xff1a;rowspan“合并单元格的个数” 跨列合并&#xff1a;colspan"“合并单元格的个数” 文章目录 合并单元格(S-TableVue3)第一列跨行合并单元格templatescript效果 多列跨行合并单元格templatescript效果图 多行合并可参考 第一列…

exceljs库实现excel表样式定制化

概览 xlsx 是前端最热门的 Excel 导出方案&#xff0c;又叫做 SheetJs&#xff0c;默认不支持修改 Excel 的样式。而exceljs库就可以做到自定义excel表样式&#xff0c;下面来介绍一下其使用方法 一. 完整示例 代码示例 const exportTemplate2 () > { // 创建工作簿 …