《正点原子BEE BLOCK模块资料》ATK-MB005模块使用说明

ATK-MB005模块使用说明


        1, 硬件连接

       这里以正点原子M48Z-M3最小系统板STM32F103版为例,给大家介绍一下模块和板卡的连接方法。其它板卡与模块的硬件连接方法,请大家在“ATK-MB005 烟雾传感器模块\3,程序源码\相应板卡例程文件夹\readme.txt”路径下查看。

       ATK-MB005 烟雾传感器模块可通过杜邦线与正点原子M48Z-M3最小系统板STM32F103版进行连接,具体的连接关系,如下表所示:


表1.1烟雾传感器模块与M48Z-M3最小系统板STM32F103版连接关系


        2,实验功能


       2.1 烟雾传感器模块测试实验


       2.1.1 功能说明

       在本实验中,串口会打印烟雾传感器模块DO端输出、AO端电压转换值和烟雾或可燃气体是否达到阈值等信息。需要查看这部分实验信息的用户,可用杜邦线将最小系统板STM32F103的PA9引脚和GND连接至外部的USB转串口设备,这样就可以通过XCOM上位机查看串口打印的信息了。

       用户还可以通过调节电位器来控制可燃气体的浓度检查的阈值。当检测到可燃气体浓度达到电位器设定的阈值时,STA灯亮;当检测到可燃气体浓度低于电位器设定的阈值时,STA灯熄灭。

       开发板的LED0闪烁,提示程序运行。


       2.1.2 源码解读

       打开本实验的工程文件夹,能够在./Drivers/BSP目录下看到ATK_SMOKE文件夹和ADC文件夹,其中ATK_SMOKE文件夹中就包含了烟雾传感器模块的驱动文件,ADC文件夹中就包含了ADC的驱动文件如下图所示:


 图2.1.2.1烟雾传感器模块驱动代码


图2.1.2.2 ADC驱动代码


       2.1.2.1 烟雾传感器模块驱动

       下面简要介绍atk_smoke.c中几个重要的API 函数。


       1. 函数atk_smoke_init ()

       该函数用于初始化烟雾传感器模块,具体的代码,如下所示:

/**
 * @brief       烟雾传感器模块初始化函数
 * @param       无
 * @retval      无
 */
void atk_smoke_init (void)
{
    GPIO_InitTypeDef gpio_init_struct = {0};
    ATK_SMOKE_DO_GPIO_CLK_ENABLE ();                 /* DO时钟使能 */
 
    gpio_init_struct.Pin = ATK_SMOKE_DO_GPIO_PIN;     /* DO引脚 */
    gpio_init_struct.Mode = GPIO_MODE_INPUT;                 /* 输入 */
    gpio_init_struct.Pull = GPIO_NOPULL;                       /* 无上下拉 */
    HAL_GPIO_Init(ATK_SMOKE_DO_GPIO_PIN, &gpio_init_struct);
    adc_init();                                                  /* 初始化ADC */
}

       atk_smoke_init () 函数负责初始化烟雾传感器模块的DO引脚,并将其配置为无上下拉输入模式;然后调用adc_init() 函数初始化 ADC 采集通道,用于获取AO端电压转换值。


       2. 函数atk_smoke_adc_converted_value ()

该函数用于获取AO端电压转换值,具体代码,如下所示:

/**
 * @brief       读取AO端电压转换值
 * @param       无
 * @retval      AO端电压转换值
 */
uint32_t atk_smoke_adc_converted_value (void)
{
    return adc_get_result_average(ADC_ADCX_CHY, 10);
}

       该函数通过adc_get_result_average()函数得到ADC通道的电压转换值,并做了采集10次ADC取平均值的操作,这样数据会更稳定可靠。


       3. 函数atk_smoke_get_ppm ()

       该函数用于求可燃气体的浓度值,具体代码,如下所示:

/**
 * @brief  求ppm值函数
 * @param  无
 * @retval ppm
 * @note
 * 本函数根据MQ-2_规格书提供的传感器灵敏度特性曲线来拟合成幂函数
 * 根据Rs/R0推算ppm,所以拟合函数时,x轴为Rs/R0,y轴为ppm,推导的式子为:y = ax^b
 * 规格书上的曲线没有每个点的具体数值,所以只能大致估算,会存在误差,大家可以多次标定减少误差
 */
