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

조회 수: 7(최근 30일)
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)
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');

로그인 to comment.

### 채택된 답변

Wayne King 18 Apr 2016
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 18 Apr 2016
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

로그인 to comment.

Wayne King 18 Apr 2016
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;
% Power but not scaled properly
plot(freq(1:Nyq),powerdata);
[~,idx] = max(powerdata);
freq(idx)

#### 댓글 수: 1

David Streinger 18 Apr 2016
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

로그인 to comment.

이 질문에 답변하려면 로그인을(를) 수행하십시오.