WICHTIG: Der Betrieb von goMatlab.de wird privat finanziert fortgesetzt. - Mehr Infos...

Mein MATLAB Forum - goMatlab.de

Mein MATLAB Forum

 
Gast > Registrieren       Autologin?   

Partner:




Forum
      Option
[Erweitert]
  • Diese Seite per Mail weiterempfehlen
     


Gehe zu:  
Neues Thema eröffnen Neue Antwort erstellen

Frequenzspektrum eines Schwingkreises

 

dahumpi1989
Forum-Anfänger

Forum-Anfänger


Beiträge: 11
Anmeldedatum: 28.12.13
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 29.03.2015, 15:25     Titel: Frequenzspektrum eines Schwingkreises
  Antworten mit Zitat      
Hallöchen liebe Gemeinde, ich versuche gerade einen doch recht simplen Schwingkreis zu analysieren und arbeite dabei mit LT-Spice um den ganzen Spaß zu simuliren und wollte die Datenauswertung mit MATLAB machen. Es handelt sich dabei um einen simplen Parallelschwingkreis mit der Resonanzfrequenz bei etwa 100MHz. Nun habe ich ein Skript geschrieben, dass quasi aus den exportierten .txt Datein die entsprechenden Größen extrahiert, darstellt und für die FFT vorbereitet. Nun kann ich ja sehr schön das FFT-Ergebnis von LT-Spice mit dem Ergebnis von Matlab vergleichen und dabei fällt mir auf, dass dort anscheinend noch ein Problem in der Umrechnung des Amplitudenspektrums besteht. Ich habe schon einige Zeit im Forum verbracht und versucht das Problem alleine zu lösen, komme jedoch nicht weiter.
Den Code poste ich einfach mal hier drunter.

Code:
clear all
%close all

freq = '100Mhz';
typ = 'Parallel';            %Reihe
Quelle = 'Stromquelle';    %Spannungsquelle; Stromquelle
datei = '.txt';

groesse = 'L1';             %L1,R1,C1,V;
flanke = 'EIN';              %EIN;AUS;

datei = [typ,'_',freq,'_',Quelle,datei];

daten = importdata(datei);

variablen = length(daten.textdata);

for i=1:1:variablen
   
    if(strcmp(Quelle,'Stromquelle'))
        if (i == 1)    
            eval([daten.textdata{i} '= daten.data(:,i);']);
        elseif (i == 2)
            eval([daten.textdata{i}(1) '= daten.data(:,i);']);
        elseif (i == 4)
            eval(['anregung' '= daten.data(:,i);']);
        else
            eval([daten.textdata{i}(3:4) '= daten.data(:,i);']);
        end
   
    else
        if (i == 1)    
            eval([daten.textdata{i} '= daten.data(:,i);']);
        elseif (i == 2)
            eval([daten.textdata{i}(1) '= daten.data(:,i);']);
        elseif (i == 3)
            eval(['anregung' '= daten.data(:,i);']);
        else
            eval([daten.textdata{i}(3:4) '= daten.data(:,i);']);
        end
    end
end

   
    fighandle1 = figure;
    grid on
    hold all

% Problem mit Latex-Textinterpreter, deshalb Y-Label manuell eingefügt
           
        if (strcmp(Quelle,'Stromquelle'))
           
            plot(time*10^6, eval(groesse),'Linewidth',2);
            plot(time*10^6, anregung,'Linewidth',2);
           
            if (strcmp(groesse,'L1'))
                str = ['$I_{L1}$ in $A$'];
            elseif (strcmp(groesse,'C1'))
                str = ['$I_{C1}$ in $A$'];
            elseif (strcmp(groesse,'R1'))
                str = ['$I_{R1}$ in $A$'];
            elseif (strcmp(groesse,'C1'))
                str = ['$I_{C1}$ in $A$'];
            elseif (strcmp(groesse,'V'))
                str = ['$V_P$ in $V$'];
            end
       
        else
            plot(time*10^6, eval(groesse)*10^3,'Linewidth',2);
           
            if (strcmp(groesse,'L1'))
                str = ['$I_{L1}$ in $mA$'];
            elseif (strcmp(groesse,'C1'))
                str = ['$I_{C1}$ in $mA$'];
            elseif (strcmp(groesse,'R1'))
                str = ['$I_{R1}$ in $mA$'];
            elseif (strcmp(groesse,'C1'))
                str = ['$I_{C1}$ in $mA$'];
            elseif (strcmp(groesse,'V'))
                str = ['$V_P$ in $V$'];
            end
       
        end        
       
            set(fighandle1,'defaulttextinterpreter','latex');
            set(gca, 'DefaultLineLineWidth',2.5);
            set(gca,'Fontsize',18);
            xlim([4.98 , 5.1]);
            xlabel('Zeit in $\mu s$', 'Fontsize',18);
            ylabel(str, 'Fontsize',18);

           
