信号处理学习笔记2:软件RC二阶高通\低通滤波

接上一文:

信号处理学习笔记1:软件RC一阶高通\低通滤波-CSDN博客

目录

适用场景与优势:

[1)二阶低通 专属场景](#1)二阶低通 专属场景)

[2)二阶高通 专属场景](#2)二阶高通 专属场景)

相较于一阶的对比:

滤波效果对比

[响应速度 & 延迟](#响应速度 & 延迟)

适用场景精准对比

二阶低通滤波:

二阶高通滤波:

彻底消基线漂移

「突变、震动、动作」精准提取

抗干扰比一阶高通强

C语言测试代码:

C测试结果:

python测试图例:


适用场景与优势:

核心适用场景

1)二阶低通 专属场景

  1. 靠近电机、电磁阀、电源模块的传感器有强电磁干扰、尖峰毛刺、突发跳变(霍尔、电流、温湿度、压力传感器)。
  2. 工业环境测温 / 测湿、粮仓 / 冷库 / 机柜监测要求曲线极度平滑,不允许数据乱跳。
  3. 精密采样:称重传感器、气压、液位、微弱模拟信号采集一阶压不住微小抖动,二阶能彻底滤干净。
  4. 需要导出报表、画趋势图、做数据分析的项目波形必须顺滑美观,不能有杂波。

2)二阶高通 专属场景

  1. 振动检测、碰撞冲击、微动识别滤掉缓慢基线漂移,只保留瞬间变化。
  2. 心率 / 脉搏 / 微弱生物信号消除体位漂移、基线慢慢下沉问题。
  3. 加速度传感器(去掉重力直流分量 + 慢漂移)精准提取晃动、震动、动作变化。

相较于一阶的对比:

滤波效果对比

  1. 抗干扰 / 压毛刺
  • 一阶:只能压制小幅轻微噪声;遇到电机电磁尖峰、大跳变,压不住,还会飘
  • 二阶:强力削除大尖峰、突发毛刺、磁场干扰,专门适配电机、线圈、电源旁的传感器
  1. 平滑程度
  • 一阶:中等顺滑,肉眼还能看到轻微抖动
  • 二阶:波形极致丝滑,几乎无波动,做报表、绘图、精密采集完美
  1. 抑制基线漂移(高通)
  • 一阶高通:弱漂移能清,强慢漂移清不干净
  • 二阶高通:彻底剔除温漂、电压慢偏移,基线牢牢锁在 0

响应速度 & 延迟

  • 一阶:响应快、延迟小,数据跟得上真实变化
  • 二阶:有明显滞后延迟,信号真变了,要多帧才能跟上
  • 快速检测(按键、急动、快速动作)不能用二阶

适用场景精准对比

选一阶:

  • 室内干净环境温湿度、普通液位、电压采集
  • 需要实时响应、跟数据快
  • 简单教学、低成本小项目

选二阶:

  • 靠近电机、磁铁、电磁阀、强电源(电磁干扰大)
  • 霍尔传感器、精密称重、工业测温测湿
  • 需要曲线极度平滑、去除顽固漂移
  • 噪声大、一阶滤波效果拉胯的现场

二阶低通滤波:

y[n]=αx[n]+2(1−α)y[n−1]−(1−α)y[n−2]
符号说明:

y[n] = 当前滤波输出(out)

x[n] = 当前原始数据(current)

y[n-1] = 上一次输出(prev1)

y[n-2] = 上上次输出(prev2)

α = 滤波系数(ALPHA,越小滤波越强)

二阶高通滤波:

彻底消基线漂移

  • 传感器温漂、电压慢慢偏移、零点慢慢跑
  • 长时间采集,整条波形慢慢往上 / 往下歪✅ 二阶高通:直接把慢悠悠的偏移全部滤掉,波形死死贴 0 轴

「突变、震动、动作」精准提取

适合:

  • 加速度传感器:删掉重力 + 缓慢倾斜,只留晃动、震动、撞击
  • 心率 / 脉搏 ECG:删掉身体微动基线漂移,只留心跳尖峰
  • 振动检测、碰撞报警、微小冲击识别

抗干扰比一阶高通强

旁边有电机、磁场、电源低频杂波:

  • 一阶高通:还会带一点漂移、杂波擦不干净
  • 二阶高通:滤得非常彻底,噪声几乎不剩

C语言测试代码:

cpp 复制代码
#include <stdio.h>

/*
    二阶滤波 = 比一阶滤波更"丝滑",滤波效果更强
    二阶低通:去噪更干净,波形更平滑
    二阶高通:去漂移更彻底,变化量更清晰

    二阶比一阶多记录一组历史值(上一次、上上次)
*/

// 二阶滤波系数(可调)
#define ALPHA 0.08f


// 二阶低通滤波(更平滑、更稳)
float low_pass_2nd_filter(float current, float *prev1, float *prev2)
{
    float out;
    // 二阶公式:更平滑,抑制突变更强
    out = ALPHA * current + 2 * (1 - ALPHA) * (*prev1) - (1 - ALPHA) * (*prev2);

    // 更新历史值
    *prev2 = *prev1;
    *prev1 = out;

    return out;
}


// 二阶高通滤波(去漂移更强)
float high_pass_2nd_filter(float current, float *in_prev1, float *in_prev2, float *out_prev1, float *out_prev2)
{
    float out;
    // 二阶高通公式
    out = (1 - ALPHA) * ((*out_prev1) - current + (*in_prev1));

    // 更新历史值
    *in_prev2 = *in_prev1;
    *in_prev1 = current;

    *out_prev2 = *out_prev1;
    *out_prev1 = out;

    return out;
}

