聚丰项目 > 基于STM32的高精度气体传感器的设计

基于STM32的高精度气体传感器的设计

本项目应用电调制红外光源,根据朗伯—比尔(Lambert-Beer)吸收定律,采用热释电红外传感器,主要设计了一款高精度的气体传感器,用于检测煤炭经过燃烧以后均匀气体中CO2、CO、SO2、H2的浓度,从而达到检测煤炭中含C和S的百分比。

h1654155909.0656 h1654155909.0656

分享
1 喜欢这个项目
团队介绍

h1654155909.0656 h1654155909.0656

团队成员

陈新喜 副教授

分享
项目简介
本项目应用电调制红外光源,根据朗伯—比尔(Lambert-Beer)吸收定律,采用热释电红外传感器,主要设计了一款高精度的气体传感器,用于检测煤炭经过燃烧以后均匀气体中CO2、CO、SO2、H2的浓度,从而达到检测煤炭中含C和S的百分比。
硬件说明

一:热释电红外传感器的组成和工作原理

           0b3a1c086b03f4e963d98615

图1双探测元热释电红外传感器内部结构图  图2:双探测元热释电红外传感器实物图

热释电红外传感器和热电偶都是基于热电效应原理的热电型红外传感器。不同的是热释电红外传感器的热电系数远远高于热电偶,其内部的热电元由高热电系数的铁钛酸铅汞陶瓷以及钽酸锂、硫酸三甘铁等配合滤光镜片窗口组成,其极化随温度的变化而变化。为了抑制因自身温度变化而产生的干扰 该传感器在工艺上将两个特征一致的热电元反向串联或接成差动平衡电路方式,因而能以非接触式检测出物体放出的红外线能量变化并将其转换为电信号输出。

热释电红外传感器在结构上引入场效应管的目的在于完成阻抗变换。由于热电元输出的是电荷信号,并不能直接使用,因而需要用电阻将其转换为电压形式 该电阻阻抗高达104MΩ,故引入的N沟道结型场效应管应接成共漏形式 即源极跟随器 来完成阻抗变换。热释电红外传感器由传感探测元、干涉滤光片和场效应管匹配器三部分组成。

1是一个双探测元热释电红外传感器的结构示意图。使用时D端接电源正极,G端接电源负极,S端为信号输出。该传感器将两个极性相反、特性一致的探测元串接在一起,目的是消除因环境和自身变化引起的干扰。

二:电调制非分光红外传感器气体分析机理:

当红外光通过待测气体时,气体分子对特定波长的红外光有吸收作用,其吸收关系服从朗伯—比尔(Lambert-Beer)吸收定律:设平行入射光的强度为I0,出射光的强度为I1,气体介质的厚度为L,气体的浓度为c,气体的吸收系数为,则其关系表达式为:

                                    --1

其中是表示不同气体的吸收系数,是表示不同气体的浓度。

当为多种混合气体时,为了分析特定特定的气体组分,需要在传感器或者红外光源前安装一个适合分析气体吸收波长的窄带滤光片,使传感器的信号变化只反映被测气体的浓度变化。

  三:硬件电路设计

     根据系统的设计要求,本系统的主要由一下几个模块组成:

图3:系统硬件框图

3.1  STM32主控电路图

 

         图4:STM32主控电路及平台硬件图

3.2  A/D转换电路

图5:A/D转换电路原理图

3.3:信号处理电路

 

     图6:信号处理电路图


软件说明

4.1上位机监控软件

4.2 下位机控制程序

#include

#include "absacc.h"

#include "intrins.h"

//#include "string.h"

//#include "math.h"

#include

//#include

 

#define  sum    (2)   //108   (76)  (140)//(28)   (22)      (240)

#define  Average        (10)

#define  Full_Scale     (65000)   //TBD adjust volatile resistance to get the value

#define  Coefficient    (6500)    //TBD

#define  nCHANNEL       (2)

 

bit              sample_flag,sampling_enabled;

//uint xdata signal_buffer[10],temp_buffer[10];

uchar    data   count,channel,Txd_count;

uint     xdata   sample_value[3][sum],average[3],adjust_value ;  //signal_value[3],temp_value[3];

 

//uint     xdata   signal_average,temp_average;

uint     xdata   concentration;

//longint  xdata   signal_sum,temp_sum;

 

unsigned long int data sampling_buffer,sample_value24;

void data_processing(void)