float atk_smoke_get_ppm(void)
{
    uint32_t adc_converted_value;  /* AO端电压转换值 */
    float vrl;                          /* AO端的电压(传感器串联的负载电阻RL上的电压) */
    float rs;                           /* 当前传感器的电阻 */
    float ppm;                          /* 可燃气体平均浓度 */
    float rs0;/* 传感器电阻比(在测试环境传感器的阻值比上在洁净空气环境传感器的阻值) */
    
    adc_converted_value = atk_smoke_adc_converted_value();
    printf("AO端电压转换值为:%d\r\n", adc_converted_value);
    
    vrl = (float)adc_converted_value / 4096.f * VREF;  /* 计算AO端的电压 */
    printf("AO端电压(vrl)为:%.3fV\r\n", vrl);
    
    rs = (float)(VC - vrl) * RL / vrl;                  /* 计算传感器的阻值 */
    printf("当前MQ2传感器电阻值为:%.1fkΩ\r\n", rs);
    
    rs0 = rs / R0;  /* Rs / R0 */
    printf("Rs/R0 = %0.3f\r\n", rs0);
 
    /* y = ax^b; 其中x为Rs/R0,a和b的取值根据数据手册图表自行拟合成幂函数 */
    ppm =  A * pow(rs0, B);
 
    return ppm;
}

       该函数通过幂函数y = ax^b,得到可燃气体的浓度值的。其中x为Rs/R0,y为ppm,即可燃气体浓度值。a和b分别是atk_smoke.h头文件中的宏定义A和B。atk_smoke.h头文件相关宏定义如下:

#define RL      1         /* 根据空气质量传感器模块原理图可知:RL = 1k */ 
#define R0      34     /* MQ2在洁净空气中的阻值,需预热后测量,这里取平均值得到 */
#define VC      5.0f     /* MQ2供电电压,接5V */
#define VREF    3.3f     /* STM32的ADC的参考电压 */
#define A       45.852   /* y = ax^b 的 a */
#define B       -1.649   /* y = ax^b 的 b */

       本函数获取到的可燃气体浓度值只是一个大概的值,不是精准的。原因如下:第一,不同MQ2模块特性可能存在一些差异,原因:传感器内阻不同、使用时间和使用环境不同,比如被传感器接触到水、腐蚀液等,会导致传感器灵敏度不同,关于MQ2使用要避免的事项,请查看MQ2规格书。第二,本函数是多次测试取平均值得到的拟合幂函数,函数本身也存在误差。如果大家觉得精度不够,可以测试并修改我们上面的相关宏定义,以求得更佳的精准度。

       特别注意:追求更高精度的话,我们最容易修改的宏定义就是R0了,方法如下:

       1, 首先将开发板和模块正确连接好,并放在洁净的空气中测试。

       2, 传感器预热(建议大于5分钟)。

       3, 通过XCOM查看传感器的电阻值,数值比较稳定即可。

       4, 将R0宏定义的值修改为这个新测的传感器电阻值即可。


图2.1.2.1.1 修改R0宏定义的值


       2.1.2.2 ADC驱动

       在图2.1.2.2中,adc.c 和 adc.h 为 ADC 驱动文件,包含了 ADC通道的初始化,并实现了多次采样取平均值等功能。我们就是使用其中的adc_get_result_average()函数来获取AO端电压转换值的。关于ADC的驱动介绍,请查看正点原子各个开发板对应的开发指南中ADC章节。


       2.1.2.3 实验测试代码

       实验的测试代码在demo.c文件中,该文件在工程根目录下的 User文件夹。测试代码的入口函数为 demo_run(),具体的代码,如下所示:

/**
 * @brief       例程演示入口函数
 * @param       无
 * @retval      无
 */
void demo_run(void)
{
    float ppm;                   /* 可燃气体平均浓度 */
    
    atk_smoke_init();           /* 初始化烟雾传感器模块 */
    
    printf("烟雾传感器模块读取数据实验\r\n");
    printf("检测浓度范围:300~10000ppm\r\n");
    
    while (1)
    {
        printf("DO端输出为:%d\r\n", ATK_SMOKE_DO);
        
        ppm = atk_smoke_get_ppm();    /* 拟合函数换算出ppm */
        
        if(ppm<300)
        {
            printf("可燃气体平均浓度小于300ppm\r\n");
        }
        else if(ppm>10000)
        {
            printf("可燃气体平均浓度大于10000ppm\r\n");
        }
        else
        {
            printf("可燃气体的平均浓度为:%0.3fppm\r\n", ppm);
        }
        
        if(ATK_SMOKE_DO == 0)
        {
            printf("可燃气体浓度达到阈值\r\n");
        }
        else
        {
            printf("可燃气体浓度未达到阈值\r\n");
        }
        
        printf("\r\n\r\n");
        
        LED0_TOGGLE(); /* 闪烁LED,提示系统正在运行. */
        
        delay_ms(500);
    }
}

       从MQ2规格书知道,它的可燃气体测试范围是:300~10000ppm,所以这里的demo_run函数判断ppm<300和>10000就打印提示信息;ppm值在300~10000范围才会打印ppm值。然后,读取DO值可以判断可燃气体浓度是否达到电位器设置的阈值,并通过串口打印。最后,LED0闪烁表示程序正常运行。


       2.1.3 实验现象

       将烟雾传感器模块按照第一节“硬件连接”中介绍的连接方式与开发板连接,并将实验代码编译烧录至开发板中。本实验使用串口输出调试信息,因此需将开发板的 PA9连接至 DAP 虚拟串口(或 USB 转 TTL 模块)的 RX引脚。完成连接后,可通过串口调试助手XCOM查看实验信息输出,如下图所示:


图2.1.3.1 串口调试助手显示内容


       注:其它现象请看2.1.1功能说明。


请使用浏览器的分享功能分享到微信等