打印

信号处理 --- 正态分布在气体报警器中的应用

[复制链接]
2765|6
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 会笑的星星 于 2020-1-2 17:23 编辑

在实际应用中,当气体报警器检测到浓度超过阀值时,气体报警器发生报警。一般而言,单片机在处理气体传感器输出的数据时需要根据情况进行滤波,然后根据滤波结果来确定是否报警。这种处理方法比较常见,但是也有两个问题,第一个需要选择一个合适的滤波器,如果滤波器使用不当反而造成更差的结果。第二个使用滤波器时单片机都需要消耗一定的资源,比如平均值滤波,他就需要消耗一定的RAM空间。基于上述的两个问题,有没有一种可能直接利用传感器的数据而不需要使用特定滤波器对传感器的输出数据进行过滤呢,答案是真有。不过,这个需要用到一个数学模型 --- 正态分布(高斯分布)。

我们先来看看一个随机变量的分布,不用担心,只需要高中知识即可。


上图中,X的取值只有两个可能,当X=0时,发生的概率P(X=0) = 1-p,当X=1时,发生的概率P(X=1)=p,类似于这种X取值只有两种---非此即彼的分布被称为(0-1)分布。

举个例子,掷一枚硬币,我们知道正面朝上的概率 1/2,反面朝上的概率也是1/2。设硬币正面表示1,反面表示0,X表示硬币朝上的一面的值,那么X就只有两种取值,服从(0-1)分布。


知道(0-1分布)对我们有什么用呢?我们知道,气体报警器的MCU某一次检测到传感器的值有两种可能,一种是超过阀值,一种是小于阀值,很明显它服从(0-1)分布。假设超过阀值时X1=1,此时就是报警的概率为0.8,小于阀值时X1=0,是报警的概率只有0.2(这也是符合实际的)。


单一一次的采样值服从上表中的(0-1)分布,显然我们没有办法依赖单一一次采样来决定是否报警,但是我们可以依赖连续的多次采样来判断是否报警,怎么做呢。

如果我们从t0时刻开始,每隔100ms采集一次传感器数据,一共持续5s,一共采样50次,每次采样的结果服从(0-1)分布,这意味着第k次采样时,超过阀值时Xk = 1,低于阀值时Xk = 0,其中k = 1.2.3..........50。

令X = X1 + X2 + ...... + Xk + ...... +X50 ,这里随机变量X的含义是连续采样50次中,传感器的采样值超过阀值的次数。根据中心极限定理,n(根据经验值,n > 30,原则上n越大越好)个同分布(这里是(0-1)分布)的随机变量之和服从正态分布(严格来说是接近)。这意味着就我们要解决的问题来说,由于n = 50,因此X服从正态分布,这个正态分布的均值是μ = n*p = 50 * 0.8 = 40,标准差 σ = 根号(n*p*(1-p)) = 2.8,如下图就是一个典型的正态分布。



就所有服从正态分布的随机变量X而言,他们都有几个共同的特性:
  • 正态分布关于均值μ对称。
  • X落在以均值为中心,左右一个标准差范围内的概率是68.27%。
  • X落在以均值为中心,左右两个标准差的概率是95.45。
  • X落在以均值为中心,左右三个标准差的概率是99.73%。

根据正态分布的性质,当X <μ+2σ = 46时,对应发生的概率P(X < 46)= 0.98(P(X ≥ 46)= 1-0.98 = 0.02),也就是说X<46是一个极大概率的事情,对于这种极大概率发生的事情我们就不能认为此时的X满足报警条件。相反,X ≥ 46是一件极小概率的事情,这意味着假如这种极小概率的事情真的发生了,我们就有理由相信这是真的报警了。

因此,基于上述分析,我们只要从某一时刻开始,每隔100ms采样50次,然后统计超过阀值的情况,如果至少有45次采样值超过阀值,那么我们就认为应该触发报警了。理论分析完成了,接下来,我们就可以写程序了。

程序的实现如下:
unsigned char sensor_samp_v; //传感器的当前采样值
unsigned char sensor_th = 0x50; //假设sensor的报警阀值是0x50
unsigned char sensor_gre_th_count = 0; //超过阀值时的计数
unsigned char sensor_detect_cycle = 0; //检测周期

//100ms的软件定时器
void app_clk_100ms(void )
{
  if(sensor_detect_cycle != 0)
  {
    sensor_detect_cycle--;
      
    if(sensor_samp_v > sensor_th)
    {
      ++sensor_gre_th_count;
    }
  }  
  else
  {
    sensor_detect_cycle = 50;
    if(sensor_gre_th_count > 45)
    {
       //报警  
    }
    sensor_gre_th_count = 0; //重新计数
  }
}

上面的分析看上去比较复杂,但是程序的实现相比选择滤波器来处理传感器信号还是要简单不少的,这或许就是所谓的大道至简吧,就像物理学中哪些我们耳熟能详的公式F=ma、E=mc^2表面看上去都非常简单,但是其背后的道理却一点也不简单。


使用特权

评论回复
评论
andy520520 2020-12-23 09:05 回复TA
对于温度、气压这种连续的模拟量用一个边界值这样比对就瞎扯断,竟然还把正态分布还扯上 难道不应该加迟滞滞区间比较? 还在这瞎逼逼!!! 
xch 2020-1-8 12:00 回复TA
打死体育老师 
评分
参与人数 1威望 +3 收起 理由
红蛋大叔 + 3 赞一个!

相关帖子

沙发
会笑的星星|  楼主 | 2020-1-2 17:19 | 只看该作者
21的小喇叭,没问题的话把这篇**给推荐推荐啊

使用特权

评论回复
板凳
whtwhtw| | 2020-1-10 09:55 | 只看该作者
学学概率论还是有必要的,赞一个

使用特权

评论回复
地板
a7551453| | 2020-1-11 17:22 | 只看该作者
学学概率论还是有必要的,赞一个

使用特权

评论回复
5
shizaigaole| | 2020-1-14 13:24 | 只看该作者
这种方法打击都能想得到,但是45%这个阈值是有理论支撑的,我们不知道。

为楼主点个赞!

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

31

主题

96

帖子

16

粉丝