How to obtain correct frequency and amplitude via FFT
77 Ansichten (letzte 30 Tage)
Ältere Kommentare anzeigen
Nicolas
am 10 Jan. 2023
Bearbeitet: Paul
am 18 Jan. 2023
Hi
I have tried to test a Fast Fourier Transform using a simple example signal. The signal has a length of 2 seconds, a frequency of f = 2 and an amplitude of a = 3. However, when I apply the FFT and determine the maxima via the command findpeaks, I get f = 1.8311 and a = 2.5763. This means that the results differ quite a lot from my input.
I have already looked around here in the forum, but so far I have not been able to find a real solution to my problem. I hope that someone here has an idea what I am doing wrong.
I'd appricate the help! Thanks
clear all; close all; clc;
% create sinusoidal signal
f_sign = 2 ; % signal frequency
a_sign = 3 ; % signal amplitude
t_sign = 2 ; % length of signal [s]
dt_sign = 0.0001 ; % sample rate [s]
nt_sign = t_sign/dt_sign ; % discrete number of datapoints
t = 0:dt_sign:t_sign ; % Time vector
y = a_sign*sin(2*pi*f_sign*t) ; % create signal
% Fourier transformation
y_fft = y - mean(y);
nfft = 2^nextpow2(nt_sign);
FFT = fft(y_fft,nfft)/nt_sign;
FFT = 2*abs(FFT(1:nfft/2+1));
fs=1/dt_sign;
f = fs/2*linspace(0,1,nfft/2+1);
% find maximum amplitude and frequency
[pks,locs] = findpeaks(FFT,f);
[pks_max,idx_pks_max] = max(pks);
locs_max = locs(idx_pks_max);
% results
f_fft = locs_max
a_fft = pks_max
6 Kommentare
Star Strider
am 17 Jan. 2023
The multiplication-by-2 is important, and is in the documentation. The reason is that the signal energy is divided (in the two-sided fft) between the ‘positive’ and ‘negative’ frequencies. The multiplication-by-2 (in either the one-sided to two-sided fft corrects) for this, giving an appropriate amplitude.
Paul
am 17 Jan. 2023
Bearbeitet: Paul
am 18 Jan. 2023
I thought I was clear that my comment was only relevant to the FFT(1) and FFT(N/2+1), which are the elements of FFT that correspond to f(1) and f(end). So, I'm only talking about those two elements.
Suppose we have "sine wave" at zero frequency with amplitude = 3. For simplicity, I'll assume N = 8.
N = 8;
n = (0:(N-1));
x = 3*cos(0*n)
X = fft(x)/N
As we can see, the first point in X is 3, which is the amplitude of the input. So why multiply X(1) by 2?
Now, let the frequency be pi, i.e., the Nyquist frequency
x = 3*cos(pi*n)
X = fft(x)/N
The element X(N/2+1) that corresponds to the Nyquist frequency is 3, which is the amplitude of the input. Why multiply
X(N/2+1) by 2?
Keep in mind that if N is odd, no element of X corresponds to the Nyquist frequency. But we still have the same issue with X(1) regardless.
P1 = P2(1:L/2+1);
P1(2:end-1) = 2*P1(2:end-1);
i.e., the first element of P1 is not multiplied by 2, and neither is the last element for L even.
Akzeptierte Antwort
Star Strider
am 10 Jan. 2023
Increase the frequency resolution (I doubled it here, although you can increase it further) with
nfft = 2^nextpow2(nt_sign)*2
and the results significantly improve.
With that:
f_fft = 1.9836
a_fft = 3.0070
and you can likely get improved accuracy with finer ffrequency resolution.
% clear all; close all; clc;
% create sinusoidal signal
f_sign = 2 ; % signal frequency
a_sign = 3 ; % signal amplitude
t_sign = 2 ; % length of signal [s]
dt_sign = 0.0001 ; % sample rate [s]
nt_sign = t_sign/dt_sign ; % discrete number of datapoints
t = 0:dt_sign:t_sign ; % Time vector
y = a_sign*sin(2*pi*f_sign*t) ; % create signal
% Fourier transformation
y_fft = y - mean(y);
nfft = 2^nextpow2(nt_sign)*2
FFT = fft(y_fft,nfft)/nt_sign;
FFT = 2*abs(FFT(1:nfft/2+1));
fs=1/dt_sign;
f = fs/2*linspace(0,1,nfft/2+1);
% find maximum amplitude and frequency
[pks,locs] = findpeaks(FFT,f);
[pks_max,idx_pks_max] = max(pks);
locs_max = locs(idx_pks_max);
% results
f_fft = locs_max
a_fft = pks_max
.
2 Kommentare
Weitere Antworten (0)
Siehe auch
Kategorien
Mehr zu Fourier Analysis and Filtering finden Sie in Help Center und File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!