Smaller frequency bins after FFT for PPG signal
2 views (last 30 days)
Show older comments
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?
0 Comments
Accepted Answer
Star Strider
on 28 Apr 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)
Fr1 = Fs/(NFFT1) % Frequency Resolution
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)
Fr2 = Fs/(NFFT2) % Frequency Resolution
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 Comments
Star Strider
on 29 Apr 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.
More Answers (0)
See Also
Categories
Find more on Measurements and Feature Extraction in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!