如何使用嵌入式C来阻止传感器中偶尔出现的突然尖峰值

how to arrest sudden spike value occurs occasionally in sensor using embedded c

提问人:Aravinth 提问时间:10/29/2023 最后编辑:James ZAravinth 更新时间:10/30/2023 访问量:78

问:

我正在使用带放大器的传感器。我可以看到传感器突然产生了非常高的价值,这影响了功能。我正在寻找一些可以消除突然峰值值的算法。我在这个项目中使用嵌入式 c,请向我推荐一些使用 c 程序消除突然峰值值的算法。

我尝试了以前和当前值的比较方法,但它没有解决我的问题

C 算法 嵌入式 传感器 标定

评论

0赞 Spektre 10/29/2023
通常的方法是计算运行中信号的(滑动平均值)并检测尖峰,但是如果没有样本输入,我们只能猜测...... 因此,只需平均结果值,其结果值将为您提供平均值的中间值,这可以通过环形缓冲区或 FIFO 轻松完成,如果您的平均功效为 2 个值,而不是,那么您可以使用位移而不是以轻微的时间偏移为代价......savgxif (abs(x-savg(x))>_some_threshold) /* here spike is detected */ ;svg(x(t)) = ( x(t-n)+ ... +x(t-2)+x(t-1)+x(t)+x(t+1)+x(t+2)+ ... +x(t+n) )/(n+n+1);2n+1x2n+1/
0赞 Lundin 10/30/2023
假设取值范围是ADC从0到Vref的整个范围,那么我们就无法真正设置阈值。但是,如果我们对系统有具体的了解,我们可以预测值应该以多快的速度变化。例如,如果我们使用PWM电流控制某些执行器或阀门,则测得的电流不应偏离输出太多或关闭。
0赞 Martin Brown 11/1/2023
首先,最好找到传感器上尖峰和毛刺的根本原因,而不是在软件中掩盖问题。如果您想要一个粗略且现成的快速修复,那么奇数个样本的滑动棚车平均值是可以且无偏差的。您可能应该记录坏值,但如果它们跳到超过 3 sigma 噪声水平以馈送到任何控制算法,则将它们替换为 boxcar 平均值。我告诫不要过滤原始数据,因为您无法取回已调整的原始数据。但要向客户提供经过消毒的流。
0赞 Spektre 11/2/2023
@MartinBrown“滑动棚车”被称为“滑动平均线”......

答:

0赞 Cem Polat 10/29/2023 #1

您可以尝试一个简单的移动平均过滤器,例如

#define N 5

int sensorData[N];
int currentIndex = 0;

int FilterSensorData(int newData) {
    sensorData[currentIndex] = newData;

    int sum = 0;
    for (int i = 0; i < N; i++) {
        sum += sensorData[i];
    }

    int movingAverage = sum / N;    
    currentIndex = (currentIndex + 1) % N;

    return movingAverage;
}

根据需要选择 N。

我不知道你们的传感器数据的详细信息。如果传感器数据为实数,则可以使用浮点类型更改整数。

评论

0赞 Lundin 10/30/2023
通常应使用中值滤波器而不是平均滤波器来消除尖峰。否则,您让尖峰影响输出。
0赞 Martin Brown 11/1/2023
如果尖峰是单个样本,这是一个公平的点,但如果尖峰是影响多个连续样本的某种真实物理过程,则会变得棘手。出于这个原因,通常最好保存未受干扰的原始数据,并将经过清理的数据提供给任何客户,并使用 Boxcar 平均值的输出来替换平均值中的任何加标样本。
1赞 Lundin 10/30/2023 #2

请注意,数字平均滤波器的工作原理与硬件中的RC滤波器完全相同:它不会消除任何东西,只是将其向下舍入。如果尖峰是预期输入的一部分,则可以使用平均滤波器。

但是,如果尖峰是应该被忽略的异常,那么要消除尖峰而不是“调低”它们,您需要使用中值滤波器。通常称为 median-3 或 median-5 等,具体取决于您存储的先前样本数量。采样率需要足够长,以至于峰值仅在 1 个样本期间发生,否则您可以说是在处理浪涌,而不是峰值 - 或者只是采样太快。

如何对它们进行编码取决于您读取的是数字输入还是模拟输入。

数字输入就像按出现顺序存储 1 或 0 序列一样简单。假设 0 是预期值,那么您可以对 进行表查找,其“中位数 3”值为 0。001

对于模拟输入,您必须在输入值时对它们进行排序。可以在这里找到一些示例: https://embeddedgurus.com/stack-overflow/2010/10/median-filtering/ 有一些方法可以进一步优化该代码,但它应该是一个很好的介绍。