Matlab – Low frequency, high pass filter for MATLAB

filterMATLABsignals

I'm having real trouble trying to create/use a filter in MATLAB which is accurate enough at very low frequencies.

I'm interested in a range of signals between 5 and 50Hz, the high band isn't too much of a concern, what I really want to do is filter anything beneath 5Hz. However, I'm finding the roll off with Butterworth filters is doing very little in terms of filtering, it's just attenuating the signal to about half what the normal signal is.

I've tried two methods. One was using MATLABs filter tool fdatool and the other was a manual method below:

filtLow = 5;
filtHigh = 50;
Fs = 1000;
[b, a] = butter(1, filtLow/(Fs/2), 'high');
y = filtfilt(b, a, data);

or

[b, a] = butter(1, [filtLow/(Fs/2), filtHigh/(Fs/2)]);
y = filtfilt(b, a, data);

Can anyone give me a suggestion or code which may give me better results?

Best Answer

If you want signals in the range of 5-50Hz and nothing else, the order of your filter will likely wind up being quite high. Also, a butterworth filter, although linear phase and flat frequency response in the passband does not have the best rolloff from pass band to rejection. If you can stand a little distortion, an elliptical or bessel filter would give you a much tighter rolloff. Also, if you use 5 Hz as your cutoff frequency, it should, in theory, be the -3 dB point, which is why you are seeing attenuation of 1/2. You'll need to consider some specifications.

  1. What is the lowest frequency I can accept in the passband?
  2. What is the highest frequency I can accept in the passband?

You consider this to determine desired realizable attenuation. Right now, it looks as if you want infinite attenuation at a single frequency. Unfortunately, you'll need to decide what attenuation over a frequency range is acceptable to your design.

I tried my hand at the high pass portion and came up with the following:

Fs = 1000;
BW = Fs/2;
% get the recommended order and cutoff for high pass
[n,Wc] = buttord(10/BW,5/BW,3,10);
% get the butterworth filter
[b,a] = butter(n,Wc);
% get the frequency response
[H,W] = freqz(b,a);
% plot the low end of the response
plot( BW*W(1:10)/pi, 20*log10(abs(H(1:10))) )

Gives me ->

Frequency Response

Which seems pretty reasonable.

Related Topic