1
votes

I'm looking for some ideas to filter a noisy signal. my sampling Condition is :

  • Ferequency Sample Rate : 8000 Hz
  • Number Of Signal Sample : 32000 Byte ( about 4 Seconds)

I want to extract 15.84 Hz ferequency from my signal. my filter bandwidth must be very narrow. like 0.01 Hz or less. ( bandpass filter : 15.83Hz to 15.85Hz )

what is your idea?
i wrote FIR Bandpass Filter ( hanning window ) in matlab. but is there any idea to extract exact 15.84 Hz better?

this is my matlab code :

function Hd = hannigfilter
% FIR Window Bandpass filter designed using the FIR1 function.
% All frequency values are in Hz.
Fs = 8000;  % Sampling Frequency
N    = 4 * 4096;     % Order   -> for accurate filtering
Fc1  = 15.83;    % First Cutoff Frequency
Fc2  = 15.85;    % Second Cutoff Frequency
flag = 'scale';  % Sampling Flag
% Create the window vector for the design algorithm.
win = hann(N+1);

% Calculate the coefficients using the FIR1 function.
b  = fir1(N, [Fc1 Fc2]/(Fs/2), 'bandpass', win, flag);
Hd = dfilt.dffir(b);

and:

band_passed_signal = filter(Hd.Numerator,1,mySignal);

thanks.

3
I'm voting to close this question as off-topic because its about signal processing, not about programming. dsp.stackexchange.com is the right place to ask. - Daniel
I feel you're being too rigid. matlab is a technical computing language at heart, not a programming language. the lines between algorithm and implementation are often blurry. - crowdedComputeeer

3 Answers

1
votes

Assuming you have the signal processing toolbox, which it seems that you do, there are myriad ways to bandpass a signal. Your desire for narrowness of the band is probably computationally infeasible and higher-order filters are unstable, but one can more or less converge on a center frequency. In the following example I construct a fourth-order bandpass filter with butter(). I tested this with white noise and it seems to work fine. Y is the starting signal here, and newY is the output. And note that a butter() bandpass filter has an order twice the first argument, unlike a lowpass or highpass call, which is why filterOrder is 2. If you think it is necessary, you could do this same operation again on the output with a filter bandwidth an order of magnitude smaller in the call to butter().

fs=8000;
nyquist=fs/2;
CF=15.84;
filterOrder=2;

[b,a]=butter(filterOrder,[CF-.01 CF+.01]/nyquist);
newY=filter(b,a,Y);
0
votes

I'm not sure what you mean by extract... but. here's some ideas and an example assuming you want to remove some undesirable frequency from your signal.

if your goal is to extract some frequency, you don't want a band pass filter but notch filter. A bandpass is the opposite of extraction.

Try iirnotch

The below example creates a signal with two tones and additive noise. It then uses iirnotch to get coefficients that remove the second tone from the signal.

fs=8000;
N=32000;
n=(0:N-1)/fs;
x = 5*sin(2*pi*200*n)+2*sin(2*pi*600*n)+randn(1,N);
X=fft(x);
f=(-N/2:N/2-1)*fs/N
plot(f, fftshift(10*log10(X.*conj(X))))
xlim([0,1000])
ylim([40,100])
w0=600/(0.5*fs)
q=35;
[b,a]=iirnotch(w0,w0/q);
y=filter(b,a,x);
Y=fft(y);
plot(f, fftshift(10*log10(Y.*conj(Y))))
xlim([0,1000])
ylim([40,100])
0
votes

The uncertainty in frequency of a signal is proportional to the sample rate divided by the length. So you will either need to use more data or any filter will have an intrinsic wider bandwidth (due to the informational uncertainty, assuming non-zero noise).

If you have all of a sufficiently longer signal and want to see the beginning filtered without a delay, try running the signal backwards in time through the filter.