2009-07-18 5 views
1

Ich versuche die Frequenz einer Rechteckwelle zu messen, die über MATLAB durch ein USB 1024 HLS Daq Modul gelesen wird. Was ich getan habe, ist eine Schleife zu erstellen, die 100 Werte von der digitalen Eingabe liest und die mir den Vektor von 0 und 1 gibt. Es gibt auch einen Timer in dieser Schleife, der die Dauer misst, für die die Schleife läuft.Messen der Frequenz von Rechteckwellen in MATLAB mit USB 1024HLS

Nachdem ich den Vektor bekommen habe, zähle ich dann die Anzahl der 1en und benutze dann frequency = num_transitions/time, um mir die Frequenz zu geben. Dies scheint jedoch nicht gut zu funktionieren :(Ich bekomme verschiedene Frequenzen für verschiedene Anzahl von Wiederholungen der Schleife. Irgendwelche Vorschläge?

+0

Wie zählen Sie die Anzahl der 1s? Könnten Sie den Code bereitstellen? Ich würde empfehlen, den Vektor zu summieren. – Jacob

Antwort

0

Ich kann das Problem nicht herausfinden, aber wenn der boolesche Vektor v dann,

frequency = sum(v)/time_to_give_me_the_frequency 
+0

Ich glaube nicht, dass dies richtig funktionieren würde, außer Sie sind sicher, dass der Vektor * nur * eine volle Periode enthält. Zum Beispiel würde der obige Code die gleiche Frequenz für diese zwei Vektoren berechnen: v = [1 0 1 0 1 0]; v = [1 1 1 0 0 0]; – gnovice

0

Basierend auf Ihrer Beschreibung, wie ein Problem mit der Software klingt nicht, es sei denn Du die Windows-System-Timer verwenden, die notorisch ungenau ist (es auf etwa 15 Millisekunden nur genau ist) .

Es gibt hochauflösende Timer in Windows, aber ich d Ich weiß nicht, wie man sie in Matlab benutzt. Wenn Sie Zugriff auf das .NET-Framework haben, hat das Stopwatch class eine Genauigkeit von 1 Mikrosekunde (oder besser), wie die API QueryPerformanceCounter in Win32.

Sonst könnten Sie etwas Jitter haben. Es könnte etwas in Ihrer Signalkette sein, das falsche Trigger usw. verursacht.

UPDATE: Der folgende CodeProject-Artikel sollte das Timing-Problem lösen, falls es einen gibt. Sie sollten die Matlab-Dokumentation Ihrer Version von Matlab überprüfen, um zu sehen, ob sie einen nativen hochauflösenden Timer hat. Andernfalls können Sie diese verwenden:

C++/Mex-Wrapper fügt Mikrosekunde Auflösung Timer in Matlab unter WinXP http://www.codeproject.com/KB/cpp/Matlab_Microsecond_Timer.aspx

2

würde ich vorschlagen, den folgenden Code versuchen:

vec = ...(the 100-element vector of digital values)... 
dur = ...(the time required to collect the above vector)... 
edges = find(diff(vec)); % Finds the indices of transitions between 0 and 1 
period = 2*mean(diff(edges)); % Finds the mean period, in number of samples 
frequency = 100/(dur*period); 

Zuerst den Code findet die Indizes der Übergänge von 0 zu 1 oder 1 zu 0. Als nächstes werden die Differenzen zwischen diesen Indizes berechnet und gemittelt, was die durchschnittliche Dauer (in Anzahl von Abtastungen) für die Längen von Nullen und Einsen angibt. Multiplikation dieser Zahl mit zwei gibt dann die durchschnittliche Periode (in Anzahl von Abtastwerten) der Rechteckwelle an. Diese Zahl wird dann mit dur/100 multipliziert, um den Zeitraum zu erhalten, in dem die Einheiten dur gleich sind (d. H. Sekunden, Millisekunden usw.). Nimmt man den Kehrwert, erhält man die durchschnittliche Frequenz.

Eine zusätzliche Einschränkung: Um eine gute Schätzung der Häufigkeit zu erhalten, müssen Sie möglicherweise sicherstellen, dass die 100 Proben, die Sie sammeln, mindestens ein paar wiederholte Perioden enthalten.

Funktionen von Interesse verwendet oben: DIFF, FIND, MEAN

1

Zunächst einmal müssen Sie sicherstellen, dass Ihre 100 Proben mindestens eine volle Periode des Signals enthalten, sonst werden Sie falsche Ergebnisse. Sie benötigen einen guten Kompromiss zwischen der Sample-Rate (d. H. Je mehr Samples pro Periode Sie haben, desto besser ist die Messung) und der Anzahl der Samples.

Um wirklich präzise zu sein, sollten Sie entweder einen Zeitstempel mit jeder Messung haben (da Sie normalerweise nicht sicher sein können, dass Sie äquidistante Zeitabstände in der for-Schleife haben) oder vielleicht ist es möglich, Ihr USB-Modul in einigen zu wechseln "Running" -Modus, der nicht nur jeweils einen Sample, sondern eine komplette Wellenform mit fester Samplerate liefert.

Bei der Berechnung der Frequenz hat gnovice bereits auf den richtigen Weg hingewiesen. Wenn Sie einzelne Zeitstempel haben (in Sekunden), sind folgende Änderungen notwendig:

tst = ...(the timestamps associated with every sample)... 
period = 2*mean(diff(tst(edges))); 
frequency = 1/period; 
+0

+1: Guter Punkt über die einzelnen Zeitstempel. Es ist schwer zu sagen, auf welche Weise genau sie die Zeit messen (entweder für jede Probe oder für alle 100 Proben). – gnovice

0

mersenne31:

Vielen Dank allen für Ihre Antworten. Ich habe die Lösungen ausprobiert, die gnovice und groovingandi erwähnt haben, und ich bin mir sicher, dass sie funktionieren werden, sobald das Timing-Problem gelöst ist.

Der Code, den ich verwendet habe, ist wie folgt:

für i = 1: 100 tic; Wert = getvalue (portCH); Vektor (i) = Wert (1); tst (i) = toc; % Erhält eine individuelle Zeitprobenende

% der Gesamtzeit I setzen TOTAL_TIME = toc nach der for-Schleife

totaltime = sum (TST) zu erhalten; Kanten = finden (diff (vec)); % Findet die Indizes der Übergänge zwischen 0 und 1 Periode = 2 * Mittelwert (diff (Kanten)); % Findet die mittlere Periode, in Anzahl der Stichproben Häufigkeit = 100/(Gesamtzeit * Periode);

Das Problem ist, dass das Messen der Zeit für eine Probe nicht wirklich hilft, weil es für alle Proben fast gleich ist. Was benötigt wird, ist, wie groovingandi erwähnt, ein "laufender" Modus, der 100 Abtastungen für 3 Sekunden liest.

So etwas wie für (3 Sekunden) und dann machen wir die Datenerfassung. Aber ich kann so etwas nicht finden. Gibt es irgendeine Funktion in MATLAB, die dies tun könnte?

0

Dies wird Ihre Frage nicht beantworten, aber es ist, was ich nach dem Lesen Ihrer Frage dachte. Rechteckwellen haben unendliche Frequenz. Die FFT einer Rechteckwelle es sin (x)/x, die von -inf zu + inf geht.

Versuchen Sie auch, nur die steigenden Kanten in Matlab zu zählen. Sie können das Signal auf +1 und 0 quantisieren und dann die Zählung nur erhöhen, wenn Sie [0 1] Scheibe Ihres Vektors sehen.

ODER

Sie quantisieren kann, dezimieren, dann nur Summe. Dies funktioniert nur, wenn jeder Rechteckimpuls die gleiche Länge hat und Ihre Abtastfrequenz konstant ist. Ich denke, das wäre schwieriger zu machen.