RC滤波器数学公式推导及软件算法实现

前言


题外话 :
本文是博主对几个滤波算法整理的笔记之一,原本一篇,但由于CSDN篇幅限制分为了几个部分,包括:
卡尔曼滤波器:标准卡尔曼滤波器公式推导及算法实现
陷波滤波器:陷波滤波器的数学模型推导及算法实现
以及本文的RC滤波器。
包括:

  • 一阶低通滤波器的数学模型推导及算法实现
  • 一阶高通滤波器的数学模型推导及算法实现
  • 二阶低通滤波器的数学模型推导
  • 二阶高通滤波器的数学模型推导

原文PDF下载链接:https://mp.csdn.net/mp_download/manage/download/UpDetailed


  • 在工程使用中,难免要使用到滤波算法,比如均值滤波,低通滤波等等,本文主要分析常用得低通和高通滤波算法(软件)
  • 文中公式基本都是从物理模型推导而来,由浅入深得逐步推算,过程相对详细,并使用C++给出了验证代码验证了滤波算法。
  • 由于up主水平有限,难免有错误,欢迎大家指正和交流。

1、一阶低通滤波

低通滤波器(英语:Low-pass filter)容许低频信号通过,但减弱(或减少)频率高于截止频率的信号的通过。对于不同滤波器而言,每个频率的信号的减弱程度不同。
在这里插入图片描述

1.1 一阶RC低通滤波器的连续域数学模型

在这里插入图片描述

1.2 一阶RC低通滤波器的算法推导

在这里插入图片描述

1.3 代码实现

#define PI 3.1415926
#define Get_LPF_Cof(fc, ts) (2 * PI * fc * ts / (float)(1 + 2 * PI * fc * ts))
#define LPF1(Yn, Xn, cof) Yn = (1 - cof) * Yn + cof * Xn

1.4 算法验证

验证代码:

#include <iostream>
#include <fstream>
#include <vector>
#include <cstdlib>  // For random number generation
#include <ctime>    // For seeding the random number generator
using namespace std;

#define PI 3.1415926
#define Get_LPF_Cof(fc, ts) (2 * PI * fc * ts / (float)(1 + 2 * PI * fc * ts))
#define LPF1(Yn, Xn, cof) Yn = (1 - cof) * Yn + cof * Xn

void saveToCSV(const vector<double>& data, const string& filename) {
    ofstream file(filename);

    if (file.is_open()) {
        for (const double& value : data) {
            file << value << endl;
        }
        file.close();
        cout << "Data saved to " << filename << endl;
    }
    else {
        cerr << "Unable to open the file: " << filename << endl;
    }
}

int main() {
    float fc = 1.0;         // Cutoff frequency
    float ts = 0.1;         // Sampling time
    int numSamples = 100;   // Number of samples
    vector<double> inputSignal(numSamples);
    vector<double> noisySignal(numSamples);
    vector<double> filteredSignal(numSamples);

    // Seed the random number generator
    srand(time(nullptr));

    // Generate input signal with noise
    for (int i = 0; i < numSamples; ++i) {
        inputSignal[i] = sin(2 * PI * 0.05 * i) + 0.2 * (rand() / (double)RAND_MAX - 0.5);
    }

    // Apply the low-pass filter
    double Yn = 0.0;
    for (int i = 0; i < numSamples; ++i) {
        double Xn = inputSignal[i];
        LPF1(Yn, Xn, Get_LPF_Cof(fc, ts));
        filteredSignal[i] = Yn;
    }

    // Save data to CSV files
    std::string filename1 = "LPF_before_Data.csv";
    saveToCSV(inputSignal, "input_signal.csv");
    std::string filename2 = "LPF_after_Data.csv";
    saveToCSV(filteredSignal, "filtered_signal.csv");

    return 0;
}

在这里插入图片描述

2、一阶高通滤波

高通滤波器(英语:High-pass filter)是容许高频信号通过、但减弱(或减少)频率低于截止频率信号通过的滤波器。对于不同滤波器而言,每个频率的信号的减弱程度不同。
在这里插入图片描述

2.1 一阶RC高通滤波器的连续域数学模型

在这里插入图片描述

2.2 一阶RC低通滤波器的算法推导

在这里插入图片描述

2.3 代码实现

#define PI 3.1415926
#define Get_HPF_Cof(fc,ts) (1/(float)(1+2*PI*fc*ts)) /* get coefficient */
#define HPF1(Yn,Xn,cof) Yn = (1-cof)*Yn + cof*Xn  /* Yn:out;Xn:in;a:coefficient */

2.4

