Smaller frequency bins after FFT for PPG signal

2 visualizaciones (últimos 30 días)
Jeremy Lin
Jeremy Lin el 28 de Abr. de 2022
Comentada: Star Strider el 29 de Abr. de 2022
I have a PPG sensor sampling at Fs = 25Hz and I want to obtain the power in frequency bands <1, i.e. 0.04Hz-0.15Hz for LF and 0.15Hz-0.4Hz for HF. My PPG data is structured as a double, [Y x 25], where Y is the number of seconds of data and each seconds has 25 datapoints (therefore, N = 25 right?). I then compute the FFT per second to yield a double of [Y x 13] (N/2 + 1 = 13 right?), and each column of the output represents the power from 1Hz to 13Hz. How then do I decrease the size of my frequency bins (this is increasing frequency resolution right?) such that I can isolate the frequencies of float values? Does increasing N to N = 50, i.e. input for FFT is per 2 seconds rather than per second, result in the frequency bins being 0.5Hz instead?

Respuesta aceptada

Star Strider
Star Strider el 28 de Abr. de 2022
For a one-sided fft, the frequency vector will extend from 0 Hz (DC) to 12.5 Hz (Nyquist frequency) for your signal. The length of the fft (that can be varied with zero padding) controls the frequency resolution, and the frequency resolution is approximately equal to the sampling frequency divided by the length of the fft. (This is exact if the length of the fft is even, and approximate if it is odd, since the length of the fft must be an integer.)
So if the sampling frequency is known (and constant), to get a specific frequency resolution, the length of the fft must be at least:
NFFT = Fs/Fr;
where ‘Fs’ is the sampling frequency and ‘Fr’ is the desired frequency resolution. The fft is more computationally efficient if ‘NFFT’ is an integer power of 2 greater than or equal to the length of the signal.
Fs = 100;
t = linspace(0, Fs-1, Fs)/Fs;
s = sin(2*pi*29*t) + sin(2*pi*30*t);
figure
plot(t,s)
grid
xlabel('Time')
ylabel('Amplitude')
format longG
L = numel(t);
Ts = t(2) - t(1);
Fs = 1/Ts;
Fn = Fs/2;
NFFT1 = 2^nextpow2(L)
NFFT1 =
128
Fr1 = Fs/(NFFT1) % Frequency Resolution
Fr1 =
0.78125
FT1s = fft(s,NFFT1)/L;
Fv1 = linspace(0, 1, fix(NFFT1/2)+1)*Fn;
Iv1 = 1:numel(Fv1);
figure
plot(Fv1, abs(FT1s(Iv1))*2)
grid
xlabel('Frequency)')
ylabel('Amplitude')
title(sprintf('Frequency Resolution = %.7f Hz',Fv1(2)))
NFFT2 = 2^(nextpow2(L)+4)
NFFT2 =
2048
Fr2 = Fs/(NFFT2) % Frequency Resolution
Fr2 =
0.048828125
FT2s = fft(s,NFFT2)/L;
Fv2 = linspace(0, 1, fix(NFFT2/2)+1)*Fn;
Iv2 = 1:numel(Fv2);
figure
plot(Fv2, abs(FT2s(Iv2))*2)
grid
xlabel('Frequency)')
ylabel('Amplitude')
title(sprintf('Frequency Resolution = %.7f Hz',Fv2(2)))
.
  2 comentarios
Jeremy Lin
Jeremy Lin el 29 de Abr. de 2022
Editada: Jeremy Lin el 29 de Abr. de 2022
Oh wow, ok I will give this a try, thank you so much for the thorough explanation! Sorry but why did you divide your FFT by the length of your signal?
Star Strider
Star Strider el 29 de Abr. de 2022
My pleasure!
Dividing by the signal length (and that is constant even if ‘NFFT’ is greater than the signal length) normalises the signal so that the amplitudes are correct, and that has to do with the way the fft is calculated, specifically because it is a series of summations at different frequencies.
See the documentation on the fft function for details.

Iniciar sesión para comentar.

Más respuestas (0)

Categorías

Más información sobre Measurements and Feature Extraction en Help Center y File Exchange.

Productos


Versión

R2022a

Community Treasure Hunt

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

Start Hunting!

Translated by