signal amplitude using FFT - conflicting results and misunderstandings
4 views (last 30 days)
I am trying to measure the amplitude of different frequencies composing a signal using some code found here on this post.
Using this code
nfft = length(seg1); % calculate lenght of signal, seg1 is my signal
res = fft(seg1,nfft)/ nfft; % calculate fft over the whole segment normalizing the fft
f = Fs/2*linspace(0,1,nfft/2+1); % choosing correct frequency axes
res = res(1:nfft/2+1);
xlabel('Frequency in Hz');ylabel('Amplitude (mV)');
ytix = yticks*1000; % convert signal in mV (the original signal units are in V)
I get this
It seems fine, now I cannot verify if the signal amp is really around 45 mV but I could test it.
Just for proofing, I checked the help of the FFT function in MATLAB and I found this code to calculate signal power
Fs = 20000;
L = length(seg1); % length of signal
n = 2^nextpow2(L); % determine adjustable window size based on powers of 2
Y = fft(seg1,n,dim); % calculate fft of signal over the whole segment
P2 = abs(Y/L); % calculate signal power
P1 = P2(1:L/2+1);
P1(2:end-1) = 2*P1(2:end-1);
f = Fs*(0:(L/2))/L;
title('Single-Sided Amplitude Spectrum of X(t)')
what I get is this
I think the result is the same and it is just a matter of converting the units in the right way. Besides the 10^3 conversion, I think there is a 2x factor that needs to be removed somewhere...however I am not sure which would be the more correct way to calculate it.
While in the first code power is simply calculated as the absolute value of the fft transformed signal, In the second case it seems that, besides that (see the line commented with "calculate signal power"), the signal power is also multiplied per 2. As a result I get a double of the first power measurement in the second plot (note: the units in this second plot are not converted in millivolts but if one does it, the value seems to me double). And in fact I checked it, and it is the case.
Just wondering what would be the correct way to calculate signal amplitude. My signal is a sinewave voltage signal at 400 Hz. The amplitude should be in the range of few tens of mV (so the first calculation could be realistic... but the second too).
Thank you for your feedback !
dpb on 21 Nov 2021
Edited: dpb on 24 Nov 2021
The latter accounts that the FFT and PSD are two-sided (hence the "2" in the variable P2 for the PSD). The total energy is thus spread over [-Fmax +Fmax] or, in your case of a single frequency in two peaks, one at +/-400 Hz.
Hence, the total energy in the signal is twice the energy in each of those two peaks, ergo, this would indicate your input sine wave was of amplitude 90 mV rather than 45 mV.
It should be noted that the factor of 2 is applied only on the PSD elements (2:end-1) of P1 -- this is owing to the fact that the DC and Fmax components are unique in the two-sided PSD/FFT and so contain the total energy for those frequencies already. This can be confirmed empirically by comparing the DC component of a signal with a nonzero mean to the mean of the input time signal.
See the example at doc FFT from whence the latter code snippet was derived (recognizable by the variable naming) that illustrates producing the exact amplitudes of the input signal for a dual-component sine wave with two frequencies and amplitudes of 1.0 and 0.7.
Also NB: that the peak will only match the input exactly when the frequency resolution of the FFT is such that the bin center frequency of one of the FFT/PSD bins matches EXACTLY the input frequency of the signal; if this is not the case, then one will have energy content in surrounding bins as well and the total energy will be the integral of the peak, not just the peak value.
I've written and posted examples of these issues at length on Answers altho I didn't think to keep a library of links to those at hand...