验证代码:

#include <iostream>
#include <fstream>
#include <vector>
#include <cstdlib>  // For random number generation
#include <ctime>    // For seeding the random number generator
using namespace std;

#define PI 3.1415926
#define Get_HPF_Cof(fc,ts) (1/(float)(1+2*PI*fc*ts)) /* get coefficient */
#define HPF1(Yn,Xn,cof) Yn = (1-cof)*Yn + cof*Xn  /* Yn:out;Xn:in;a:coefficient */

void saveToCSV(const vector<double>& data, const string& filename) {
    ofstream file(filename);

    if (file.is_open()) {
        for (const double& value : data) {
            file << value << endl;
        }
        file.close();
        cout << "Data saved to " << filename << endl;
    }
    else {
        cerr << "Unable to open the file: " << filename << endl;
    }
}

int main() {
    float fc = 1.0;         // Cutoff frequency
    float ts = 0.1;         // Sampling time
    int numSamples = 100;   // Number of samples
    vector<double> inputSignal(numSamples);
    vector<double> noisySignal(numSamples);
    vector<double> filteredSignal(numSamples);

    // Seed the random number generator
    srand(time(nullptr));

    // Generate input signal with noise
    for (int i = 0; i < numSamples; ++i) {
        inputSignal[i] = sin(2 * PI * 0.05 * i) + 0.2 * (rand() / (double)RAND_MAX - 0.5);
    }

    // Apply the low-pass filter
    double Yn = 0.0;
    for (int i = 0; i < numSamples; ++i) {
        double Xn = inputSignal[i];
        HPF1(Yn, Xn, Get_HPF_Cof(fc, ts));
        filteredSignal[i] = Yn;
    }

    // Save data to CSV files
    std::string filename1 = "HPF_before_Data.csv";
    saveToCSV(inputSignal, "input_signal1.csv");
    std::string filename2 = "HPF_after_Data.csv";
    saveToCSV(filteredSignal, "filtered_signal1.csv");

    return 0;
}

在这里插入图片描述

3、二阶低通滤波器

在这里插入图片描述

3.1 二阶RC低通滤波器的连续域数学模型

在这里插入图片描述

3.2 二阶RC低通滤波器的算法推导

在这里插入图片描述

4、二阶高通滤波器

在这里插入图片描述

3.1 二阶RC高通滤波器的连续域数学模型

在这里插入图片描述

3.2 二阶RC高通滤波器的算法推导

在这里插入图片描述
式(35)的求解过程相对复杂,这里使用python工具进行求解:

# coding: utf-8
from sympy import symbols, Eq, solve

# 定义符号变量
Vo_k, Vo_k_minus_1, Vo_k_minus_2 = symbols('Vo_k Vo_k_minus_1 Vo_k_minus_2')
Vx_k, Vx_k_minus_1, Vx_k_minus_2 = symbols('Vx_k Vx_k_minus_1 Vx_k_minus_2')
Vi_k, Vi_k_minus_1, Vi_k_minus_2 = symbols('Vi_k Vi_k_minus_1 Vi_k_minus_2')
RC, Ts = symbols('RC Ts')

# 定义方程组
equations = [
    Eq(RC * ( (Vx_k - Vo_k) - (Vx_k_minus_1 - Vo_k_minus_1) ) / Ts, Vo_k),
    Eq(RC * ( (Vx_k_minus_1 - Vo_k_minus_1) - (Vx_k_minus_2 - Vo_k_minus_2) ) / Ts, Vo_k_minus_1),
    Eq(RC * ( (Vi_k - Vx_k) - (Vi_k_minus_1 - Vx_k_minus_1) ) / Ts, Vx_k),
    Eq(RC * ( (Vi_k_minus_1 - Vx_k_minus_1) - (Vi_k_minus_2 - Vx_k_minus_2) ) / Ts, Vx_k_minus_1)
]

# 解方程组,得到Vx_k_minus_1、Vx_k_minus_2和Vx_k(前三个公式)
solutions_ab = solve(equations[:3], (Vx_k_minus_1, Vx_k_minus_2,Vx_k))

# 将Vx_k_minus_1和Vx_k_minus_2 的解代入第四个方程
equation_c = equations[3].subs(solutions_ab)

# 解方程,得到 Vo_k 关于 Vo_k_minus_1、Vo_k_minus_2、Vi_k、Vii_k_minus_1、Vi_k_minus_2的表达式
solution_c = solve(equation_c, Vo_k)

# 打印结果
print("Vo_k表达式:")
print(solution_c)
  • 6
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hlpinghcg

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值