int main()
{
    // 更长的模拟传感器数据(30个点,带漂移+噪声)
    float raw_data[] = {
        10.2, 10.4, 10.9, 10.1, 10.6,
        11.3, 11.0, 11.7, 10.8, 11.2,
        11.5, 11.1, 11.8, 11.2, 11.6,
        12.1, 11.7, 12.2, 11.6, 12.0,
        12.3, 11.9, 12.4, 11.8, 12.2,
        12.5, 12.1, 12.6, 12.0, 12.4
    };

    int len = sizeof(raw_data) / sizeof(raw_data[0]);

    // 二阶低通需要保存前 2 次输出
    float lp_prev1 = raw_data[0];
    float lp_prev2 = raw_data[0];

    // 二阶高通需要保存前 2 次输入 + 前 2 次输出
    float hp_in_prev1 = raw_data[0];
    float hp_in_prev2 = raw_data[0];
    float hp_out_prev1 = 0;
    float hp_out_prev2 = 0;

    printf("序号\t原始数据\t二阶低通\t\t二阶高通\n");
    printf("---------------------------------------------------------\n");

    for (int i = 0; i < len; i++)
    {
        float cur = raw_data[i];

        // 二阶低通
        float lp_out = low_pass_2nd_filter(cur, &lp_prev1, &lp_prev2);

        // 二阶高通
        float hp_out = high_pass_2nd_filter(cur, &hp_in_prev1, &hp_in_prev2, &hp_out_prev1, &hp_out_prev2);

        printf("%d\t%.2f\t\t%.2f\t\t%.2f\n", i, cur, lp_out, hp_out);
    }

    return 0;
}

C测试结果:

python测试图例:

python 复制代码
import matplotlib.pyplot as plt

# 解决中文显示
plt.rcParams["font.family"] = ["SimHei", "Microsoft YaHei"]
plt.rcParams["axes.unicode_minus"] = False

# ===================== 30个数据(你二阶C代码的数据)=====================
x = list(range(30))

raw = [
10.2,10.4,10.9,10.1,10.6,
11.3,11.0,11.7,10.8,11.2,
11.5,11.1,11.8,11.2,11.6,
12.1,11.7,12.2,11.6,12.0,
12.3,11.9,12.4,11.8,12.2,
12.5,12.1,12.6,12.0,12.4
]

low_2nd = [
10.20,10.23,10.31,10.28,10.35,
10.49,10.56,10.72,10.73,10.82,
10.95,11.02,11.16,11.23,11.35,
11.52,11.63,11.79,11.84,11.94,
12.06,12.14,12.24,12.28,12.35,
12.43,12.49,12.57,12.59,12.63
]

high_2nd = [
0.00,0.02,0.09,-0.06,0.03,
0.12,-0.02,0.15,-0.17,0.02,
0.09,-0.08,0.13,-0.09,0.09,
0.18,-0.06,0.17,-0.16,0.08,
0.13,-0.06,0.12,-0.14,0.09,
0.13,-0.07,0.12,-0.15,0.07
]

# ===================== 绘图 =====================
plt.figure(figsize=(12,9))

# 原始信号
plt.subplot(3,1,1)
plt.plot(x, raw, color='#555555', marker='o', markersize=3, linewidth=1.5, label='原始信号(带噪声+漂移)')
plt.title('原始传感器信号(30点 含电磁干扰模拟)', fontsize=13)
plt.grid(True, alpha=0.3)
plt.legend()

# 二阶低通
plt.subplot(3,1,2)
plt.plot(x, low_2nd, color='#0077ff', marker='o', markersize=3, linewidth=2, label='二阶低通滤波(超强平滑)')
plt.title('二阶低通滤波结果:抗干扰强、波形极平滑', fontsize=13)
plt.grid(True, alpha=0.3)
plt.legend()

# 二阶高通
plt.subplot(3,1,3)
plt.plot(x, high_2nd, color='#ff3300', marker='o', markersize=3, linewidth=2, label='二阶高通滤波(提取变化量)')
plt.axhline(0, color='black', linestyle='--', alpha=0.6)
plt.title('二阶高通滤波结果:去除基线漂移、突出波动', fontsize=13)
plt.grid(True, alpha=0.3)
plt.legend()

plt.tight_layout()
plt.show()
相关推荐
左左右右左右摇晃1 小时前
ConcurrentHashMap ——put + get
java·开发语言·笔记
啥咕啦呛2 小时前
java打卡学习4:HashMap底层结构、扩容机制
java·学习·哈希算法
朱一头zcy2 小时前
设计模式入门:最简单的模板方法模式
笔记·设计模式·模板方法模式
qq_389600132 小时前
pads 学习笔记
笔记·学习
M malloc3 小时前
软件测试学习第一期
软件测试·学习·可用性测试
头疼的程序员3 小时前
计算机网络:自顶向下方法(第七版)第六章 学习分享(三)
网络·学习·计算机网络
醇氧3 小时前
【学习】现代计算机有多少种架构
学习·架构
新缸中之脑3 小时前
SaaS 葬礼笔记
笔记
左左右右左右摇晃3 小时前
ConcurrentHashMap 设计原理笔记
java·开发语言·笔记