Why is my fft peak frequency slightly lower than my known input signal?

4 ビュー (過去 30 日間)
David Streinger
David Streinger 2016 年 4 月 18 日
コメント済み: David Streinger 2016 年 4 月 18 日
I do an fft of an input signal which I know is exactly one 1kHz, since it comes from a frequency generator.
The peak is at 996, with a measurment time of 10 sec and a sampling frequency of 51000.
measurement1=importdata('765_180.txt');
t=measurement1(:,1);
MIC2=measurement1(:,2);
MIC2_FFT=fft(MIC2);
N = length(measurement1);
figure
grid on
grid minor
subplot(2,1,1)
bin_vals = [0 : N-1]; %adapt to frquency instead of bins
time_new = bin_vals*fs/N; %adapt to frquency instead of bins
N_2 = ceil(N/2); %ceil rounds to next integer-->eliminates the artifacts at the end
plot(time_new(1:N_2), MIC2_FFT_ABS(1:N_2))
%plot(time_new, MIC2_FFT) %this would be with artifacts at freq end
xlabel('Frequency [Hz]')
ylabel('Magnitude');
title('Magnitude spectrum Mic 2 FFT');
Thanks for your help :)

採用された回答

Wayne King
Wayne King 2016 年 4 月 18 日
Hi David, we don't see what fs is in your code above, but in general your code looks like it would generate the expected answer. Once you obtain your t variable above from the first column of the imported data, if you execute
mean(diff(t))
Does that return 1.9608e-05?
You would expect a sampling interval of 1.9608e-05 seconds given the sampling frequency of 51 kHz. I would check to see if that is what you get, otherwise everything else will be off. Again, if fs is specified corrected and the spacing in the t vector is correct, then once you generate your time_new vector if you execute
mean(diff(time_new))
Do you get 0.1? That should be your frequency resolution. Here is an example that produces the expected result, it is essentially your code with a few variables renamed.
fs = 51e3;
dt = 1/fs;
t = 0:dt:10-dt;
% test signal
x = cos(2*pi*1e3*t);
xdft = fft(x);
powerx = abs(xdft(1:Nyq));
N = length(t);
bins = 0:N-1;
freq = bins*fs/N;
Nyq = N/2;
plot(freq(1:Nyq),powerx);
You see in the above, the maximum occurs at bin 1001
[~,idx] = max(powerx);
idx
freq(idx)
Which corresponds to 1000 Hz.
  1 件のコメント
David Streinger
David Streinger 2016 年 4 月 18 日
編集済み: David Streinger 2016 年 4 月 18 日
Hello Wayne King, fs is my sampling frequency and 51khz. I included your suggestions of the mean values in my code and get the following:
mean(diff(t)) = 1.9531e-05
mean(diff(time_new)) = 0.1
So it is pretty much what you expected.
The weird part is that with a test signal like you put in, I actually get the correct 1kHz, but not With my measurment data. That's weird because I use a TGA1244 Frequency generator, which should provide a correct signal. Also with a test tone 1kHz from youtube I had 996 Hz as a result.
here is a link to my test file if that helps:
https://www.dropbox.com/s/si1q6rnb3qwg2st/1kHz_10s_3mics.txt?dl=0
thanks for your help :)

サインインしてコメントする。

その他の回答 (1 件)

Wayne King
Wayne King 2016 年 4 月 18 日
Hi David, You are using the wrong sampling frequency. The actually sampling frequency is 51200. You can see this by entering
1/mean(diff(t))
Once you have the correct sampling frequency, the tone is exactly where you would expect it.
data = importdata('1kHz_10s_3mics.txt');
fs = 1/mean(diff(data(:,1))); % corrected
N = length(data(:,2));
freq = (0:N-1)*fs/N;
Nyq = N/2;
datadft = fft(data(:,2));
% Power but not scaled properly
powerdata = abs(datadft(1:Nyq));
plot(freq(1:Nyq),powerdata);
[~,idx] = max(powerdata);
freq(idx)
  1 件のコメント
David Streinger
David Streinger 2016 年 4 月 18 日
Thanks a lot, looks like I have a problem with my labview code. :)
I know have 1000,0063 which is completely enough for my purpurse :)
Regards David

サインインしてコメントする。

カテゴリ

Help Center および File ExchangeParametric Spectral Estimation についてさらに検索

Translated by