⏩ 大家好哇!我是小光,嵌入式爱好者,一个想要成为系统架构师的大三学生。
⏩在环境检测中我们经常会用到检测气体的传感器,检测乙醇、甲烷、一氧化碳、氢气等等,博主呕心沥血对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)免费获取博主所有资料哦!如果群里没有请咨询群主哦!