{

     uchar idata         i,j,checkout;

//  uint xdata          tmp;

//  longint  xdata         signal_sum;

//  float idata         tmp_val;

    EA=false;

    EX0=false;       

//  SCLK=true;  //reset the a/d chip       

 

 /*    for ( i=0;i<sum-1;i++ )

        {       

               for ( j=i+1;j<sum;j++ )

                      {

                             if ( sample_value[i]<sample_value[j] )

                                   {

                                          tmp=sample_value[i];

                                             sample_value[i]=sample_value[j];

                                             sample_value[j]=tmp;

                                      }

                         }              

           }    */

 

   // signal_sum=0;

/*        for ( i=6;i<sum-6;i++ )

        {

               signal_sum+=sample_value[i];

           }

 

 

    average[!channel]=signal_sum/(sum-12);      */

//////////////////////////////////////////////////

  /*   for ( i=0;i<sum;i++ )

        {

               signal_sum+=sample_value[0][i];

           }

 

 

    average[0]=signal_sum/sum;                                    //use

   */

//  sample_value24=sample_value24/sum;             

    //average[0]=average[0]*2;  //test

 

/*        signal_sum=0;  

    for ( i=0;i<sum;i++ )

        {

               signal_sum+=sample_value[1][i];

           }

 

 

    average[1]=signal_sum/sum;           */

    //average[1]=average[1]*2;  //test                       

  ////////////////////////////////////////////

   /*  if ( sample_value[0][0]>0x7000 )

        {

            adjust_value=sample_value[0][0]-0x7000; 

           

            sample_value[2][0]=sample_value[1][0]+adjust_value;

        } */

 

  ////////////////////////////////////////////

 

    sample_flag=false;

        

 

    //if ( !channel )

       {

             Txd_count++;

 

               Send_Disp(0x55);

 

            i=0;

            j=0;

                  checkout=0;//i^j;

 

                  i=sample_value[0][0]>>8;     

                  j=sample_value[0][0]&0x00ff;

             checkout=i^j;

 

            Send_Disp(i);

            Send_Disp(j);    //       so2

 

                  i=sample_value[1][0]>>8;     

                  j=sample_value[1][0]&0x00ff;

             checkout=checkout^i^j;

 

            Send_Disp(i);

            Send_Disp(j);    //co2         h2o

 

             Send_Disp(Txd_count);

            Send_Disp(0);

 

             checkout=checkout^Txd_count^0;

            

          /*     i=sample_value[2][0]>>8;     

                  j=sample_value[2][0]&0x00ff;

             checkout=checkout^i^j;

 

            Send_Disp(i);

            Send_Disp(j);    //H2O         check   temp

         */   

            Send_Disp(checkout);       

          }

 

 

 

    //SCLK=false;

    _nop_();

    LED_Green=Txd_count/128;  //!LED_Green;

    EA=true;

    //EX0=true;

    

 

    /*

    maximal=sample_value[0];

    minimal=sample_value[0];

 

    for ( i=1;i<Filter_times;i++ )

        {

               if ( maximal<sample_value[i] )   

                     {

                               serial_number[0]=i;

                               maximal=sample_value[i];

                        }

                  else if ( minimal>sample_value[i] )

                     {

                            serial_number[0]=i;

                               minimal=sample_value[i];

                        }

                  

           }     */

    /* float idata nVoltage;

 

     sample_flag=false;

     count++;

    if ( count>Filter_times )   

       {

                 //signal_sum += adjust_signal();  //sample_value[0];      

                       

            nVoltage=signal_sum/Average;               

                 nVoltage=Full_Scale/nVoltage;

                 nVoltage=log(nVoltage);

                 concentration=nVoltage*Coefficient;

                

                 //ES=false;

                 Send_Disp(concentration&0x00ff);

                 Send_Disp(concentration>>8);

            //ES=true;

 

                 signal_sum=0;

                 temp_sum=0;

                 count=0;

          }

    else

       {

              ;//signal_sum += adjust_signal();  //sample_value[0];

                 //temp_sum   += adjust_signal(1);  //sample_value[1];

          }

          */

    

}

/*

uchar rec_len;

/*********************************************/

void Main(void)

{

   _nop_();

   _nop_();

   _nop_();

   Mcu_Init();

   Variable_Init();

   delay(1000);       //for a/d chip reset

   SCLK=false;

   EA=true;

   //EX0=true;

 

   while(1)

     {

       Watch_Dog=!Watch_Dog;

      scout();

      if ( sample_flag ) data_processing();

     }

}


演示效果

 经过软硬件的设计,将测试到的信号上传到上位机监控窗口,监测到的信号如图8和图9所示。

常温放箱体里(10HZ)

                   图8:信号波形(箱体内常温)

海绵隔热恒温

              图9:图8:信号波形(48度恒温箱体内检测)

由上面的测试数据可以看出,信号变化大概在130uV;测试精度高。


评论区(2 )
  • 动心忍性1234: 您好我是无线电杂志的编辑,我们对您的项目十分感兴趣,请问您有兴趣投稿吗?成为我们的作者除稿费外还有其他优厚条件。敬请参与。投稿请联系QQ260534978.

    回复

  • 可乐_47480004: 看不见图片

    回复