LabVIEWForum.de - Problem mit Timing bei Datenerfassung

LabVIEWForum.de

Normale Version: Problem mit Timing bei Datenerfassung
Du siehst gerade eine vereinfachte Darstellung unserer Inhalte. Normale Ansicht mit richtiger Formatierung.
Hallo zusammen,

ich benötige etwas Hilfe bei der Zeitsteuerung von zwei Prozessen.

Und zwar habe ich eine Datenerfassung (NI-6009), die mir die Werte von einer Fotodiode ausliest und gleichzeitig
eine Linearachse, die mir eine Probe vor dieser Fotodiode in Ausbreitungsrichtung eines Laserstrahls hin und herfährt.

Das Problem ist, dass die Messwerte der Fotodiode der jeweiligen Achsenposition zugeordnet werden müssen. Leider bekomme ich
von der Achse aber nur ein Positionsfeedback, wenn sie ein "Go"-Kommando abgeschlossen hat.

Bisher bin ich also in möglichst kleinen Schritten gefahren, hab die Diode ausgelesen und dementsprechend meine Werte direkt mit dem
Feedback der Achse verknüpfen können. Leider ist das Ganze relativ langsam, weil die Kommunikation mit der Achse über RS232 läuft und nur ca alle 20 ms
ein Feedback kommen kann. Dadurch kann ich die volle Achsengeschwindigkeit nicht nutzen und eine Messung dauert ziemlich lang.

Meine Idee ist nun, die Kommandos zur Messwertaufnahme und zum Starten der Bewegung gleichzeitig zu geben, wobei die Achse die
volle Wegstrecke mit Maximalgeschwindigkeit zurücklegen soll (zwischendrin kein Feedback) und währenddessen die Fotodiode ausgelesen
wird. Der Auslesevorgang soll gestoppt werden, sobald die Achse am Ende ist und das Feedback (automatisch) gibt.

Wichtig dabei ist natürlich die Synchronisation zwischen:

a) Starten der Achse und Beginn der Messwertaufnahme und
b) Ausgabe des Feedbacks ("ich bin am Ende angekommen") und Beendigung der Messwertaufnahme.

Anschließend ordne ich einfach die Messwerte der entsprechenden Position - unter Annahme einer konstanten Geschwindigkeit zu.

ABER: Ich krieg es bisher einfach nicht hin.

Ich hab versucht zwei zeitgesteuerte Strukturen - genauer eine Schleife und eine Sequenz zu synchronisieren. In der Schleife
läuft dann die Messwerterfassung und in der Sequenz erfolgt das Start-Kommando für die Achse. Sobald die Achse fertig ist mit bewegen, kommt das Feedback und wird als "Position" in eine lokale Variable geschrieben. Die Schleife mit der Messwerterfassung soll stoppen, sobald der Wert der
lokalen Vaiablen dem Stop-Wert entspricht.

Soweit die Idee. Im angehängten Minimalbeispiel funktioniert das auch ganz gut. Vielleicht kann mal jemand drüberschauen und
mir ein kurzes Feedback dazu geben. Ist die Herangehensweise ok?

Ein Problem tritt jetzt auf, wenn ich die Achse mermals hin- und herbewege. Schließlich sollen auch auf dem Rückweg Messwerte erfasst werden.
Ich mach das ganze einfach mit einer kleinen For-Schleife und einer If-Abfrage. Hier bekomme ich allerdings "error 200429" von
NI DAQmx. Ich verstehe nicht warum. Der Fehler tritt manchmal auf, manchmal aber auch nicht.

DANKE für eure Hilfe!
Wieso stellst du deine Datenerfassung auf 16 kS/s, und liest dann aber nur mit 1 kHz Daten ein?

Wenn du das ganze in einer While-Loop laufen lässt, müsste es auch reichen.