% ---------- Berechnung Funktionsparameter -------------------%
           
% Amplitude des ersten Überschwingens ermitteln        
            amplitude = max(eval(groesse));
            schwingung = amplitude/max(anregung);
        text(5.045,0.555,['\^I = ',num2str(schwingung),' A'],'Fontsize',18,'Interpreter','latex','BackgroundColor',[1 1 1])
            clear schwingung; clear amplitude;
% Zeitpunkt des Maximums ermitteln
            position_val = find(eval(groesse) == max(eval(groesse)));
        text(5.045,0.30,['$t_{r}$ = ',num2str(((time(position_val)*10^6)-5)*10^3),' $ns$'],'Interpreter','latex','Fontsize',18,'BackgroundColor',[1 1 1])
       
% Zeit für Abklingen berechnen

            breite = 0.1; %0.5;
            [peak_val,peak_loc] = findpeaks(eval(groesse));
           
            if (strcmp(groesse, 'L1'));
                if(strcmp(Quelle,'Stromquelle'))
                    gedaempft = find(peak_val < (max(anregung) + breite) * max(anregung));
                elseif(strcmp(Quelle,'Spannungsquelle'))
                    gedaempft = find(peak_val < ((max(anregung) + breite) * max(anregung))/1000);
                end
            else
                if(strcmp(Quelle,'Stromquelle'))
                    gedaempft = find(peak_val < (breite * max(peak_val)));
                elseif(strcmp(Quelle,'Spannungsquelle'))
                    gedaempft = find(peak_val < (breite * max(peak_val)));
                end
            end
                zeitkonst = time(peak_loc(gedaempft(1)))*10^6;
        text(5.045,0.1,['$t_{cd}$ = ',num2str((zeitkonst-time(position_val)*10^6)*10^3),' $ns$'],'Fontsize',18,'Interpreter','latex','BackgroundColor',[1 1 1])
        clear gedaempft; clear position_val; clear peak_loc; clear peak_val; clear breite;
       
% Vorbereiten der Signal für die FFT
       
        % L1 zuschneiden und vorbereiten Ein- und Ausschaltvorgangsgröße
        % hinzufügen der "tail-Größen" um aus dem Schwingvorgang eine
        % periodische Größe zu machen, Start = Endwert
           
            t_on = time(1:400);         % Einschaltzeit (Originaldaten)
            str1 = [groesse,'_on'];     % str1 für neue Variable
            str2 = eval(groesse);       % str2 als Referenz für Ausgangsssignal
            eval([str1 ' = str2(1:400,:);']);   % dynamisches Zuschneiden für Einschaltvorgang
           
            str3 = [str1,'_tail'];      % str3 für "Tail-Teil" der Funktion
            eval([str3 ' = str2(400) : -(str2(400)/15999) : 0;']);  % dynamische Tailfunktion Generierung
            %L1_on_tail = str2(400) : -(str2(400)/15999) : 0;  % Übergang zu Anfangswert (modelliert)
 
            t_interp = 0 : time(400)/8000 : time(400);  % äquidistanter Zeitstempel für interpolliertes Signal
                                                        % mit Start bei 0 und Ende beim Zeitwert des Originalsignals
                                                        % time(400)
               
            interpolation = interp1(t_on,eval(str1),t_interp,'linear');  % linear interpolliertes Zeitsignal "L1_on" auf neuen Zeitbereich "t_interp"
       if(strcmp(groesse,'L1'))
            %gesamt_signal = [interpolation L1_on_tail]; % Einschaltvorgang + "Tail-Funktion"
                 gesamt_signal = interpolation;        % für Plot des
                                                        % tatsächlichen Signals
       else
            gesamt_signal = interpolation;
       end
       
            fft_amplitude = fft(gesamt_signal); % Durchführen der FFT
            fft_amplitude = abs(fft_amplitude); % Absolutwert um negative Frequenzen zu eliminieren
            fft_amplitude(1) = [];              % Gleichanteil unterdrücken
           
        if(strcmp(groesse,'L1'))
            schrittweite = (time(400)*3)/(24000);   % Abstand zwischen zwei Abtastpunkten skaliert auf das neue Signal
                                                    % demnach die dreifache
                                                    % Zeit von time(400)
                %fft_time = 0 : (time(400)*3)/24000 : time(400)*3;  
        else
            schrittweite = (time(400)/8000);
        end
       
            n = length(fft_amplitude);
            amplitude_fft = 20*log10((fft_amplitude(1:floor(n/2)-1)));    % dB-Umrechnung
            %amplitude_fft = amplitude_fft - max(amplitude_fft);         % Normierung auf 0 dB max
            freq_fft = (1:floor((n-1)/2))/((n)*(schrittweite));         % Erstellen des Frequenzvektors abhängig von Schrittweite
           
            fighandle2 = figure;
            semilogx(freq_fft,amplitude_fft,'Linewidth',1.2);
            set(fighandle2,'defaulttextinterpreter','latex');
            set(gca,'Fontsize',18);
            xlabel('Frequenz in $Hz$','Interpreter','latex','Fontsize',18);
            ylabel('Amplitude in $dB$','Interpreter','latex','Fontsize',18);
            grid on
            clear L1_on_tail; clear n; clear i; clear schrittweite;
            clear str1; clear str2; clear str3;


