Smaller frequency bins after FFT for PPG signal

2 次查看(过去 30 天)
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?

采纳的回答

Star Strider
Star Strider 2022-4-28
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 个评论
Jeremy Lin
Jeremy Lin 2022-4-29
编辑:Jeremy Lin 2022-4-29
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 2022-4-29
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.

请先登录,再进行评论。

更多回答(0 个)

类别

Help CenterFile Exchange 中查找有关 Measurements and Feature Extraction 的更多信息

产品


版本

R2022a

Community Treasure Hunt

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

Start Hunting!

Translated by