Designing a bandpass filter in Matlab

11 views (last 30 days)
Hi,
I am trying to implement an FIR bandpass filter, with a pass band from ~350KHz to ~700KHz.
For that, I am using the fir1 function.
My signal is sampled at 10Mhz and the number of sample points are ~126M.
For the bandpass filter I use the following code:
%% testing
Fs = 1e7; % sampling frequency
L = 126204866; % length of signal
% Parameters for the implementation of a BandPass filter
f3 = 300e3; % low cut-off frequency for Bandpass: 700e3, 300e3
f4 = 750e3; % high cut-off frequency for Bandpass: 1450e3, 750e3
fpass = [f3 f4];
hc = fir1(200,fpass/Fs,"bandpass");
% Break the frequency axis into "L" bins/buckets
f = (-0.5:1/L:0.5-1/L)*Fs; % create the frequency vector (frequency X-axis)
Y = 20*log10(abs(fftshift(fft(hc,L))));
figure;
reduce_plot(f,Y);
axis([0 Fs/2 -60 20])
title('Filter Frequency Response')
grid on
If I use the frequencies f3 = 300KHz and f4 = 750 KHz, I get the following filter frequency response:
As can be seen the 3db attenuation is at ~170KHz and ~355KHz.
On the other hand, if I use frequencies f3 = 700KHz and f4 = 1450 KHz, I get the desired filter frequency response:
As can be seen the 3db attenuation is at ~370KHz and ~705KHz.
It seems that I need to double the input frequencies I use in fir1 function to get the desired frequency response.
Could somebody explain what is the cause for this?
I am using Matlab R2021b.
Thank you in advance for your response and time.
-Nassos

Accepted Answer

Star Strider
Star Strider on 27 Jun 2022
It took me a while to figure out what the problem was, and it turns out to be that the passband frequencies must be normalised by the Nyquist frequency, while the posted code normalises them by the sampling frequency. The result is that the frequencies in the uncorrected code are half of what they should be.
%% testing
Fs = 1e7; % sampling frequency
L = 126204866; % length of signal
% Parameters for the implementation of a BandPass filter
f3 = 300e3; % low cut-off frequency for Bandpass: 700e3, 300e3
f4 = 750e3; % high cut-off frequency for Bandpass: 1450e3, 750e3
fpass = [f3 f4];
hc = fir1(200,fpass/(Fs/2),"bandpass");
% Break the frequency axis into "L" bins/buckets
f = (-0.5:1/L:0.5-1/L)*Fs; % create the frequency vector (frequency X-axis)
Y = 20*log10(abs(fftshift(fft(hc,L))));
[h,w] = freqz(hc, 1, 2^16, Fs);
idx = find(w >= mean(fpass), 1, 'first');
idxv = [1 idx; idx+1 numel(w)];
format short eng
absh = abs(h);
for k = 1:2
idxr = idxv(k,1) : idxv(k,2);
hpf(k) = interp1(mag2db(absh(idxr)), w(idxr), -6);
% figure
% plot(w(idxr),mag2db(absh(idxr)))
% grid
end
fprintf('Half-Power (-6 dB) Frequencies = [%8.3E, %8.3E]',hpf)
Half-Power (-6 dB) Frequencies = [2.999E+05, 7.499E+05]
figure;
freqz(hc, 1, 2^16, Fs)
set(subplot(2,1,1), 'XLim',[0 1]*1E+6)
yline(subplot(2,1,1), -3)
xline(subplot(2,1,1),hpf,'-r')
set(subplot(2,1,2), 'XLim',[0 1]*1E+6)
title('Filter Frequency Response')
grid on
Also, the bulit-in freqz function is the correct way to depict discrete filter Bode plots in MATLAB.
.
  2 Comments
nassos
nassos on 1 Jul 2022
Thank you for the answer @Star Strider and for the tip about freqz function!

Sign in to comment.

More Answers (0)

Products


Release

R2021b

Community Treasure Hunt

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

Start Hunting!