想必大家都看过关于一阶低通滤波器如何在程序(无论是 C、C++ 还是 PLC 等等)实现的例子或相关说明,不外乎就是常见的公式:
Y ( n ) = a ∗ X ( n ) + ( 1 − a ) ∗ Y ( n − 1 ) Y(n) = a*X(n) + (1-a)*Y(n-1) Y(n)=a∗X(n)+(1−a)∗Y(n−1)
然后告诉你 a a a 就是滤波系数, n − 1 n-1 n−1代表前一次状态等内容,既不知道如何设定滤波系数,也不清楚为什么要加入前一次数值。以下就为大家说明上述的公式是如何得来。
1.低通滤波器(LPF)
最常见的一阶低通滤波器电阻电容组合而成,是应用了电容对于电压响应速度较慢的特性。
由于这种特性,使得电容的阻抗呈现为一组时间函数。根据基本电学原理,我们了解到:
i
c
(
t
)
=
C
d
v
o
u
t
(
t
)
d
t
i_c(t) = C \frac{d\ v_{out}(t)}{dt}
ic(t)=Cdtd vout(t)
也就是说流经电容的电流,是和电压的变化率有关系。经过拉氏转换(The Laplace Transfrom)我们可以得到:
I c = C s V o u t I_c=C\ sV_{out} Ic=C sVout
根据欧姆定律,阻抗是电压除以电流,我们可以得到电容的阻抗关系式为:
X
c
=
V
o
u
t
I
c
=
1
s
C
X_c=\frac{V_{out}}{I_c}=\frac{1}{s\ C}
Xc=IcVout=s C1
我们以输入源为步阶响应(Step Response)得出输出电压与输入电压的关系式(此处的
1
s
\frac{1}{s}
s1是由于步阶系统
t
>
0
t>0
t>0后才作用):
V
o
u
t
=
1
s
V
i
n
×
1
s
C
R
+
1
s
C
=
V
i
n
×
1
R
C
s
(
s
+
1
R
C
)
V_{out}=\frac{1}{s}V_{in} \times \frac{\frac{1}{s\ C}}{R+\frac{1}{s\ C}}=V_{in}\times\frac{\frac{1}{RC}}{s(s+\frac{1}{RC})}
Vout=s1Vin×R+s C1s C1=Vin×s(s+RC1)RC1
经过反拉氏转换我们可以得到输入输出电压的时间函数为:
v
o
u
t
(
t
)
=
v
i
n
(
t
)
×
(
1
−
e
−
1
R
C
t
)
v_{out}(t)=v_{in}(t)\times(1-e^{-\frac{1}{RC}t})
vout(t)=vin(t)×(1−e−RC1t)
而滤波器本身的转移函数为:
H
(
s
)
=
ω
0
s
+
ω
0
H(s)=\frac{\omega_0}{s+\omega_0}
H(s)=s+ω0ω0
此处我们定义截止频率
ω
0
=
2
π
f
0
=
1
R
C
\ \omega_0=2\pi f_0=\frac{1}{RC}
ω0=2πf0=RC1
至此我们已经建立了由RC组成的低通滤波器时间函数,然而上述方程还是连续时间函数,要进行离散(电脑运算)还必须转换成离散时间函数,过程之复杂并且还需要额外积分器等计算,难以在程序中实现。
2.拉氏转换的应用
拉氏转换之所以占用高等数学一个章节,并不只是因为让微分方程的考试可以靠记忆来计算这么简单而已,更多的是
拉氏转换将微分运算子、积分运算子可以透过 代数运算 的方式处理
讲白话就是 (此处画重点):
可以更简单的透过电脑进行运算
我们都知道要电脑进行矩阵运算、代数运算都是相对容易的,因此透过拉氏转换我们可以轻松的将微分方程转换成电脑更容易计算的代数运算。
我们引入 双线性变换(The Tustin Transform) 将 z z z 平面与 s s s 平面进行映射,即:
z = e s T = e s T / 2 e − s T / 2 ≈ 1 + s T / 2 1 − s T / 2 z=e^{sT}=\frac {e^{{sT/2}}}{e^{{-sT/2}}}\approx\frac {1+sT/2}{1-sT/2} z=esT=e−sT/2esT/2≈1−sT/21+sT/2
其中 T T T 表示离散系统的取样时间。
或是我们将微分运算子
s
s
s 进行转换:
s
=
1
T
ln
(
z
)
=
2
T
[
z
−
1
z
+
1
+
1
3
(
z
−
1
z
+
1
)
3
+
1
5
(
z
−
1
z
+
1
)
5
+
1
7
(
z
−
1
z
+
1
)
7
+
⋯
]
≈
2
T
z
−
1
z
+
1
=
2
T
1
−
z
−
1
1
+
z
−
1
{\begin{aligned}s&={\frac {1}{T}}\ln(z)\\&={\frac {2}{T}}\left[{\frac {z-1}{z+1}}+{\frac {1}{3}}\left({\frac {z-1}{z+1}}\right)^{3}+{\frac {1}{5}}\left({\frac {z-1}{z+1}}\right)^{5}+{\frac {1}{7}}\left({\frac {z-1}{z+1}}\right)^{7}+\cdots \right]\\&\approx {\frac {2}{T}}{\frac {z-1}{z+1}}\\&={\frac {2}{T}}{\frac {1-z^{{-1}}}{1+z^{{-1}}}}\end{aligned}}
s=T1ln(z)=T2[z+1z−1+31(z+1z−1)3+51(z+1z−1)5+71(z+1z−1)7+⋯]≈T2z+1z−1=T21+z−11−z−1
也就是说:
s
←
2
T
z
−
1
z
+
1
.
s\leftarrow {\frac {2}{T}}{\frac {z-1}{z+1}}.
s←T2z+1z−1.
再回到上面的
R
C
RC
RC 低通滤波器转移函数
H
(
s
)
H(s)
H(s),令
s
←
2
T
z
−
1
z
+
1
s\leftarrow {\frac {2}{T}}{\frac {z-1}{z+1}}
s←T2z+1z−1 代入将函数转换为离散时间域:
H
(
z
)
=
H
(
s
)
∣
s
=
2
T
z
−
1
z
+
1
=
ω
0
2
T
z
−
1
z
+
1
+
ω
0
=
ω
0
(
z
+
1
)
2
T
ω
0
(
z
−
1
)
+
ω
0
(
z
+
1
)
=
(
1
+
z
−
1
)
2
T
ω
0
(
1
−
z
−
1
)
+
(
1
+
z
−
1
)
{\begin{aligned}H(z)&=H(s){\bigg |}_{{s={\frac {2}{T}}{\frac {z-1}{z+1}}}}\\&=\frac{\omega_0}{\frac{2}{T}\frac{z-1}{z+1}+\omega_0}\\&=\frac{\omega_0(z+1)}{\frac{2}{T\omega_0}(z-1)+\omega_0(z+1)}\\&=\frac{(1+z^{-1})}{\frac{2}{T\omega_0}(1-z^{-1})+(1+z^{-1})}\end{aligned}}
H(z)=H(s)
s=T2z+1z−1=T2z+1z−1+ω0ω0=Tω02(z−1)+ω0(z+1)ω0(z+1)=Tω02(1−z−1)+(1+z−1)(1+z−1)
此处 z n z^{n} zn 是表示当前( z 0 = 1 z^{0} = 1 z0=1)、过去( z − 1 z^{-1} z−1)或未来( z 1 z^{1} z1)的状态,然而我们并不知道未来的状态,因此必须将转移函数以过去状态 z − 1 z^{-1} z−1 计算。
有了离散低通滤波器转移函数,我们就可以透过程序将其实现。
3.以程序实现低通滤波器
假设输入源为
x
x
x 通过滤波器后的输出为
y
y
y,可表示为下列方程:
y
n
=
(
1
+
z
−
1
)
2
T
ω
0
(
1
−
z
−
1
)
+
(
1
+
z
−
1
)
x
n
y_{n} = \frac{(1+z^{-1})}{\frac{2}{T\omega_0}(1-z^{-1})+(1+z^{-1})} \ x_{n}
yn=Tω02(1−z−1)+(1+z−1)(1+z−1) xn
y
n
×
(
2
T
ω
0
(
1
−
z
−
1
)
+
(
1
+
z
−
1
)
)
=
x
n
+
x
n
−
1
y_n \times(\frac{2}{T\omega_0}(1-z^{-1})+(1+z^{-1})) = x_n+x_{n-1}
yn×(Tω02(1−z−1)+(1+z−1))=xn+xn−1
由于目标是得到
y
n
y_n
yn,整理后可得到:
y
n
=
(
x
n
+
x
n
−
1
)
−
y
n
−
1
×
(
1
−
2
T
ω
0
)
1
+
2
T
ω
0
y_{n} = \frac{(x_{n} + x_{n-1}) - y_{n-1} \times (1 - \frac{2}{T\omega_0})}{1 + \frac{2}{T\omega_0}}
yn=1+Tω02(xn+xn−1)−yn−1×(1−Tω02)
下面以 CODESYS 核心 PLC 代码为例,我们先设定 PLC 执行周期为
4
m
s
4ms
4ms,接着我们定应一些参数以及初始值:
VAR
T: LREAL := 0.004; //取样周期 4ms
res: LREAL := 15.9E3; //电阻值 15.9k
cap: LREAL := 1E-6; //电容值 1uF
w : LREAL;
x: LREAL; //输入源
y: LREAL; //输出
x_1: LREAL; //输入源前一次状态
y_1: LREAL; //输出前一次状态
END_VAR
R C RC RC 的组合将截止频率设定为 f 0 = 1 2 π R C ≈ 10 H z f_0=\frac{1}{2\pi RC}\approx 10Hz f0=2πRC1≈10Hz
程序实现低通滤波器:
w := 1 / (res * cap);
y := ((x + x_1) - y_1 * (1 - 2 * res * cap / T)) / (1 + 2 * res * cap / T);
y_1 := y;
x_1 := x;
4.测试结果
我们以震幅为
1
1
1 频率
10
H
z
10Hz
10Hz 的正弦波输入,量测输出峰值为
0.710
0.710
0.710 ,接近理论值的
y
=
1
2
×
x
y = \frac{1}{\sqrt{2}} \times x
y=21×x: