How can I create a bandpass FIR filter using firpm?

22 views (last 30 days)
I have to create a bandpass FIR filter for an EEG signal with cutoff frequencies [1,8] Hz and sampling rate= 500, I wanted to first use the firpmord command to find the minimum order for the filter to work and then realize the same filter with the same specifics through both firpm and the windows method with fir1 trying the minimum order, and higher order and a lower order to show how the filter changes, but there are some problems:
  • when trying to use firpmord I don't know how to choose the amplitude and the deviation, i chose to have a rp=0.5 and rs=30 in dB but I don't know how to link them to dev or how to choose the amplitude
  • I tried the formula for the dev that is on the matlab example but I can't understand if it's right and why should I use this formula
  • I can't understand how to use the w parameter that I get from appliying firpmord.
  • I think I realized a highpass filter, can you tell me what I did wrong and how to correct the code?
  • If you're confident with filters applied to EEG do you think that I chose good values for rp and rs? Should I change them?
Here's the code:
fFIR= [1 8]; % frequenza di taglio in Hz
a=[0 1]; %ampiezza desiderata
rp= 0.5; %ripple banda passante in dB
rs= 30; %ripple banda di stop in dB
fs=500; % frequenza di campionamento in Hz
dev = [ 10^(-rs/20) (10^(rp/20)-1)/(10^(rp/20)+1)];
%ricavo l'ordine minimo del filtro
[n,fo, ao, w]=firpmord(fFIR,a,dev,fs);
b = firpm(n,fo,ao,w);
freqz(b,1,1024,fs)
title('Filtro FIR passabanda con frequenze di taglio [1,8] Hz')
  2 Comments
Paul
Paul on 8 Oct 2023
Hi FRANCESCA,
For this part of your question:
  • I think I realized a highpass filter, can you tell me what I did wrong and how to correct the code?
See this firpm example for how to set the f and a inputs for a bandpass filter.
FRANCESCA SANASI
FRANCESCA SANASI on 8 Oct 2023
thanks, the order also depends on the deviation and I don't know how to link amplitude and deviation and in the example the order is chosen arbitrarily. Do you have any suggestion?

Sign in to comment.

Accepted Answer

Star Strider
Star Strider on 8 Oct 2023
I could not get this to work with firpm, since it apparently only works with lowpass filters.
Getting it to work with fir1 is straightforward —
Fs = 500;
Fn = Fs/2;
fcomb = [0.8 1 8 8.2]/Fn;
n = 2^12
n = 4096
hh = fir1(n, fcomb(2:3));
figure
freqz(hh, 1, 2^16, Fs)
set(subplot(2,1,1), 'XLim',[0 10])%, 'XScale','log')
set(subplot(2,1,2), 'XLim',[0 10])%, 'XScale','log')
Higher values for ‘n’ will produce steeper (shorter) transition regions, however they also lengthen the filter, requiring longer signals to work with it.
Your best option however is likely to use an IIR filter, designed by —
Wp = [1 8]/Fn; % Passband Frequency (Normalised)
Ws = [0.8 8.2]/Fn; % Stopband Frequency (Normalised)
Rp = 1; % Passband Ripple
Rs = 60; % Passband Ripple (Attenuation)
[n,Wp] = ellipord(Wp,Ws,Rp,Rs); % Elliptic Order Calculation
[z,p,k] = ellip(n,Rp,Rs,Wp); % Elliptic Filter Design: Zero-Pole-Gain
n
n = 11
[sos,g] = zp2sos(z,p,k); % Second-Order Section For Stability
figure
freqz(sos2, 2^16, Fs) % Filter Bode Plot
set(subplot(2,1,1), 'XLim',[0 10])%, 'XScale','log')
set(subplot(2,1,2), 'XLim',[0 10])%, 'XScale','log')
This is a very short and efficient filter. Use filtfilt to do the actual filtering:
EEG_Filtered - filtfilt(sos,g,EEG);
.
  2 Comments
FRANCESCA SANASI
FRANCESCA SANASI on 8 Oct 2023
Edited: FRANCESCA SANASI on 8 Oct 2023
Thank you so much! Actually I think I was able to create a bandpass filter with firpm, even though I'm not sure it's cutting off at the right frequency; i'll paste the newer code:
fFIR= [0 1 4 6 8 9]; % frequenza di taglio in Hz
a=[0 1 1 0]; %ampiezza desiderata
rp= 0.5; %ripple banda passante in dB
rs= 30; %ripple banda di stop in dB
fs=500; % frequenza di campionamento in Hz
% La deviazione (dev) rappresenta il massimo ripple possibile tra la risposta del filtro e la risposta desiderata,
% quindi dovrebbe essere calcolata come il valore massimo tra rp e rs linearizzati (prima erano in dB)
dev = [ 10^(-rs/20) (10^(rp/20)-1)/(10^(rp/20)+1) (10^(rp/20)-1)/(10^(rp/20)+1) 10^(-rs/20)];
%ricavo l'ordine minimo del filtro
[n,fo, ao, w]=firpmord(fFIR,a,dev,fs);
b = firpm(n,fo,ao,w);
freqz(b,1,512,fs )
title('Filtro FIR passabanda con frequenze di taglio [1,8] Hz')
Thanks also for the suggestion on the IIR filter, it is actually the third question of the exercise I'm trying to do so your answer will surely come in handy.
Star Strider
Star Strider on 8 Oct 2023
As always, my pleasure!
You had better results with firpm than I did!
I do not usually use firpm, preferring fir1, usually with kaiserord, to create comb filters that have multiple passbands and stopbands that make them preferable to and more efficient than designing a number of IIR filters to do the same thing. For single bandpass or stopband filters or with short signals (that would not work with FIR filters), I generally use elliptic filters.

Sign in to comment.

More Answers (0)

Products


Release

R2023b

Community Treasure Hunt

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

Start Hunting!