LabVIEWForum.de - PXI misst nicht konstant (Zeitdrift)

LabVIEWForum.de

Normale Version: PXI misst nicht konstant (Zeitdrift)
Du siehst gerade eine vereinfachte Darstellung unserer Inhalte. Normale Ansicht mit richtiger Formatierung.
Seiten: 1 2
Hallo liebe, kluge Foristen,

ich sitze schon seit ein paar Wochen an einem Problem und bin mittlerweile wirklich am Verzweifeln. Hoffe daher wirklich, dass mir jemand helfen kann.

Ich will eine AE-Messungen durchführen und daher mit mindestens einem MHz abtasten. Hierfür benutze ich ein NI PXI-1031 als Chassis, in welcher eine NI PXI 6132 verbaut ist mit der ich messen will. Daher besitze ich eigentlich vier Kanäle, die jeder für sich genommen mit bis zu 2,5 MS abtasten können sollten (und das eben auch in Echtzeit, da ich ja mein Skript auf das PXI lade).

Das Grundproblem ist jetzt Folgendes:

Ich zeichne die Daten auf, allerdings ist die Zeit zwischen den einzelnen Messungen die das SubVI DAQmxLesen ausspuckt nicht konstant.

Ich habe ein paar Screenshots angefügt die mein Programm zeigt und genau mit diesen Einstellungen ein paar Minuten laufen lassen. Da die Periode der Schleife „Speichern“ mit 10 eingestellt wurde, als Quelle „1 kHz“ gewählt wurde und nach 3.000 Schleifendurchgänge eine neue TDMS-Datei erstellt wird, müsste doch eigentlich alle 30 Sekunden eine neue Datei erstellt werden (oder?).
Ich habe noch ein weiteren Screenshot angefügt in dem man die gespeicherten TDMS-Dateien mit dem Zeitstempel in ihrem jeweiligen Namen sieht. Wie man sehen kann sind die Intervalle zwischen den Dateien weder 30 Sekunden noch konstant….  Fragezeichen

[attachment=45846]

Kann mir das vielleicht jemand erklären???? Ich bin mit meinem Latein mittlerweile wirklich am Ende und habe auch schon mal die Mühe gemacht mit jedem Durchlauf der Schleife „Lesen“ auch einen eigenen Zeitstempel in die globale Variable und dann in die TDMS-Datei zu schreiben. Hier habe ich dann auch kein konstante Periode zwischen den Schleifendurchgänge gehabt, daher muss ja mein Fehler eindeutig darin liegen, dass meine zeitgesteuerten Schleifen nicht "gleichmäßig schnell" laufen (oder?).

In jeder TDMS- Datei befinden sich im Übrigen ungefähr gleich viele Sampels (in diesem Fall ca. 30.007.132 ) und dadurch dass eben das Intervall zwischen den TDMS-Dateien nicht konstant ist bekomme ich nicht eine ziemliche Streuung meiner Abtastrate..... Ahrg1Ahrg1Ahrg1

Wäre für jegliche Hilfe sehr sehr Dankbar!!!!

PS: Ich hoffe ich habe das Problem gut dagestellt. Ist mein erster Eintrag und beschäftige mich noch nicht allzu lange mit Labview, daher bitte ich falsch benutztes Fachjargon zu entschuldigen (man kann mich allerdings gerne drauf hinweisen Rolleyes)
Dir fehlt -soweit man das aus den Screenshots schließen kann- jegliche Pufferung und Deterministik beim Übertragen der Daten von der Erfassungsschleife zur Schreibschleife.

Ich würde dir folgende Änderungen vorschlagen:
1) Lies immer die gleich Anzahl an Samples bei DAQmx-Read aus - einfach einen Wert anschließen. Damit ist jedes Datenpaket, dass du weitergeben willst, gleich groß.
2) Beschäftige dich mit den Queue-Funktionen zur Übergabe an die Schreibschleife anstatt mit Shared Variables rumzumachen. IMHO hast du bei einer Queue am Ende einen wesentlich besseren Überblick.

