Designed filter does not filter as it should

10 views (last 30 days)
fineline
fineline on 7 Aug 2017
Commented: fineline on 8 Aug 2017
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?

Answers (1)

John BG
John BG on 7 Aug 2017
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 Comments
John BG
John BG on 8 Aug 2017
Edited: John BG on 8 Aug 2017
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 on 8 Aug 2017
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'

Sign in to comment.

Tags

Community Treasure Hunt

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

Start Hunting!