Designed filter does not filter as it should

조회 수: 10 (최근 30일)
fineline
fineline 2017년 8월 7일
댓글: fineline 2017년 8월 8일
I designed a FIR Kaiser windowed low pass digital filter with filter design app, and had MATLAB generate the code for it and return the filter object:
function Hd = filter_lp_100
%FILTER_LP_100 Returns a discrete-time filter object.
% MATLAB Code
% Generated by MATLAB(R) 9.2 and the DSP System Toolbox 9.4.
% Generated on: 04-Aug-2017 17:09:08
% FIR Window Lowpass filter designed using the FIR1 function.
% All frequency values are in Hz.
Fs = 500; % Sampling Frequency
Fpass = 100; % Passband Frequency
Fstop = 110; % Stopband Frequency
Dpass = 0.057501127785; % Passband Ripple
Dstop = 0.0000000001; % Stopband Attenuation
flag = 'scale'; % Sampling Flag
% Calculate the order from the parameters using KAISERORD.
[N,Wn,BETA,TYPE] = kaiserord([Fpass Fstop]/(Fs/2), [1 0], [Dstop Dpass]);
% Calculate the coefficients using the FIR1 function.
b = fir1(N, Wn, TYPE, kaiser(N+1, BETA), flag);
Hd = dfilt.dffir(b);
But this filter does not attenuate the input signal, it even amplifies it because PSD for output is larger than input PSD for all points. Please see the plots. Blue is input signal power spectrum density, Red is output PSD, and yellow is filter response:
I tried different filters, none of them is performing. My code is very simple, I copied the part that does filtering and plotting filter response:
%%FILTER %%%%%%%%%%%%%%%%%%%%%%%%%%
coef=filter_lp_100; % MATLAB filter generated function. It returns Hd = dfilt.dffir(b);
out_signal=filter(coef.numerator,1,in_signal);
%%%plotting filter response. f is array of physical frequencies, fs is sampling rate:
h=freqz(coef,f,fs);
plot(f,10*log10(abs(h)))
Do you see anything wrong with this?

답변 (1개)

John BG
John BG 2017년 8월 7일
Hi Fineline
instead of
[N,Wn,BETA,TYPE] = kaiserord([Fpass Fstop]/(Fs/2), [1 0], [Dstop Dpass]);
try
[N,Wn,BETA,TYPE] = kaiserord([Fpass Fstop], [1 0], [Dstop Dpass]);
.
If the unnecessary Fs in the definition of the filter was all required to fix your question. would you consider marking my answer as accepted answer by clicking in the Accept Answer button?
If further corrections required, would you consider supplying the signal in a .mat file attached to the question?
then I will reproduce the signals shown in your question, and see what else can be done.
Awaiting answer
John BG
  댓글 수: 3
John BG
John BG 2017년 8월 8일
편집: John BG 2017년 8월 8일
ok,
1.
Fs at end, not reducing [Fpass Fstop]
[N,Wn,BETA,TYPE] = kaiserord([Fpass Fstop]/(Fs/2), [1 0], [Dstop Dpass]);
try
Dstop=.01;Dpass=.01;
[N,Wn,BETA,TYPE] = kaiserord([Fpass Fstop], [1 0], [Dstop Dpass],Fs);
2.
also, in fir1,
TYPE after kaiser, not before
3.
do not normalise coefficients if defining Dpass Dstop. From fir1 help:
'scale' normalizes the coefficients so that the magnitude response of the filter at the center of the passband is 1 (0 dB).
'noscale' does not normalize the coefficients.
4.
When defining the tolerances, D1 D2 D3 .. tolerances should follow same order as the preceding magnitudes vector [0 1 0 ..]
If defining a low pass filter, in this example it doesn't really matter because the tolerances you want are really small, but because it's a low pass filter, since you have [1 0] it makes more sense for readers to read [Dpass Dstop], not [Dstop Dpass].
So, instead
b = fir1(N, Wn, TYPE, kaiser(N+1, BETA), flag);
either
flag='noscale'
b = fir1(N, Wn, kaiser(N+1, BETA), TYPE, flag);
If you supply a sample of the input signal readers will be able to reproduce the results shown in the question, and perhaps better assist you.
Does it work now?
In any case, the output signal is already LPF of the input isn't it?
why don't you scale the output to focus on the beating, DC out
John BG
fineline
fineline 2017년 8월 8일
I have attached the signal. I tried your edits as:
Dstop=.01;Dpass=.01;
[N,Wn,BETA,TYPE] = kaiserord([Fpass Fstop], [1 0], [Dstop Dpass],Fs)
% Calculate the coefficients using the FIR1 function.
% b = fir1(N, Wn, TYPE, kaiser(N+1, BETA), flag);
b = fir1(N, Wn, kaiser(N+1, BETA), TYPE, flag);
It gives error though:
Error using fir1>validateargs (line 216)
Unrecognized or ambiguous filter type specified.
Error in fir1>parseoptargs (line 147)
[Ftype,Wind,Scale] = validateargs(Wn,Ftype,Wind,Scale);
Error in fir1 (line 98)
[Ftype,Wind,SCALING] = parseoptargs(Wn,varargin{:});
Error in filter_lp_100 (line 25)
b = fir1(N, Wn, kaiser(N+1, BETA), TYPE, flag);
Here are outputs of kaierord:
N =
224
Wn =
0.4100
BETA =
3.3953
TYPE =
'low'

댓글을 달려면 로그인하십시오.

카테고리

Help CenterFile Exchange에서 Single-Rate Filters에 대해 자세히 알아보기

태그

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by