Das Bild, welches ich angehängt habe, zeigt das FFT-Ergbenis, was LT-Spice ausspuckt. Die Resonanzfrequenz ist deutlich zu erkennen und von der prinzipiellen Form her stimmen die beiden Spektren auch überein. Allerdings stimmt die Amplitude nicht Crying or Very sad
Hat jemand eine Idee, woran das liegt?

Grüße


humpi

Unbenannt.PNG
 Beschreibung:

Download
 Dateiname:  Unbenannt.PNG
 Dateigröße:  82.98 KB
 Heruntergeladen:  286 mal
Private Nachricht senden Benutzer-Profile anzeigen E-Mail senden


DSP
Forum-Meister

Forum-Meister



Beiträge: 2.117
Anmeldedatum: 28.02.11
Wohnort: ---
Version: R2014b
     Beitrag Verfasst am: 29.03.2015, 17:02     Titel:
  Antworten mit Zitat      
Da die Matlab FFT ein zweiseitiges Spektrum erzeugt, muss entsprechend anders skaliert werden.

Siehe folgendes Skript: http://www.gomatlab.de/fft-umfassendes-beispiel-t777.html

Code:

N = 1024; % gewünschte FFT-Länge (N=2^x, sonst wird der DFT-Algorithmus verwendet!)

H = fft(y, N);
% Berechnung des Amplitudengangs aus dem komplexen Frequenzvektor H:
amplH = abs(H);

% Darstellung des interessierenden Frequenzbereichs des
% Amplitudengangs (0...fn) und
% daran angepasste Amplitudenskalierung (Normierung auf N/2):
amplitudengang = [amplH(1)/N amplH(2:N/2)/(N/2) amplH((N/2) + 1)/N]; % DC-Bin und Nyquistfrequenz auf N normieren!
 
Private Nachricht senden Benutzer-Profile anzeigen
 
dahumpi1989
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 11
Anmeldedatum: 28.12.13
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 29.03.2015, 17:40     Titel:
  Antworten mit Zitat      
Hey, danke für die schnelle Antwort.

Demnach muss ich das Amplitudenspektrum nach der Betragsbildung skallieren und dann in dB umrechnen und dann müsste das gleiche rauskommen, liege ich damit richtig?


Grüße


humpi
Private Nachricht senden Benutzer-Profile anzeigen E-Mail senden
 
DSP
Forum-Meister

Forum-Meister



Beiträge: 2.117
Anmeldedatum: 28.02.11
Wohnort: ---
Version: R2014b
     Beitrag Verfasst am: 29.03.2015, 18:05     Titel:
  Antworten mit Zitat      
Ob dann das gleiche dabei herauskommt, kann ich nicht sagen.

Schau dir einfach das Skript an...diese Darstellung eines Frequenzspektrum (linear/dB) ist auf jeden Fall korrekt für Matlab.
Private Nachricht senden Benutzer-Profile anzeigen
 
dahumpi1989
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 11
Anmeldedatum: 28.12.13
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 29.03.2015, 19:22     Titel:
  Antworten mit Zitat      
So ich habe das mal versucht zu implementieren und es sieht damit auch deutlich besser aus (ich hab das Spektrum mal als Bild angehängt), und es ergibt sich folgender Code

