Question

Cette question repose sur une précédente question similaire.

I ai l'équation suivante et ajusté (quelques données aléatoires): 0,44 * sin (N * 2 * PI / 30)

Je suis en train d'utiliser la FFT pour obtenir la fréquence à partir des données générées. Cependant, la fréquence finit par être proche, mais pas égale à la fréquence (ce qui rend l'onde un peu plus grande que prévu)

Les fréquences qui sont au maximum pour la FFT est 7 Hz, mais la fréquence attendue est (30 / 2PI) 4.77hz.

J'ai inclus un graphique de la FFT et transcrites valeurs.

text alt

Le code J'utilise est:

[sampleFFTValues sFreq] = positiveFFT(sampledata, 1);
sampleFFTValues = abs(sampleFFTValues);
[v sFFTV]= max(sampleFFTValues)

positif FFT peut être trouvé ici . Fondamentalement, il centre le graphe FFT et coupe les signaux négatifs.

Ma question est de savoir comment puis-je obtenir la FFT pour être plus précis, sans avoir à recourir à des moindres carrés pour seulement la fréquence?

Était-ce utile?

La solution

Je ne pense pas FFT est bon pour une mesure de fréquence fine résolution (quasi) des signaux périodiques -. Voir ci-dessous

Chaque FFT discrète a répand sur les fréquences de casiers non entiers (qui se trouve sur une fréquence quelconque qui ne correspond pas exactement à l'une des étapes de fréquence de la FFT notamment); ces fréquences « intermédiaires » seront tachées / répartis autour du bac entier le plus proche. La forme de cet étalement ( « étalement fonction ») dépend de la fonction de fenêtrage utilisée pour la FFT. Cette fonction d'étalement - de simplifier et de généraliser les choses - est soit très étroite mais très très haillons (pics très élevés / très basses vallées), ou plus large mais moins haillons. En théorie, vous pourriez faire un très beau balayage de fréquence des ondes sinusoïdales et calculer FFT pour chacun d'eux, et vous pouvez « calibrer » en enregistrant les sorties de tous TFR la forme et le comportement de la fonction ainsi que la fréquence qui a abouti à cette sortie, puis en comparant la sortie FFT du signal à mesurer les résultats précédemment enregistrés et de trouver le plus « proche » on trouver une fréquence plus exacte.

Beaucoup d'efforts.

Mais ne le faites pas si vous avez seulement besoin de mesurer la fréquence d'un signal unique.

Au lieu de tenter de mesurer la longueur d'onde. Cela peut être aussi simple que la mesure de la distance entre zéro croix (peut-être pour plusieurs cycles pour obtenir plus de précision - Heck, mesure 1000 cycles si vous avez que beaucoup) dans les échantillons, et diviser le taux d'échantillonnage par que pour arriver à la fréquence. Beaucoup plus simple, plus rapide et beaucoup plus précis.

Exemple: taux d'échantillonnage 48000 Hz, 4,77 Hz résultats de signal en ~ 0,0005 Hz résolution juste en mesurant la durée du cycle un avec l'approche la plus grossière. (Si vous prenez n cycles, la résolution de fréquence multiplie par n et.)

Autres conseils

Comme mentionné par d'autres, vous interprétez mal la fréquence du signal. Permettez-moi de donner un exemple pour effacer quelques petites choses:

Fs = 200;                        %# sampling rate
t = 0:1/Fs:1-1/Fs;               %# time vector of 1 second 
f = 6;                           %# frequency of signal
x = 0.44*sin(2*pi*f*t);          %# sine wave

N = length(x);                   %# length of signal
nfft = N;                        %# n-point DFT, by default nfft=length(x)
                                 %# (Note: it is faster if nfft is a power of 2)
X = abs(fft(x,nfft)).^2 / nfft;  %# square of the magnitude of FFT

cutOff = ceil((nfft+1)/2);       %# nyquist frequency
X = X(1:cutOff);                 %# FFT is symmetric, take first half
X(2:end -1) = 2 * X(2:end -1);   %# compensate for the energy of the other half
fr = (0:cutOff-1)*Fs/nfft;       %# frequency vector

subplot(211), plot(t, x)
title('Signal (Time Domain)')
xlabel('Time (sec)'), ylabel('Amplitude')

subplot(212), stem(fr, X)
title('Power Spectrum (Frequency Domain)')
xlabel('Frequency (Hz)'), ylabel('Power')

time_frequency_domain

Maintenant, vous pouvez voir que le pic de la FFT correspond à la fréquence d'origine du signal à 6Hz

[v idx] = max(X);
fr(idx)
ans = 
      6

On peut même vérifier que théorème de Parseval contient:

( sum(x.^2) - sum(X) )/nfft < 1e-6

Option 2

Nous pouvons également utiliser les fonctions de la boîte à outils de traitement du signal:

%# estimate the power spectral density (PSD) using the periodogram
h = spectrum.periodogram;
hopts = psdopts(h);
set(hopts, 'Fs',Fs, 'NFFT',nfft, 'SpectrumType','onesided')

hpsd = psd(h, x, hopts);
figure, plot(hpsd)

Pxx = hpsd.Data;
fr = hpsd.Frequencies;
[v idx]= max(Pxx)
fr(idx)

avgpower(hpsd)

periodogramme

Notez que cette fonction utilise une échelle logarithmique: plot(fr,10*log10(Pxx)) au lieu de plot(fr,Pxx)

En supposant N est le temps en secondes, la fréquence est 1 / 30Hz (y=A * sin( 2* PI * f * t))

Fréquence Résolution = Taux d'échantillonnage / Points FFT

Le taux d'échantillonnage est déterminé par le critère de Nyquist, la fréquence d'échantillonnage (échantillons / seconde) doit être au moins deux fois la fréquence maximale à analyser, par exemple, 48kHz pour analyser jusqu'à 24 kHz. (Pour les données « réelles », il est bon d'avoir un peu d'un tampon).

Alors, vous pourriez avoir besoin d'augmenter la taille de votre FFT.

Ce que vous recherchez est une méthode d'estimation de la fréquence, et il y a beaucoup. Une FFT est une composante de plusieurs méthodes d'estimation. Tout en utilisant l'amplitude crête bin, comme dans votre exemple, vous donne la plus mauvaise résolution (mais la plus grande immunité au bruit à tout autre exactement sinusoïdes périodiques). Dans des situations de faible bruit, vous pouvez interpoler. interpolation parabolique de la grandeur logarithmique est une estimation commune, mais interpolation de synchronisation des résultats de la FFT peut être préférable pour une fenêtre rectangulaire. Zero-padding et de faire une FFT plus est pratiquement équivalent à l'interpolation.

Pour une sinusoïde exacte à zéro bruit, oublier la FFT et résolvez que l'équation à 3 inconnues, ce qui peut impliquer aussi peu que 3 ou 4 points d'échantillonnage non-crénelage, des algorithmes pour ce faire ici et ici .

Je liste quelques autres méthodes d'estimation de fréquence sur mon DSP page Web .

Si vous générez d'une fonction, par rapport à travailler avec des échantillons, vous pouvez générer beaucoup de points et exécuter un BIG fft de sorte que les bacs de fréquences sont très petites pour une grande précision. Mais il ne résoudra pas le problème fondamental.

D'abord, une correction à votre question: (30 / 2PI) n'est pas la fréquence. La fréquence de votre signal est 1/30 * quel que soit le taux d'échantillonnage que vous avez utilisé. Deuxièmement, pouvez-vous me dire quelle était la longueur du vecteur sampledata? Lorsque FFT renvoie un vecteur de valeurs, la valeur de la i-ième correspondra à f_i = i / N où N est une longueur de vecteur et i \ in [0, N-1] Vous voulez i / N exactement égal 1/30 pour un entier i. En d'autres termes, N doit être égal à 30 * i, à savoir, N doit être un multiple de 30. maintenant, était la longueur du vecteur que vous avez utilisé, un multiple de 30? Sinon essayer de faire, et qui devrait résoudre le problème.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top