1.滑动窗口滤波

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/*定义窗口大小*/
#define WINDOWS_SIZE 8

int filter_moving_windows()
{
static int buffer[WINDOWS_SIZE];
static int index = 0;
int sum = 0;
buffer[index] = get_value();
index = (index + 1) % WINDOWS_SIZE; //循环队列

for( int i = 0; i < WINDOWS_SIZE; i++)
{
sum += buffer[i];
}
return sum/WINDOWS_SIZE; //计算均值
}

2. 一阶卡尔曼滤波

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
typedef struct {
    float q;    // 过程噪声方差
    float r;    // 测量噪声方差
    float x;    // 状态估计值
    float p;    // 估计误差协方差
    float k;    // 卡尔曼增益
} KalmanFilter;

float kalman_update(KalmanFilter *kf, float measurement) {
    // 预测阶段
    kf->p += kf->q;  
    // 更新阶段
    kf->k = kf->p / (kf->p + kf->r);
    kf->x += kf->k * (measurement - kf->x);
    kf->p *= (1 - kf->k);
    return kf->x;
}

3. 一阶线性滤波

1
2
3
4
5
6
7
#define ALPHA 0.3  // 平滑系数(0<α<1)

float first_order_filter(float new_sample) {
    static float prev_output = 0;
    prev_output = ALPHA * new_sample + (1 - ALPHA) * prev_output;
    return prev_output;
}

4.中位值滤波

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#define N 7  // 奇数采样次数

char median_filter() {
    char samples[N], temp;
    for (int i=0; i<N; i++) 
        samples[i] = get_adc();  // 获取ADC采样值
    
    // 冒泡排序取中值
    for (int i=0; i<N-1; i++) {
        for (int j=0; j<N-i-1; j++) {
            if (samples[j] > samples[j+1]) {
                temp = samples[j];
                samples[j] = samples[j+1];
                samples[j+1] = temp;
            }
        }
    }
    return samples[N/2];  // 返回中间值
}