Code:
           N = 2^17;
           
            t_interp = 0 : time(400)/N : time(400);  % äquidistanter Zeitstempel für interpolliertes Signal
                                                        % mit Start bei 0 und Ende beim Zeitwert des Originalsignals
                                                        % time(400)
               
            interpolation = interp1(t_on,eval(str1),t_interp,'linear');  % linear interpolliertes Zeitsignal "L1_on" auf neuen Zeitbereich "t_interp"
       if(strcmp(groesse,'L1'))
            gesamt_signal = [interpolation L1_on_tail]; % Einschaltvorgang + "Tail-Funktion"
                 %gesamt_signal = interpolation;        % für Plot des
                                                        % tatsächlichen Signals
       else
            gesamt_signal = interpolation;
       end
           
            fft_amplitude = fft(gesamt_signal,N); % Durchführen der FFT
                        fft_amplitude = [fft_amplitude(1)/N fft_amplitude(2:N/2)/(N/2) fft_amplitude((N/2) + 1)/N];
            fft_amplitude = abs(fft_amplitude); % Absolutwert um negative Frequenzen zu eliminieren
            fft_amplitude(1) = [];              % Gleichanteil unterdrücken
           
        if(strcmp(groesse,'L1'))
            schrittweite = (time(400)*3)/(24000);   % Abstand zwischen zwei Abtastpunkten skaliert auf das neue Signal
                                                    % demnach die dreifache
                                                    % Zeit von time(400)
                %fft_time = 0 : (time(400)*3)/24000 : time(400)*3;  
        else
            schrittweite = (time(400)/8000);
        end
           
            %amplitudengang = [fft_amplitude(1)/N fft_amplitude(2:N/2)/(N/2) fft_amplitude((N/2) + 1)/N];
            %n = length(fft_amplitude);
            amplitude_fft = 20*log10((fft_amplitude(1:floor(N/2)-1)));    % dB-Umrechnung
            %amplitude_fft = amplitude_fft - max(amplitude_fft);         % Normierung auf 0 dB max
            freq_fft = (1:floor((N-1)/2))/((N)*(schrittweite));         % Erstellen des Frequenzvektors abhängig von Schrittweite
           
            fighandle2 = figure;
            semilogx(freq_fft,amplitude_fft,'Linewidth',1.2);
            set(fighandle2,'defaulttextinterpreter','latex');
            set(gca,'Fontsize',18);
            xlabel('Frequenz in $Hz$','Interpreter','latex','Fontsize',18);
            ylabel('Amplitude in $dB$','Interpreter','latex','Fontsize',18);
            grid on
 


Allerdings ergibt sich bei der zweiten Resonanz bei 300MHz immer noch eine Abweichung, eine Ahnung, wo das herkommt?

Und eine zweite blöde Frage müsste ich noch loswerden, die "gewünschte FFT-Länge" beeinflusst lediglich die Auflösung der FFT und entsprechend auch die Frequenzskalierung, richtig?
Da ich diese hier einmal auf 2^17 egwählt hatte??? Confused

Matlab_spektrum.png
 Beschreibung:

Download
 Dateiname:  Matlab_spektrum.png
 Dateigröße:  43 KB
 Heruntergeladen:  280 mal
Private Nachricht senden Benutzer-Profile anzeigen E-Mail senden
 
DSP
Forum-Meister

Forum-Meister



Beiträge: 2.117
Anmeldedatum: 28.02.11
Wohnort: ---
Version: R2014b
     Beitrag Verfasst am: 29.03.2015, 20:11     Titel:
  Antworten mit Zitat      
Es sollte so herum sein Wink

Code:

% 1.
fft_amplitude = abs(fft_amplitude); % Absolutwert
% 2. Nur positiven Frequenzbereich 0...Fn verwenden + Skalierung
fft_amplitude = [fft_amplitude(1)/N fft_amplitude(2:N/2)/(N/2) fft_amplitude((N/2) + 1)/N];
% dB-Umrechnung
amplitude_fft = 20*log10(fft_amplitude + eps); % eps = kleine Konstante zur Vermeidung von log10(0) = Inf    
 


Ist N>length(signal) werden die fehlenden Messwerte als Nullen am Ende des Signals gehängt um die Länge N zu erreichen. Das macht die Funktion FFT autotmatisch. Ja, N beinflusst die Auflösung des Spektrums.

Ich bevorzuge daher folgende Schreibweise für den Frequenzvektor:

Code:

