SciLab: FFT (falsche Amplitude)

Gast #4021059
Lesenswert?

Hallo zusammen,

ich habe von meinen Messdaten eine FFT in SciLab gemacht.
Es handelt sich um ein Rechtecksignal mit 4kHz und 5V Amplitude.
Wie im angehängten Plot zu erkennen, sind meine Frequenzen richtig, 
jedoch habe ich wohl einen Fehler in der Normierung meiner Amplituden.

X=2/N*abs(fft(x)); Ich teile durch die Blocklänge N und multipliziere 
mit 2. Um nur den Realteil zu erhalten, nutze ich die Funktion abs.

Wäre dankbar für Hinweise wo mein Fehler liegt.
1
Fs=62500;                         // Abtastrate 62.5kHz
2
N=length(x);                            // 4096 FFT-Blocklänge
3
t = 0:1/Fs:(N-1)/Fs;
4
n=length(t);
5
F=linspace(0,Fs,n);                     // Frequenzachse
6
whm=window('hm',n)';                    // Hamming-Fenster
7
xf=x.*whm;                              // Fenster multiplizieren
8
plot(F,xf);                             // x mit Windowfunktion
9
df=Fs/N;                                // 15.3Hz Auflösung
10
fmax=Fs/2;                              // 31.25kHz Nyquistfrequenz
11
X=2/N*abs(fft(x));                      // Transformation [AMPLITUDE FALSCH]

Liebe Grüße Mgx
Angehängte Dateien:
#4021392
Lesenswert?

Mit abs bekommst du nicht den realteil sondern den Betrag des komplexen 
Vektors, nur als Anmerkungen. Magst du mal den ganzen Code zeigen? Mir 
fehlt da der plot des Spektrums und der Frequenzshift.
Die Normierung mit 2 ist eigentlich korrekt, aber vergiss nicht, das 
beim dc Anteil nicht zu machen!
Was passiert ohne Fenster?
Gast #4023440
Lesenswert?

Der Plot ohne Fensteranwendung ist bereits angehängt. Es sollte eine 
Amplitude von 5 herauskommen im Frequenzbereich, aber ich bekomm eine 
von ~6,3.

Man kann sehen dass ich nicht xf (x mit Fensterfunktion), sondern von 
dem Signal x eine FFT mache. Bei Anwenden der Fensterfunktion bekomme 
ich komischerweise eine geringere Amplitude von ca 3,4. Sollte durch das 
Reduzieren der Nebenfrequenzen (Leakage) die Amplitude nicht eher höher 
werden?

Wie normiere ich meine Amplitude korrekt?
Gast #4023454
Lesenswert?

Okay das klingt einleuchtend bei einem Rechtecksignal, aber sollte ich 
bei Anregung durch ein Sinussignal nicht die gleiche Amplitude im Zeit- 
wie auch im Frequenzbereich bekommen?

Hab das gleiche Spiel nämlich auch mit einem Sinussignal gemacht.

Danke für die Hilfe!
#4023470
Lesenswert?

Man kann sehen, dass er die Frequenz nicht richtig trifft.

Ich kann schwer sagen, woran es liegt, dass das ungenau wird, hier ein 
paar Vermutungen:

Für den Amplitudenfehler:
- Die Fensterung reduziert den Energiegehalt des Eingangssignals 
und/oder erzeugt leakage. Wie sieht das ohne Fenster aus?

Für den Frequenzshift:
- Die FFT Algorithmen übersteuern den Wertebereich zwischendurch. 
Beispiel: Radix 2 FFTs können pro Stufe den Eingangswert um bis zu 
Faktor 2.8 anheben (wenn ich mich nicht verrechnet habe). Bei 10 Stufen 
ist das eine resultierende Amplitude von ca. 90000, die nicht mehr in 
ein int16 passt.
Wenn das Programm auf einem Computer läuft ist das wohl irrelevant 
(float)

Wie sieht denn der Sinus aus? Wie wird der erzeugt?
Gast #4023504
Lesenswert?

Durch den Leakage-Effekt treten Nebenfrequenzen auf, die Enerige 
verteilt sich somit auf diese und die Amplitude meiner eigentlichen 
Grundschwingung nimmt dadurch ab - oder hab ich da was falsch 
verstanden? Der Energiegehalt wäre ohne Nebenfrequenzen komplett in 
meiner Amplitude der Grundschwingung wiedergespiegelt!?

Anbei ein Plot von Real-/Imaginär-Teil oder soll ich euch alle 1024 
Werte meines Ergebnisses der FFT hier reinposten? ^^

plot gibt X=fft(x) wieder - ohne Fensterung, ohne abs
Angehängte Dateien:
#4023598
Lesenswert?

Mgx schrieb:
> Durch den Leakage-Effekt treten Nebenfrequenzen auf, die Enerige
> verteilt sich somit auf diese und die Amplitude meiner eigentlichen
> Grundschwingung nimmt dadurch ab

das stimmt.

Mgx schrieb:
> Der Energiegehalt wäre ohne Nebenfrequenzen komplett in
> meiner Amplitude der Grundschwingung wiedergespiegelt!

das auch. ;)

Mgx schrieb:
> Anbei ein Plot von Real-/Imaginär-Teil

Das ist nur eins von beiden! Du müsstest wohl zwei plots haben.
Also zum Beispiel plot(real(fft(X))) und plot(imag(fft(X))). Sonst wäre 
auf der y-Achse auch nicht die Amplitude, sondern der Imaginärteil.
Gast #4023849
Lesenswert?

Was ist genau gemeint mit ungenau getroffenen Frequenzen? Bedeutet, dass 
die FFT durch ihren Algorithmus die Frequenzen aus dem Zeitbereich nicht 
genau ermitteln kann?

Ich möchte nach der FFT Filter anwenden um Pegel in bestimmten 
Frequenzbereichen zu ermitteln und hätte daher gerne die "richtigen" 
Amplituden ;) - in SciLab habe ich mir hierfür gewisse Filter gebaut und 
angewendet, jedoch gehen die Filter-"Amplituden" nur bis 1 (weil Ua/Ue), 
meine Amplituden des Frequenzbereichs haben jedoch ihre eigenen Werte 
(z.B. 3,8V) - wie kann ich die Filter hier korrekt anwenden? Muss ich 
meine Amplituden vorher normieren? Eine weitere Frage wäre, ob durch 
diese digitalen Filter eine Phasenverschiebung entsteht, welche ich 
berücksichtigen muss, obwohl ich NUR den Betrag errechnet habe.

Danke für die Hilfe soweit!
#4027165
Lesenswert?

Ich denke die falsche Amplitude löst du durch eine weitere Normierung 
über die Summe des Fensters.

Die Wahl des Fensters bleibt dir überlassen, flattop ist gut, wenn du 
starke leakage Effekte hast, macht aber die Frequenzauflösung ziemlich 
mies. Hanning läuft ganz gut bei mir.
1
 fun = rect(...); % oder sinus oder was auch immer
2
 N = length(fun) * paddingfactor; % zeropadding für factor > 1
3
 winfun = flattopwin(length(fun));
4
 fun = fun.*winfun*length(fun)/sum(winfun);
5
 F=abs(fft(fun,N));
6
 F=2*F./length(fun); %normieren, Faktor 2, damit Peaks Amplitude wiederspiegeln
7
 F(1)=F(1)/2; % DC Anteil anpassen, da zwei Peaks auf f=0 fallen
8
 plot(freq,F);

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren