MCU之从0开始做工业气体传感器仪表

MCU  ·  2025-11-05

可燃气体检测仪表实现

一、单位说明

1、ppm:气体体积百分比含量的百万分之一,是无量纲单位。

  • ppm全称为parts per million,中文指百万分之一。表示在总量为一百万份的混合物中,有多少份是我们需要关注的物质。换句话说,1ppm等于1/1,000,000
  • 虽然无量纲量本身没有量纲,但是它也有时被加以无量纲的单位。在分子和分母使用同样的单位(kg/kg或mol/mol),有时可以帮助表达所测量的数值(如质量百分浓度或摩尔分数等)。
  • 1ppm=1mg/kg 1ppm=1mg/L 1ppm= 0.0001%
  • 例如10ppm二氧化碳指的是空气中含有百万分之10的二氧化碳,由于PPM单位是无量纲单位,大部分的能够检测PPM级别的气体检测仪,都是用来检测工作环境中气体微泄漏用的,因为气体微泄漏是很危险的,长时间的气体微泄漏可能会引起大事故,所以我们需要用PPM级的气体检测仪来及时排除微泄漏的地方。

2、Vol:气体体积百分比,是物理单位。

  • Vol就是某一种特定气体的体积在空气中所占的百分比。如5%VOL甲烷,代表的意思就是甲烷在空气中所占的体积是5%。我们也可以设定某一个百分比数值的VOL作为报警点,当某种气体的含量达到或者超过这个设定值时,气体检测仪就会报警
  • 例:5%Vol的甲烷:指甲烷体积在混合气体中占5%

3、LEL:可燃气体的爆炸下限浓度(到达100%遇明火大概率爆炸)

  • 可燃气体的概念是指能够与空气(或氧气)在一定的浓度范围内均匀混合形成预混气,遇到火源会发生爆炸,那么,这个可燃气体在空气中能引爆的最低体积百分比浓度,也就是我们说的气体爆炸下限浓度就是LEL%,简称是爆炸下限。
  • 它的单位也是百分比,即把爆炸下限分为一百份,一个单位为1LEL%,爆炸下限里面的气体体积的浓度是用VOL%来表示的。
  • 例如氢气的LEL4%VOL,即它在空气中的体积百分比达到4%VOL时,遇明火就会爆炸,因此将4%VOL作为100%危险来看,称为100%LEL,即4%VOL=100%LEL,那么1%VOL=25%LEL

二、LEL%、VOL%和PPM三者单位的换算

  • 首先是VOLPPM的换算,这两个单位的换算比较简单,因为%VOL是体积的百分比,而PPM则是体积的百万分比,所以1%(VOL)=10000PPM
  • VOLLEL的换算,这两个的换算我们要先找出该可燃气体的爆炸下限值是多少,空气中可燃气体浓度达到其爆炸下限值时,我们称这个场所的可燃气环境爆炸危险度为百分之百,例如甲烷的LEL5%VOL,即它在空气中的体积百分比达到5%VOL时,遇明火就会爆炸,因此将5%VOL作为100%危险来看,称为100%LEL,即5%VOL=100%LEL,那么1%VOL=20%LEL
  • PPMLEL的换算,这两个没办法直接换算,要先将LEL换算成VOL,再由VOL换算成PPM。以5%VOL甲烷为例,20%LEL的甲烷是多少PPM,根据计算公式得出:

    • 20(%LEL)×5(%VOL)×1,000,000ppm=10000PPm
    • 例:10%LEL的甲烷(爆炸下限5%)。
    • 10%LEL=10%×5%Vol=0.5%Vol
    • 0.5%Vol=0.05×1,000,000ppm=5000ppm
  • 假设25%LEL10%LEL都为报警点。甲烷的爆炸下限为5%体积比,把这个5%体积比一百等分,让5%体积比对应100%LEL,也就是说,当检测仪数值抵达10%LEL报警点时,相当于此时甲烷的含量为0.5%体积比。当检测仪数值抵达25%LEL报警点- 时,相当于此时甲烷的含量为1.25%体积比。
  • 所以,第一阶段报警不是已经危险了,此时是在提示要马上采取相应的办法,比方开启排气扇或是堵截一些阀门等,离真实危险的爆炸下限还有很大一段距离,这样才会起到报警提示的作用。

三、参数手册图表分析

  • 甲烷的LEL5%VOL5%VOL=100%LEL,那么1%VOL=20%LEL

image-20251105133027220

​ NAP-55A线性数据图

image-20251105133043307

​ NAP-57A线性数据图

image-20251105133137993

  • 根据产品参数这里的描述可知,当甲烷气体浓度达到1%Vol,也就是20%LEL时,电压输出在37-53mv之间,换算一下,与上面的分析结果大体一致。
  • 前期我们大概使用1%LEL=2mv的比例关系去做气体浓度的量程,后面根据实际环境去调整。则0.2mv = 0.1%LEL

image-20251105133203534

四、电路设计

  • 电路上设计了减法器电路,还设置了可调电阻输出对比电压,开机后校准可调电阻电压与传感器在干净空气中电压一致,此时将传感器与可调电阻输出连接到减法器,当二者压值相同时,减法器输出0电压,当R16=R15R18=R17时,通过运放公式Vout = R18/R16(VA-AD) =10,放大10倍提高精度,传感器检测到气体变化,压值发生变化,使得减法器输出与干净空气时的电压之差,此时可根据手册给出的变化特性去计算变化范围。

