Verfasst am: 18.12.2013, 14:11
Titel: Fourierzerlegung von Beschleunigungswerten
Hallo zusammen,
ich bin neu in Matlab und kenne mich außer ein paar Dingen aus den Einführungsvideos noch nicht wirklich aus. Aber nun zur Frage:
Ich habe Beschleunigungswerte in Abhängigkeit des Kurbelwinkels (Verbrennungsmotor), kann auch als zeitabhängig betrachtet werden, und müsste diese in die verschiedenen Frequenzspektren zerlegen. Wichtig sind hier eigentlich nur die ersten vier Ordnungen. Die Daten liegen in einer Excel Tabelle vor. Kann mir da irgendjemand weiter helfen.
Generelle Vorgehensweise:
(1) Bereich bestimmen, wo Daten im Excel liegen
(2) Daten aus Excel mit xlsread einlesen
(3) Zur Benutzung der FFT die Anzahl der Daten auf Zweierpotenz abrunden (oder Zeropadding benutzen)
(4) Daten zeitabhängig machen
(5) Spektralanalyse durchführen (siehe Beispiel oben)
(6) Spektrum darstellen
Zugegeben. Für den Einstieg keine leichte Aufgabe. Du kannst dich ja dann melden, wenn du ein Grundgerüst fertig hast.
Grüße
Headbucket
Roachnbua
Gast
Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
Verfasst am: 18.12.2013, 17:09
Titel:
Die Messwerte sind Beschleunigungen eines sich bewegenden Bauteils im Motor. Die Beschleunigung setzt sich so aus der 1. Ordnung ( Nenndrehzahl des Motors) 2. Ordnung ( 2*Nenndrehzahl), 3. Ordnung usw. zusammen. Nun muss ich bestimmen, wie groß die Amplitude für jede Ordnung ist!
Ich habe alle 5° Kurbelwinkel die Beschleunigungswerte im Excel und aus diesen muss ich jetzt oben gesagtes analysieren.
Gruß,
Roachnbua
Roachnbua
Gast
Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
Verfasst am: 18.12.2013, 17:14
Titel:
Meine Funktion sieht folgendermaßen aus:
x= a*sin(w*t)+b*sin(2*w*t)+c*sin(3*w*t)+...
w steht für die Kreisfrequenz Omega.
Ich muss also die Excel-Werte mit dieser Funktion vergleichen und die Amplituden bestimmen.
Roachnbua
Gast
Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
Verfasst am: 19.12.2013, 10:23
Titel:
Habe noch eine Frage zum erstellen einer Funktion aus Ecxel-Daten. Die Daten der Beschleunigung sind die y-Werte, die für die Zeit sind die x-Werte. Wie kann ich eine Funktion aus diesen beiden Daten bilden?
Okay ich glaube ich habe verstanden, was du machen möchtest.
Roachnbua hat Folgendes geschrieben:
Habe noch eine Frage zum erstellen einer Funktion aus Ecxel-Daten. Die Daten der Beschleunigung sind die y-Werte, die für die Zeit sind die x-Werte. Wie kann ich eine Funktion aus diesen beiden Daten bilden?
Grüße,
Roachnbua
Ich denke mal "Funktion" ist hier die falsche Bezeichnung.
Ich würde als erstes mal Beschleunigung und Zeit getrennt einlesen:
Code:
dateipfad = 'ExcelDatei.xlsx';
sheet = 1;
xlRange1 = 'A1:A100'; %hier liegen die Beschleunigungswerte in der Excel-Datei
xlRange2 = 'B1:B100'; %und hier die Zeitwerte
a = xlsread(dateipfad, sheet, xlRange1); %Beschleunigungswerte
t = xlsread(dateipfad, sheet, xlRange2); %Zeitwerte
Das wäre der erste Schritt. Dann siehst du erstmal den Zeitverlauf der Beschleunigungswerte. Danach musst du eine Fouriertransformation durchführen. Dazu habe ich ja oben schon ein gutes Beispiel gepostet.
Wenn du die Fouriertransformation durchgeführt hast lässt du dir am besten mal das Spektrum darstellen. Dort kannst du dann ganz bequem alle Frequenzen (Kreisfrequenzen) und ihre Amplituden ablesen und in deine Gleichung einsetzen.
so würdest du z.B. eine einfache FFT mit den obrigen Werten durchführen:
Code:
fa = ??? %Abtastfrequenz = 1 / Abtastperiode = 1 / (t(2)-t(1))(Beispiel)
N = length(a);
x = fft(a, N)/N;
f = fa/2*linspace(0,1,N/2+1); %Frequenzvektor
figure(2);
loglog(f,2*abs(x(1:N/2+1))); %Amplitudenspektrum
Ich habe das Problem jetzt so gelöst und es funktioniert wunderbar. Jetzt möchte ich mir aber noch die Zahlenwerte der Amplituden für jede Ordnung ausgeben lassen, denn bis jetzt sehe ich nur die Werte in den Diagrammen. Weiß da jemand weiter?
Ordnungen = 0:0.5:(size(X,1))/2-0.5;
plot(Ordnungen, X, 'rx', 'LineWidth', 2.0) title('Anregungsordnungen') xlabel('Ordnung') ylabel('Amplitude') axis([0100(max(X)+50)]) %in die Grafik reinzoomen, so dass nur die ersten 10 Ordnungen dargestellt werden
Ordnungen = 0:0.5:(size(Y,1))/2-0.5;
plot(Ordnungen, Y, 'rx', 'LineWidth', 2.0) title('Anregungsordnungen') xlabel('Ordnung') ylabel('Amplitude') axis([0100(max(Y)+50)]) %in die Grafik reinzoomen, so dass nur die ersten 10 Ordnungen dargestellt werden
Um auf die Amplituden der jeweiligen Ordnungen zu kommen wirst du wohl mit Schwellwerten arbeiten müssen.
So kannst du z.B. zunächst die maximale Amplitude im Spektrum suchen und dann prozentual von dieser alle anderen Amplituden suchen. Je nachdem, wie "sauber" das Spektrum ist bekommst du dann 1-x Amplituden pro Ordnung. Da musst du dann gegebenenfalls nochmal gesondert aussortieren indem du nur die höchste Spektrallinie bei jeder Ordnung verwendest.
Das ganze wird eventuell übersichtlicher, wenn du die Amplituden zunächst mit der maximalen Amplitude normierst.
Das ist zwar ein bisschen "Trial and Error"-Mäßig aber was besseres fällt mir im Moment nicht ein. Ich bin auch gerne für Anregungen offen .
Roachnbua
Gast
Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
Verfasst am: 21.12.2013, 17:30
Titel:
Kannst du nochmal genauer beschreiben wie du das mit diesen Schwellwerten verstehst. Gibt es da irgend eine Funktion dazu?
% Maskierung der Werte mit Schwellwert -> nur noch Werte über dem Schwellwert vorhanden
maske = (X > Schwellwert);
X_mask = maske .* X;
% Zusammenfassen von Frequenz (Ordnungen) und Amplitude in einem Vektor
X_result(:,1) = X_mask; %Amplituden in Spalte 1 speichern
X_result(:,2) = Ordnungen; %Ordnugnen in Spalte 2 speichern eventuell ist hier noch eine Transponierung der Matrix nötig. Also X_result(:,2) = Ordnungen';
% Finden der Maxima [X_peaks, i] = findpeaks(X_result); %Vektor enthält nur noch die Spektrallinien, welche über dem Schwellwert liegen mit den dazugehörigen Frequenzen
Im Idealfall wars das schon. Du hast jetzt für jede Ordnung die Amplitude. Arbeitest du aber mit realen Daten kann es sein, dass du mehrere Amplituden für die selbe Ordnung findest. Dann müsstest du noch die größe Amplitude bei jeder Ordnung raussuchen (mit ein paar for- und if-Schleifen).
Ich hoffe du weißt jetzt ugf. wie ich es meine. Keine Garantie auf den Code oben. Konnte ihn ja nicht testen. Aber vom prinzip her muss es so funktionieren.
Grüße
Roachnbua
Gast
Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
Verfasst am: 30.12.2013, 20:21
Titel:
Ok wie du es meinst verstehe ich. Matlab hat aber mit der Funktion "findpeaks" ein Problem. Ich denke das kommt daher da du eigentlich vorher kein Vektor sondern eine Matrix definiert hast. Es wurden nämlich auf der gleichen Variable zwei Spalten definiert. Daher glaube ich hat er dann mit 'X_results' ein Problem. Habe bisschen rum probiert mit Vektoren und Matrizen, bin aber nicht weiter gekommen. Kann man sich dann eigentlich die resultierende Tabelle irgendwie plotten?
Dieser Code löscht alle Zeilen, wo in der ersten Spalte eine Null steht. Danach sollte in "X_result" in der ersten Spalte alle Maxima stehen und in der zweiten Spalte die dazugehörigen Ordnungen.
Ansonsten kann ich nur immer empfehlen sich mal ein paar Breakpoints mit dem Debugger zu setzen und genau zu gucken, was in den Vektoren/Matrizen steht. Dadurch wird das ganze viel anschaulicher und man findet oft selbst die Fehler.
Grüße
Roachnbua
Gast
Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
Verfasst am: 13.01.2014, 16:04
Titel:
Super mit der letzten Zeile hat es schon mal funktioniert, aber eben nur einmal. Ich habe dann nichts mehr geändert und jetzt hat er mit X und Y Probleme. Matlab schreibt raus das Integer dort benötigt werden. Für X und Y steht aber ein Vektor mit <73x1 double> da. Müsste das nicht eigentlich passen?
Code:
% Das ist mein Programm
Den obersten Teil habte ich weggelassen, da nicht interessant!
%Fourierzerlegung mit der FFT-Funktion
fa = 144; %Abtastfrequenz = 1 / Abtastperiode = 1 / (t(2)-t(1))(Beispiel)
N1 = length(ax);
Fft_Analyse1 = fft(ax, N1)/N1;
X = 2*abs(Fft_Analyse1(1:N1/2+1));
N2 = length(ay);
Fft_Analyse2 = fft(ay, N2)/N2;
Y = 2*abs(Fft_Analyse2(1:N2/2+1));
fig = figure(fig + 1);
Ordnungen1 = 0:0.5:(size(X,1))/2-0.5;
subplot(2,1,1);
plot(Ordnungen1, X, 'rx', 'LineWidth', 2.0) title('Anregungsordnungen') xlabel('Ordnung') ylabel('Amplitude') axis([0100(max(X)+50)]) %in die Grafik reinzoomen, so dass nur die ersten 10 Ordnungen dargestellt werden
Ordnungen2 = 0:0.5:(size(Y,1))/2-0.5;
subplot(2,1,2);
plot(Ordnungen2, Y, 'rx', 'LineWidth', 2.0)
%title('Anregungsordnungen') xlabel('Ordnung') ylabel('Amplitude') axis([0100(max(Y)+50)]) %in die Grafik reinzoomen, so dass nur die ersten 10 Ordnungen dargestellt werden
%Amplitudenwerte von ax finden
Schwellwert = 0.10; %Schwellwert von 10%
MaxValueX = max(X); %maximale Amplitude im Spektrum suchen
SchwellwertX = Schwellwert * MaxValueX; %Schwellwert berechnen
% Maskierung der Werte mit Schwellwert -> nur noch Werte über dem Schwellwert vorhanden
maskeX = (X > SchwellwertX);
X_mask = maske.* X;
% Zusammenfassen von Frequenz (Ordnungen) und Amplitude in einem Vektor
X_result(:,1) = X_mask; %Amplituden in Spalte 1 speichern
X_result(:,2) = Ordnungen1; %Ordnugnen in Spalte 2 speichern eventuell ist hier noch eine Transponierung der Matrix nötig. Also X_result(:,2) = Ordnungen';
X_result(X_result(:,1)==0,:)=[];
%Amplitudenwerte von ax finden
Schwellwert = 0.10; %Schwellwert von 10%
MaxValueY = max(Y); %maximale Amplitude im Spektrum suchen
SchwellwertY = Schwellwert * MaxValueY; %Schwellwert berechnen
% Maskierung der Werte mit Schwellwert -> nur noch Werte über dem Schwellwert vorhanden
maskeY = (Y > SchwellwertY);
Y_mask = maske.* Y;
% Zusammenfassen von Frequenz (Ordnungen) und Amplitude in einem Vektor
Y_result(:,1) = Y_mask; %Amplituden in Spalte 1 speichern
Y_result(:,2) = Ordnungen2; %Ordnugnen in Spalte 2 speichern eventuell ist hier noch eine Transponierung der Matrix nötig. Also X_result(:,2) = Ordnungen';
Y_result(Y_result(:,1)==0,:)=[];
Wenn diese Meldung ( wie oben beschrieben) kommt, stimmen dann die Ergebnisse in der Workspace. Zur Sicherheit möchte ich mir die Ergebnisse in einem Diagramm darstellen lassen und eine Formel einbauen mit den Amplituden und Ordnungen. Ich habe das erst einmal in Excel gemacht und die Formel erst mit einem Sinus erstellt. Bei ax hat es gepasst bei ay aber nicht. Jetzt ist die Frage ob ich mir die Phasenverschiebung für jede Ordnung ausgeben lassen kann, denn dann kann ich die Formel immer mit dem Sinus bilden. Hat da jemand eine Idee?
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
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.