Dass du mit diesem Vorgehen immer noch keine saubere Synchronisation hinbekommst, ist dir hoffentlich klar. Das liegt aber vor allem daran, dass du deine Linearachse über die serielle Schnittstelle ansteuerst. Hat die vielleicht einen Digital-Trigger-Eingang, so dass erst auf dieses Trigger-Signal hin der nächste Befehl ausgeführt wird? Wie wertet deine Linearachse ihre Position aus? Ist da irgendein Linear- oder Drehencoder eingebaut? Dann könntest du dir eine Phase des Positionssignals als Triggersignal für dein Analog-In holen.

Gruß, Jens
Guten morgen,

danke für die schnelle Hilfe!

Ich war mir zunächst nicht sicher, ob eine normale While-Schleife zur Synchronisation ausreicht. Ich hatte es zwar mal probiert. Allerdings hat das Ganze damit nicht funktioniert, was aber wohl auf einen Programmierfehler zurückzuführen war. Jetzt hab ich die zeitgesteuerten Strukturen durch normale While-Schleifen ersetzt und es läuft ganz gut.

Auch wenn ich das Ganze mehrfach mit einer for-Schleife ausführen lasse, bekomm ich keinen Fehler mehr.

Du sagtest, dass ich nur mit 1kHz Daten einlese, obwohl ich auf 16k eingestellt hab. Liegt das an den Einstellungen der zeitgesteuerten Struktur? Ich kenne mich damit nicht so aus (bin eh noch kein LabVIEW Veteran) und hab dort quasi die Standardeinstellungen genommen. Mehr als 1kHz kann ich aber nicht einstellen (MHz und andere Optionen sind ausgegraut).

Ich bekomme jetzt pro Durchlauf ca. 12000 Datenpunkte, was bei einer Dauer für die gewählte Strecke von unter einer Sekunde ja ganz gut mit den 16kS/s übereinstimmt. Von daher bin ich schonmal ganz zufrieden und werde mal fleisig weiterarbeiten.

Bei der Achse handelt es sich um eine TSLR von Zaber mit 75 mm Weg. Die wird über einen Schrittmotor angetrieben und bietet zumindest soviel ich weiß als Feedback nur die Anzahl der zurückgelegten Mikroschritte. Einen Trigger Eingang hat sie leider auch nicht (Ist halt unteres Preissegment). Du hast Recht, dass die perfekte Synchro gar nicht klappen kann. Wenn ich das richtig im Kopf hab, braucht die Hardware ca. 16 ms für einen Befehl/ für ein Feedback. Ich hoffe aber, dass das bei insgesamt einer Sekunde Messzeit nicht zu stark ins Gewicht fällt. Außerdem kann ich ja die Ergebnisse der schnellen Messungen mit den Langsamen vergleichen und eventuell einen Zeitpuffer oder so etwas einbauen.

Ich hab nochmal den aktuellen Stand angehängt. Wäre nett, wenn du mal kurz rüberschaust und eventuell Verbesserungsvorschläge gibst.

Danke nochmal und viele Grüße,

Sönke
Lv86_img
1. Bitte: Zieh mal gerade Linien, dein Spaghetti Code ist grausam!
Schau mal, wie viel übersichtlich dein Code werden kann:
[attachment=21118]

2. Nutz doch die Pufferung, die dir der DAQmx-Treiber bietet, indem du immer mehrere Werte auf einmal einliest:
[attachment=21116]
Wenn du am Eingang "number of samples per channel" per channel eine Konstante anschließt, kannst du sogar einen "Durchlauf-Takt" für deine While-Schleife erzeugen, das senkt die CPU-Last.

3. Das mit der Abbruch-Bedingung deiner Datenerfassung könnte man vielleicht auch etwas eleganter lösen. Verstehe ich richtig, dein COMMAND-20-Befehls-VI an deine T-LSR Achse (bitte, wenn schon, dann korrekte Typ-AngabenWink) liefert erst dann eine Rückmeldung, wenn die Zielposition des Verfahrbefehls erreicht ist? Dann könnte dies das Abbruch-Event auslösen, z.B. im einfachsten Fall durch Setzen einer boolschen Variablen, die du dann wieder als lokale Variable in der While-Schleife ausliest.

Noch vieles Mehr ist sicher möglich, aber nicht mehr heute abend.

Gruß, Jens
Referenz-URLs