Fs =... % Hz
Fn = Fs/2; % Nyquistfreq.
N = ...
df = Fs/N; % Schrittweite in Hz/Frequenzauflösung
% Frequenzvektor
fv = 0 : df : fn; % Hz
 


Es wäre evtl. auch hilfreich ein Fensterfunktion zu verwenden.
Private Nachricht senden Benutzer-Profile anzeigen
 
dahumpi1989
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 11
Anmeldedatum: 28.12.13
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 29.03.2015, 20:40     Titel:
  Antworten mit Zitat      
Ja richtig, damit hast du vollkommen recht, allerdings wenn ich so das Spektrum berchne ist die Amplitude im Resonanzpunkt nicht die, die bei der Simulation mit Spice rauskommt. Das wundert mich eben. Oder hat Spice dabei vielleicht irgendeine Fensterfunktion automation verwendet, das die Amplitude verändert hat?
Private Nachricht senden Benutzer-Profile anzeigen E-Mail senden
 
DSP
Forum-Meister

Forum-Meister



Beiträge: 2.117
Anmeldedatum: 28.02.11
Wohnort: ---
Version: R2014b
     Beitrag Verfasst am: 29.03.2015, 20:46     Titel:
  Antworten mit Zitat      
Keine Ahnung...ich kann nur für Matlab sprechen.

Wie gesagt...wie lang ist denn length(gesamt_signal)? Ist es kleiner als N, werden Nullen angefügt und das Spektrum wird schon etwas anders sein. Vor allem da bei einem realen Messignal von Leakage auszugehen ist, was ja die Amplitude beeinflusst. Deshalb sollte man auch immer einer Fensterfuntkion nutzen.
Private Nachricht senden Benutzer-Profile anzeigen
 
dahumpi1989
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 11
Anmeldedatum: 28.12.13
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 31.03.2015, 12:20     Titel:
  Antworten mit Zitat      
Hallöchen,

gibt es denn da bevorzugte Fensterfunktionen?
Mein Zeitsignal habe ich einmal angehängt. Ich hätte jetzt so ein "chebwin" genommen, da der Schwingungsvorgang quasi mit 1 skaliert wird und der rest gedämpft wird, ist die Überlegung richtig?

EDIT: die Anpassung der Länge hat super geholfen, nun sind es keine 70dB Unterschied mehr zwischen den beiden Spektren sondern lediglich 7-8dB. Die kriegen wir vielleicht noch mit dem Filter weg. Very Happy
Und die length(gesamt_signal) ist genauso groß wie das gewählte N, nämlich 2^14.

Signal.png
 Beschreibung:

Download
 Dateiname:  Signal.png
 Dateigröße:  9.53 KB
 Heruntergeladen:  266 mal
Private Nachricht senden Benutzer-Profile anzeigen E-Mail senden
 
DSP
Forum-Meister

Forum-Meister



Beiträge: 2.117
Anmeldedatum: 28.02.11
Wohnort: ---
Version: R2014b
     Beitrag Verfasst am: 31.03.2015, 17:43     Titel:
  Antworten mit Zitat      
Das kommt darauf an worauf man wert legt, Amplituden- oder Frequenzgenauigkeit.

I.d.R. wählt man ein Hanning oder Hamming, manchmal auch Blackman(-Harris). Für Amplitudentreue empfiehlt sich ein Flattop window.

Chebyshev ist zur Fensterung eher weniger geeignet.

Wichtig ist noch folgende Normierung (siehe bereits verlinktes Skript):

Code:

win = hann(N)';
%y_win = y.*win; % Fensterung ohne Amplitudenkorrektur
y_win = y.*win*N/sum(win); % Fensterung mit Amplitudenkorrektur
 
Private Nachricht senden Benutzer-Profile anzeigen
 
Neues Thema eröffnen Neue Antwort erstellen



Einstellungen und Berechtigungen
Beiträge der letzten Zeit anzeigen:

Du kannst Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.
Du kannst Dateien in diesem Forum posten
Du kannst Dateien in diesem Forum herunterladen
.





 Impressum  | Nutzungsbedingungen  | Datenschutz | FAQ | goMatlab RSS Button RSS

Hosted by:


Copyright © 2007 - 2025 goMatlab.de | Dies ist keine offizielle Website der Firma The Mathworks

MATLAB, Simulink, Stateflow, Handle Graphics, Real-Time Workshop, SimBiology, SimHydraulics, SimEvents, and xPC TargetBox are registered trademarks and The MathWorks, the L-shaped membrane logo, and Embedded MATLAB are trademarks of The MathWorks, Inc.