Gruß, Jens
Jens hat ja das Wesentlioche schon gesagt, er hat nur nicht alles verraten. Wichtig ist noch, dass dann die beiden Timerschleifen durch normale Whileschleifen ersetzt werden. Die Synchronisation erfolgt durcht die Daten selbst und nicht durch irgendewelche Waits.
Untere Schleife: DAQmxRead wartet, bis die im Read-Eingang angegebene Zahl von Daten im Puffer ist. Nimm am besten 10 000 Werte, dann ist die Zeit zwischen zwei Schleifendurchläufen 10ms, alo genau wir vorher.
Obere Schleife: Queue auslesen wartet, bis wieder eine neuer Datensatz (mit 10 000 Werten) im Puffer ist. Die Schleife synchronisiert sich automatisch mit der unteren.
Das Einfügen von Waits oder eine Timerschlaufe würde die Synchronisation nur stören - das gilt für beide Scheifen.
So, also erstmal vielen viele Dank für eure schnelle Antwort!!!!

Hab mir gerade mal ein wenig in diese Queue_Funktionen eingelesen und die scheinen ja wirklich genau das zu sein was ich suchen.... (daher: Danke)
Werd mir jetzt mal ein Tutorial anschauen und dann es mal damit versuchen (werd euch wissen lassen ob es funktioniert hat!! :-))

Habe, dass aber schon so verstanden dass ich ein Queue mit einer definierten Größe erstelle (das ist dann wohl der "puffer" von dem ihr geredet habt..) , ihn in einer Schleife mit Werten füllen und die andere Schleife wartet dann immer bis der Queue "voll" ist, liest ihn aus und leert ihn dabei auch noch?!?
(Nehme mal an, dass ihr das mit "sie synchronisieren sich dann von selbst" meintet??)
Nein, du hast uns falsch verstanden.
Die Queue ist prinzipiell unbegrenzt.

Du sollst bei DAQmx-Read den Eingang "number of samples" nutzen und dort eine Wert anschließen.
Die Funktion wird dir dann immer genau die gewünschte Anzahl an Messwerten zurückgeben.
Diesen "Datensatz" gibst du dann per Queue an die Schreibschleife weiter.

Die Schreibschleife kann bei Bedarf komplett asynchron laufen, da die Queue als Zwischenspeicher verwendest.

Gruß, Jens
So,
ich habe das Ganze jetzt mal so wie von euch beschrieben implementiert und wie gesagt: Guru1Guru1Guru1Guru1
Funktioniert schon viel viel besser!!!! :-)

Allerdings habe ich noch zwei Fragen:

1.)Wie sage ich dem Queue, dass es sich um einen Signalverlauf handelt?
Also wie schaut die Konstant aus die ich an das VI "Queue anfordern"/"Obtain Queue anschließe?
2.) Wenn ich das Ganze jetzt mit einem MHz laufen lasse kommt nach einiger Zeit der Fehler 50352. Woran könnte das in diesem Zusammenhang liegen?


Viele Grüße,
Gerald
(13.08.2013 13:57 )Gerald85 schrieb: [ -> ]Habe, dass aber schon so verstanden dass ich ein Queue mit einer definierten Größe erstelle (das ist dann wohl der "puffer" von dem ihr geredet habt..) , ihn in einer Schleife mit Werten füllen und die andere Schleife wartet dann immer bis der Queue "voll" ist, liest ihn aus und leert ihn dabei auch noch?!?
Nein, auf der anderen Seite (der Empfangsseite) wird nicht gewartet, bis der Puffer voll ist, sondern es wird (- max. bis zum Timeout -) gewartet, bis er nicht mehr leer ist, d.h. solange, bis etwas aus dem Puffer abzuholen ist. Nicht leer ist der Puffer, wenn sich mindestens 1 Element im Puffer befindet. Voll wird der Puffer (wenn die Größe nicht konfiguriert wurde) überhaupt nicht - es sei denn durch die endliche Memorykapazität des PC.
(13.08.2013 18:16 )Gerald85 schrieb: [ -> ]1.)Wie sage ich dem Queue, dass es sich um einen Signalverlauf handelt?
Also wie schaut die Konstant aus die ich an das VI "Queue anfordern"/"Obtain Queue anschließe?
Im einfachsten Fall per Rechtsklick am Ausgang des DAQmx-Read -> Create -> Constant.
(13.08.2013 18:16 )Gerald85 schrieb: [ -> ]2.) Wenn ich das Ganze jetzt mit einem MHz laufen lasse kommt nach einiger Zeit der Fehler 50352. Woran könnte das in diesem Zusammenhang liegen?
Meinst du vielleicht -50352? Das würde bedeuten:
"NI Platform Services: The requested memory could not be allocated."

