1. 嵌入式滤波算法入门:从噪声中提取真实信号
在嵌入式系统开发中,我们经常需要处理各种传感器数据。但无论多么精密的传感器,采集到的数据总会带有噪声。就像老式收音机里的杂音,这些噪声可能来自电源波动、电磁干扰,或是传感器本身的特性。滤波算法就是我们的"数字降噪耳机",帮助我们从嘈杂的数据中提取出有用的真实信号。
我刚入行时曾遇到一个典型问题:用加速度计测量物体倾角时,数据总在±3度范围内跳动。这种噪声导致控制系统不断微调,电机发出令人烦躁的嗡嗡声。后来通过合理选择滤波算法,最终将波动控制在±0.5度内,系统立刻安静稳定下来。
滤波算法的核心价值在于:
- 提高数据可靠性
- 降低系统误动作概率
- 提升控制精度
- 减少不必要的计算开销
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 六种经典滤波算法深度解析
2.1 移动平均滤波:简单但有效
移动平均滤波是新手最容易理解的算法,其核心思想与我们日常计算平均成绩完全相同。在嵌入式系统中实现时,需要考虑几个关键点:
窗口大小选择:
- 5-10点:适用于快速变化信号(如心率监测)
- 20-50点:适合慢变信号(如温度监测)
- 需权衡:窗口越大滤波效果越好,但延迟也越大
内存优化技巧:
c复制// 使用环形缓冲区避免数据搬移
#define WINDOW_SIZE 10
float moving_avg(float new_val) {
static float buf[WINDOW_SIZE] = {0};
static int idx = 0;
static float sum = 0;
sum -= buf[idx]; // 减去即将被替换的旧值
buf[idx] = new_val; // 存入新值
sum += new_val; // 更新总和
idx = (idx + 1) % WINDOW_SIZE;
return sum / WINDOW_SIZE;
}
实际应用场景:
- 电池电压监测
- 环境温度采集
- 慢速变化的压力测量
注意事项:在STM32等资源受限平台,建议窗口大小不超过20,否则浮点运算可能成为瓶颈。我曾在一个项目中因为设置50点窗口导致采样率从1kHz降到200Hz。
2.2 中值滤波:对抗脉冲噪声的利器
工业现场常会遇到脉冲干扰,比如电机启动时的瞬时尖峰。中值滤波是应对这类问题的首选方案。
算法优化技巧:
- 使用奇数点(3/5/7)避免平局
- 对于5点中值,可采用部分排序法减少计算量:
c复制float median5(float a, float b, float c, float d, float e) {
// 只需确定第三大的数即可
// 先比较并交换使a<=b, c<=d
if(a > b) { float t=a; a=b; b=t; }
if(c > d) { float t=c; c=d; d=t; }
// 排除不可能项
if(a < c) { a = e; if(a > b) a = b; }
else { c = e; if(c > d) c = d; }
// 最后比较剩余项
return a > c ? a : c;
}
性能对比:
| 排序方法 | 5点比较次数 | 适合平台 |
|---|---|---|
| 完全排序 | 10-12次 | 通用 |
| 部分排序 | 6-7次 | 资源受限 |
| 硬件加速 | 1 |
