MATLAB: Eliminating noise using butterworth bandpass filter

bandpass filterbutterworthsignal processing

The aim of this task is to build a bandpass filter to filter out the noise from a given data. The sampling frequency was 3490Hz. I have used fft to determine what the noises are in the given signal which are: 20Hz. 110Hz, 200Hz and 470Hz. The peak at 20Hz is peculiar to me though as the left hand side of the fft figure should be a mirror image of the right hand side of the figure. This is the fft result that I achieved:
The frequency is in bins and was converted to Hz by comparing with the sampling frequency.
Next, I need to determine the actual noise of the signals. I am not sure how to determine this. After all that, I can then possibly make a bandpass filter by the basic code flow below:
Fs = 3490; % Sampling Frequency (Hz)
Fn = Fs/2; % Nyquist Frequency (Hz)
Wp = [futcutlow fcuthigh]/Fn; % Passband Frequency (Normalised)
Ws = [futcutlow*0.95 fcuthigh/0.95]/Fn; % Stopband Frequency (Normalised)
Rp = 1; % Passband Ripple (dB)
Rs = 150; % Stopband Ripple (dB)
[n,Wn] = buttord(Wp,Ws,Rp,Rs); % Filter Order
[z,p,k] = butter(n,Wn); % Filter Design
[sosbp,gbp] = zp2sos(z,p,k); % Convert To Second-Order-Section For Stability
freqz(sosbp, 2^20, Fs) % Filter Bode Plot
filtered_signal = filtfilt(sosbp, gbp, signal); % Filter Signal
The problems that I've encountered is: 1) Why is there a spike in the left hand side of the fft at 20Hz? 2) How do I determine the actual noise that I need to eliminate? 3) How can I make the basic code flow work from that point onwards?

Best Answer

Assuming ‘signal’ is a vector (as it appears to be in the image), you can accurately calculate the fft (link) with:
L = length(signal); % Signal Length
FTsignal = fft(signal)/L; % Fourier Transform
Fv = linspace(0, 1, fix(L/2)+1)*Fn; % Frequency Vector
Iv = 1:numel(Fv); % Index Vector
figure(2)
plot(Fv, abs(FTsignal(Iv))*2)
grid
That information will produce the correct amplitude-frequency data, and will allow you to design your filter.
For your signal, a Chebyshev Type II filter may work better, if you want to eliminate or pass specific frequencies. The filter design then becomes:
Wp = [fcutlow fcuthigh]/Fn; % Passband Frequency (Normalised)
Ws = [fcutlow-1 fcuthigh+1]/Fn; % Stopband Frequency (Normalised)
Rp = 1; % Passband Ripple (dB)
Rs = 50; % Stopband Ripple (dB)
[n,Ws] = cheb2ord(Wp,Ws,Rp,Rs); % Filter Order
[z,p,k] = cheby2(n,Rs,Ws); % Filter Design, Sepcify Bandpass
[sos,g] = zp2sos(z,p,k); % Convert To Second-Order-Section For Stability
figure(3)
freqz(sos, 2^16, Fs) % Filter Bode Plot
signal_Filtered = filtfilt(sos, g, signal); % Filter Signal
You may need to experiment to get the result you want.