How does the Magnitude of an FFT relate back to the Time Series wave it was created from? Alright, to start out I am a mechanical engineer with very little circuits and digital signal processing background. So please excuse my ignorance as this is far out of my usual territory.

When looking at the magnitude of an FFT of a signal, I understand that the magnitude is in the units of the time signal (in my case it is Volts). I also understand that you need to divide the FFT results by the transform length in order to normalize.

What I don't completely understand is how the magnitude of the FFT result relates back to the time signal. From what (I think) I understand it should be related to the amplitude of the time signal. From my MATLAB code that I made (posed below) it seems that it returns 1/4 of the amplitude of the signal. Is this correct? What is the physical meaning of it?

And then on a related note, if it is related to the amplitude of a time signal, what is the sampling rate needed to get a decent measure of the amplitude. I know the highest resolvable frequency for an FFT is the nyquist frequency, but I haven't been able to find anything about accurate measurements of a signal's amplitude.

Thanks in advance for any and all help on this.

MATLAB Code:

f_s = 20;              % sampling (hz)

f_w = 2;                % frequency of wave (hz)
A = 5;                  % amplitude


d_t = 1/f_s;
t = 0:d_t:2-d_t;
n = length(t);

% Creating the time signal
time_signal = A*sin(f_w*2*pi*t);

% Generating and applying a hanning window on the time signal
window = hann(n)';
windowed_time_signal = time_signal.*window;

% Taking FFT of windowed time signal
raw_fft = fft(windowed_time_signal);

% Frequency resolution of FFT
d_f = f_s/n;

% Frequency spectrum for full FFT
f_spectrum_full = (0:n-1)*d_f;

% Only first half of FFT contains useful information
half_fft = raw_fft(1:(n/2));

% Frequency scale for half FFT
f_spectrum_half = (0:n/2-1)*d_f;

% Magnitude of the half FFT
magnitude = abs(half_fft);

% Normalized version of the magnitude
normalized = magnitude/(n); 


figure (1)

subplot(2,1,1)
plot(t,time_signal)
title('time wave')

subplot(2,1,2)
plot(t,windowed_time_signal)
title('windowed time wave')


figure (2)

subplot(3,1,1)
plot(f_spectrum_half,magnitude)
title('magnitude')

subplot(3,1,2)
plot(f_spectrum_half,normalized)
title('magnitude')
You can calculate the coherent or DC gain of a window with:

coherent_gain = sum(window)/n;

with a Hann window, and n = 40, this comes to 0.4875, as hotpaw2 mentioned.

You can therefore eliminate the effect of the coherent gain of the window on your spectral estimate by replacing windowed_time_signal = time_signal.*window; with windowed_time_signal = time_signal.*window/coherent_gain;.

If your main priority is very accurate amplitude - and you're unconcerned with spectral leakage as Sebastian mentioned, then the flattop window
is the way to go. Here's the matlab docs.

Just replace window = hann(n)'; with window = flattopwin(n)';.

Also, if you have the ability to collect more samples, that will likely improve the spectral estimate from your FFT (assuming the underlying process in your application is somewhat stationary/ergodic). You can also take FFTs of successive (possibly overlapping) slices and average them.

Furthermore, as hotpaw2 mentioned, selecting a sample rate depends very strongly on your application, and how many samples you intend to collect. That said, I've often used fs = 2.56 * bw, with good results when it comes to spectral analysis or digital filtering.