Lad doch mal deinen neuen Stand hoch, bzw. zeige mind. Screenshots...

Gruß, Jens
Hallo nochmal,
sorry war gestern außer Haus und heute war/ist her auch die Hölle los.
Vielen Dank für eure Antworten auf jeden Fall!!!

(13.08.2013 18:33 )jg schrieb: [ -> ]
(13.08.2013 18:16 )Gerald85 schrieb: [ -> ]1.)Wie sage ich dem Queue, dass es sich um einen Signalverlauf handelt?
Also wie schaut die Konstant aus die ich an das VI "Queue anfordern"/"Obtain Queue anschließe?
Im einfachsten Fall per Rechtsklick am Ausgang des DAQmx-Read -> Create -> Constant.
Im Bezug auf den Signalverlauf hab ich das hier:
[attachment=45878]
denke dass der Fehler bei dem Block "Queue anfordern" liegt... Leider weiß ich überhaupt nicht wie ein Signalverlauf Array-mäßig aufgebaut ist, daher kann ich auch keine Konstante bauen :-(

(13.08.2013 18:33 )jg schrieb: [ -> ]
(13.08.2013 18:16 )Gerald85 schrieb: [ -> ]2.) Wenn ich das Ganze jetzt mit einem MHz laufen lasse kommt nach einiger Zeit der Fehler 50352. Woran könnte das in diesem Zusammenhang liegen?
Meinst du vielleicht -50352? Das würde bedeuten:
"NI Platform Services: The requested memory could not be allocated."

Lad doch mal deinen neuen Stand hoch, bzw. zeige mind. Screenshots...

Gruß, Jens

Hier ist die Version mit der es funktioniert, aber nach einiger Zeit den Fehler 50352 ausgespuckt hat. Einziger Unterschied zu oben ist, dass es sich um ein 2DBL beim SubVi "DAQmx-Lesen" handelt.

[attachment=45879][attachment=45880]


Viele Grüße,
Gerald
Hallo Gerald,

zu den letzten beiden Bildern:
1/Links:
- Du erstellst deine Queue als Variant, das wird nicht passen. Erstelle die benötigte Konstante (Array of Waveform) aus dem Draht, der vom DAQmxRead kommt!
- Es ist nicht sinnvoll, die Verbraucher-Loop (mit dem Dequeue-Aufruf) zu beenden, bevor der Consumer stoppt. Bei deinen Datenraten kannst das schnell zu einem "Out of Memory"-Fehler führen. Nutze den Fehlerausgang des Dequeue als Stopp-Bedingung...
- Die Queue mit einer Länge von 900k Elementen zu definieren hilft nicht viel, wenn die einzelnen Elemente 1D-Arrays of Waveforms (mit je 3 Waveforms zu 100k Samples!) sind...

2/rechts:
- Die Art und Weise, wie du den Task erstellst, ist hochgradig "flawed": Man kann mehrere Kanäle auf einmal zum Task hinzufügen, die Hilfe sagt, wie das geht! ("Dev2/ai0:2"). Außerdem ist das Schieberegister falsch/gar nicht verdrahtet, was den so definierten Task wenig sinnvoll erscheinen lässt...
- zur Queue gelten wahrscheinlich die gleichen Anmerkungen wie oben...

Allgemein:
Wenn du 3 Kanäle mit 1MHz Samplerate auf die Festplatte schreiben willst, solltest du überlegen, ob die DAQmx-TDMS-Streaming-Funktionen nicht doch sinnvoll sind!
Seiten: 1 2
Referenz-URLs