STM32入门教程:如何使用烟雾传感器进行烟雾检测

文章目录

  • 前言
  • 一、学习目的
  • 二、模块介绍
  • 三、代码记录
  • 总结

  • 前言

           这次记录一下烟雾传感器的学习,由于烟雾传感器的资料比较杂,算法比较多,对我来说也比较难,所以我的代码中算法部分是不太具有参考价值,但是也可以做到随烟雾浓度的变化数值呈线性相关,以后再记录完善。


    一、学习目的

           我的学习目的是通过STM32的ADC功能,学会使用烟雾传感器检测气体的浓度,并用串口助手将气体浓度的数值实时打印出来。

    二、模块介绍

           我使用是MQ-2烟雾传感器模块,它属于二氧化锡半导体气敏材料,当它与烟雾接触时,如果晶粒间界处的势垒收到烟雾的调至面变化,就会引起表面导电率的变化。且当烟雾浓度增大时,导电率增大,电阻变小,电压增大。所以就可以用电压的变化表示烟雾的浓度。

            MQ-2的引脚也和大部分传感器一样是四个(VCC,GND,AO,DO),不一样的是,我这次想通过ADC功能获取电压值,并表示为气体浓度,而不是仅仅通过检测是否达到阈值后来改变某一个IO口的电平(例如之前记录的光敏传感器声音传感器,都是通过光照/声音达到一个阈值后,改变某一个IO的电平,再通过读取函数读取这个IO口的电平,进而判断是光明黑暗/有声无声)。所以烟雾传感器给我的感觉是要远复杂于一般传感器的。

    要注意的是,烟雾传感器由于内部有电阻丝作用,要先接通电源预热20秒,测得结果才会稳定。烟雾传感器发热属于正常现象,但是如果烫手就不正常了哈,那就建议立刻停止实验。

    接线方面:由于要实时获取电压,所以要使用的是AO引脚(检测模拟信号的变化)

    VCC–5V

    GND–GND

    AO–PA0(PA0具有ADC功能,实时输出MQ-2的电压信号)

    三、代码记录

    mq.h

    #ifndef __MQ2_H
    #define __MQ2_H
    #include "stm32f10x.h"
    
    
    void ADC_Pin_Init(void);
    u16 ADC_Trans(void);
    
    #endif
    
    

     mq.c

    #include "mq2.h"
    #include "delay.h"
    #include "sys.h"
    #include "stm32f10x_tim.h"
    #include "stm32f10x_rcc.h"
    #include "stm32f10x_adc.h"
     
    void ADC_Pin_Init(void)        //初始化PA0口作为ADC检测端,并且初始化ADC通道1
    {
    	GPIO_InitTypeDef GPIO_InitStruct;
    	ADC_InitTypeDef ADC_InitStruct;
    	
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_ADC1,ENABLE);
    	
    	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AIN;
    	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0;
    	GPIO_Init(GPIOA,&GPIO_InitStruct);
    	
    	ADC_InitStruct.ADC_ContinuousConvMode = ENABLE;  //多次连续变换
    	ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right;
    	ADC_InitStruct.ADC_Mode = ADC_Mode_Independent;
    	ADC_InitStruct.ADC_NbrOfChannel = 1;
    	ADC_InitStruct.ADC_ScanConvMode = DISABLE;
    	ADC_Init(ADC1,&ADC_InitStruct);
    	
    	ADC_RegularChannelConfig(ADC1,ADC_Channel_0,1,ADC_SampleTime_239Cycles5);
    	
    	ADC_ITConfig(ADC1,ADC_IT_EOC,ENABLE);
    	
    	ADC_Cmd(ADC1,ENABLE);
    }
    
    u16 ADC_Trans(void)       //数据处理,求电压值的平均数
    {
    	u16 adc_value = 0;
    	u8 i = 0;
    	
    	for(i = 0; i < 50; i++)
    	{ 
    		ADC_SoftwareStartConvCmd(ADC1,ENABLE);	
    		adc_value = adc_value + ADC_GetConversionValue(ADC1);
    	}
    	
    	return adc_value / 50;
    }
    
    

           mq.c文件将ADC和烟雾传感器写在了一起,主要就是初始化PA0口ADC的通道1,和一个数据处理函数。

    要注意的是,初始化ADC1时,一定要将ADC_InitStruct.ADC_ContinuousConvMode设置为ENABLE!!即设置为多次连续变换模式,否则串口将只输出第一次的值。

    【数据处理时,本来需要通过while(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC) != SET)来检测转换是否结束,但我的代码写完后会始终卡死在这个循环里。这也是很遗憾的一个点,如果大家有什么好的方法可以告诉我一下。】

    main.c

    #include "delay.h"
    #include "sys.h"
    #include "usart.h"
    #include "mq2.h"
     
    
    int main(void)
    {
    	u16 ad = 0;
    	
    	delay_init();
    	uart_init(115200);
    	printf("初始化完成\r\n");
    	ADC_Pin_Init();
    	while(1)
    	{
    		ad = ADC_Trans();
    	//	printf("电压为:%f\r\n",3.3/4095*ad);
    		printf("烟雾浓度为:%.2f\r\n",ad * 99 / 4096.0);
    		delay_ms(1000);
    	}
    }
    
    

    串口通信的代码就不作记录了,代码烧录后,打开串口助手就可以看到结果了。


     总结

           代码虽然看上去简单,那其实也是因为我的算法比较拉跨,我也看了很多大佬的算法,确实比较高级,但是由于有的代码并不完整,有的用的是STM32F4系列的芯片,我始终未能找到一个我能掌握的高级算法,以后有了进展再另作记录。

    物联沃分享整理
    物联沃-IOTWORD物联网 » STM32入门教程:如何使用烟雾传感器进行烟雾检测

    发表评论