Unable to filter out a square wave signal using Butterworth filter
5 views (last 30 days)
Show older comments
Hello all,
I am trying to use Butterworth analog filter to filter out a square wave signal.
Here is my code
clear all; close all;
%create stimuli
f_125 = 125e3;
period=1/f_125;
Nr_periods=1;
t=linspace(0,1,32^2)*period*Nr_periods;
Fs=numel(t) / (t(end)-t(1));
VinSqu=(square(2*pi*(f_125)*t));
%Create filter
Wp = [500e3 2e6]/(Fs/2); %passband in Hz
Ws = [400e3 100e6]/(Fs/2);%stopband in Hz
Rp = 1; % passband ripple
Rs = 20; % stopband ripple
% Butterworth filter order
[n1,wn1] = buttord(Wp,Ws,Rp,Rs,'s')
% Evaluate filter responses
[zb,pb,kb] = butter(n1,wn1,'s');
[bb,ab] = zp2tf(zb,pb,kb);
[hb,wb] = freqs(bb,ab,32^2);
v_filt=filter(bb,ab,VinSqu);
plot(t,v_filt)
The output (v_filt) looks as follows
There is no filtering being done, although the freqs graph looks fine.
What am I doing wrong here. Any help will be greatly appreciated
0 Comments
Answers (1)
Star Strider
on 6 Mar 2020
There are some significant errors in the code. To begin with, if you want to use a digital filter, it is necessary to design a digital filter, not a continuous filter. The coefficients are significantly different, so continuous coefficients will not work as desired in a discrete application. I am not certain what you want from the filter, so I also calculated the Fourier transform of the input signal here, since it appears that the filter eliminates most of the actual input signal. To do the actual filtering use the filtfilt funciton, not filter.
%create stimuli
f_125 = 125e3;
period=1/f_125;
Nr_periods=1;
t=linspace(0,1,32^2)*period*Nr_periods;
Fs=numel(t) / (t(end)-t(1));
VinSqu=(square(2*pi*(f_125)*t));
%Create filter
Wp = [500e3 2e6]/(Fs/2); %passband in Hz
Ws = [400e3 2.5e6]/(Fs/2);%stopband in Hz % Corrected Upper Stopband
Rp = 1; % passband ripple
Rs = 20; % stopband ripple
% Butterworth filter order
[n1,wn1] = buttord(Wp,Ws,Rp,Rs) % Calculate Discrete — Not Continuous — Filter Coefficients
% Evaluate filter responses
[zb,pb,kb] = butter(n1,wn1);
[sos,g] = zp2sos(zb,pb,kb); % Second-Order-Sectioni For Stability
figure
freqz(sos,32^2,Fs);
v_filt=filtfilt(sos,g,VinSqu); % Use ‘filtfilt’ For Phase-Neutral Filtering
figure
plot(t, VinSqu)
hold on
plot(t,v_filt)
hold off
grid
legend('Unfiltered', 'Filtered', 'Location','NW')
L = numel(t);
Ts = t(2)-t(1);
Fs = 1/Ts;
Fn = Fs/2;
FTVS = fft(VinSqu)/L; % Calculate & Plot Fourier Transform Of Input
Fv = linspace(0, 1, fix (L/2)+1)*Fn;
Iv = 1:numel(Fv);
figure
plot(Fv, abs(FTVS(Iv))*2)
grid
xlim([0 5E+6])
This at least creates the correct approach. Experiment to get the result you want.
6 Comments
Star Strider
on 10 Mar 2020
That is not a phase shift. It is the normal phase response. Bessel filters are phase neutral, the reason they are used as anti-aliasing filters. Note that it is not possible to convert an analog Bessel filter to a discrete representation.
See Also
Categories
Find more on Analog Filters in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!