image-20251105133211429

​ 运放电路与传感器、可调电阻对比电压输出

  • 如图所示,红色区域为可调电阻调节旋钮,因为每个传感器都会有一定阻值或电压的差异,用来改变对比电压,在运放上与传感器输出电压做对比,一般设置为无可燃气体时传感器的电压值,这样当二者电压相等,运放输出电压为0。
  • image-20251105133446765
  • 依据手册来看,手册上特性是有气体时升高电压,因其内部是惠斯通电桥结构,正反接都可以输出值,这里因为方便对比故使用反接来对比,当传感器检测到气体时,自身输出电压会降低一些,运放因为传感器电压与可调电阻的输出电压不一致,此时会输出二者的差值,此差值即为传感器的线性输出。
  • image-20251105133456685
  • 黄色区域按键为调试按键,粉色区域所指的排针是调试接口,当感觉读数与实际气体浓度有差异时,可以使用USB to TTL连接调试接口,按下调试按键,电脑上会显示一些数据,如图,V_Sensor为传感器电压的直接检测,V_ADC为运放对比放大10倍后的差值,V_RES为可调电阻电压的直接检测,此时可以根据传感器电压和可调电阻电压,去微调可调电阻,由于运放是放大10倍的,只要运放电压输出值在10以内都是合理的范围
  • image-20251105133502508
  • 此外还可以看到传感器探头上是要加缸体的,当不加时,探头暴露在空气中,灵敏度很高,当加上缸体,头部带有疑似活性炭等吸附功能的网面,会将气体附在网面上,与暴露在空气中的快入快出不同,是淡入淡出的,所以给气体测试会发现,读数上升有些慢,下降也会慢,此情况也符合实际中气体慢慢泄露的情况。

image-20251105133240052

  • 通过显示主板的485接口,接收每个传感器探头的数据并显示

    • 显示主板功能:4GMQTT上传、超标电话短信报警(使用非物联网卡)

      • 三路继电器控制(声光报警器、风扇等可选)
      • 探头读数屏幕显示,可翻页多显示
      • 485主从机,可扩展
      • LED和蜂鸣器报警(受环境限制,可能无法发现,应外接声光报警器)
      • 按键翻页、报警电话输入保存

image-20251105133307605

image-20251105133317997

五、算法设计(非使用版本,这里只做简要算法思路展示)

  • 思路:单片机的ADC12位ADC2的12次方为4096,测量范围0-3.3v,获取ADC值采样测量值,将采样值通过 (采样值/4096*3.3) 的公式转化为3.3v范围的电压值,此时电压值是一个浮点数,因检测范围是mv级别,将其乘1000,转为整数级别的mv表示,后面统计10次采样的电压,通过快速排序,将最小值放过在数组最前面,最大值放在数组最后面,此时可以忽略最大值与最小值,将其余数计算平均值,得到一个滤波后的电压值,发送给主机
  • 传感器电压值经过运放相减后放大10倍,静态时0.1mv实际为1mv,又因0.2mv = 0.1%LEL的比例关系,则计算时,先转为3V3比例 电压值,乘上1000,再除2可得到一个对应的%LEL比例值(带有小数点后一位数),可设置10-12%LEL第一次报警,20-24%LEL第二次报警


uint16_t num[];

uint8_t count = 0;

uint16_t adc_Value;

**float** temp;

 

uint16_t **GetAdc**() {

 

 HAL_ADC_Start_DMA((ADC_HandleTypeDef*) &hadc1, (uint32_t*) adc_Value,**sizeof**(adc_Value) / **sizeof**(adc_Value));  //这里只是为了表明启动ADC,不涉及真实实现

 temp = ( (**float**)adc_Value / 4096) * 3.3; //ADC值转化3.3V单位

 **return** (uint16_t)(temp * 1000);   //采样单位为mv,1V=1000mv,变为整数处理更好

}

 

// 比较函数用于 qsort 函数

**int** **compare**(**const** **void** *a, **const** **void** *b) {

 **return** (*(**int***) a - *(**int***) b); //返回负值,从小到大排序

}

 

uint16_t **GetMean**() {

 

 **double** sum = 0;

 num[count++] = GetAdc(); //获取采样值

 

 //滤波算法,10次采样之后,存入数组中,快速排序后忽略头尾的两个最大小值,将中间的值取平均计算

 **if** (count == 9) {

  **qsort**(num, count, **sizeof**(uint16_t), compare); //快速排序

  **for** (**int** i = 2; i < count - 2; i++) {

   sum += num[i];

  }

 }

 uint16_t value = (uint16_t) (sum / (count - 4));

 count = 0;

 **return** (uint16_t) (((((**float**) value / 4096) * 3.3) * 1000) / 2);

}

 

**int** **main**(){

 uint16_t LEL = GetMean();

 **if** (LEL > 120) {  //若12.0%LEL报警,大概对应24mv

  //报警操作

 }

 **printf**("气体报警范围:%d.%d LEL,不得大于15%%LEL", LEL/10, LEL%10);

 

 **return** 0;

}
 

 

至此,就可以实现对可燃气体的检测,同样也可以按照上面的思路更换传感器,更改一下代码,去检测其他气体。

下一篇:没有了
评论
LJ` Blog . All Rights Reserved. Theme Jasmine by Kent Liao.
冀ICP备2025127925号 冀公网安备13082402000074号