Hallo,
ich wollte mich erkundigen, ob ihr mir bei einem "Problem" helfen könnt.
Für einen Dauerbelastungsversuch habe ich ein Steuerprogramm mit Datenerfassung in Labview erstellt.
Die wiederkehrende Belastung wird über einen DC-Motor hergestellt, der über einen Arduino via LINX angesteuert wird.
Für die Aufnahme der Belastung ist eine Wägezelle eingebaut, die mittels DAQ Karte ausgelesen wird.
Das gesamte Programm habe ich als Producer-Consumer Struktur aufgebaut.
Leider läuft es nicht sehr performant.
Nun wollte ich mich erkundigen, ob ein QMH besser geeignet wäre für die Ansteuerung?
In den LabView Beispielen wird der QMH für die kontinuierliche DAQ Datenerfassung verwendet, allerdings ist da keine Ansteuerung (DC-Motor) enthalten.
Hier habe ich leider zu wenig Erfahrung und bin mir sehr unschlüssig, wie ich das Programm aufbauen soll.
Gerne kann ich auch das VI anhängen.
Die Labview Version ist 19.0.1, das Betriebssystem Windows 10.
Vielen Dank schon im Voraus und sorry für den langen Post!
Hallo Tom,
herzlich willkommen im Forum!
Zitat:Das gesamte Programm habe ich als Producer-Consumer Struktur aufgebaut.
Nun wollte ich mich erkundigen, ob ein QMH besser geeignet wäre für die Ansteuerung?
Wo siehst du den Unterschied zwischen P-C-Struktur und QMH, wenn es um die Ansteuerung eines Motors geht?
Bei P-C sendet ein Producer Befehle an einen Comsumer, der den Motor ansteuert. Bei der QMH sendet auch ein Producer Befehle an einen Handler, der den Motor ansteuert. Und beide verwenden eine Queue…
Zitat:Leider läuft es nicht sehr performant.
Das könnte an deinem Programm liegen. Oder an den Geräten.
Welche Antworten erwartest du bei dieser Informationslage?
Hallo Gerd,
sorry erstmal für die späte Antwort meinerseits und schonmal danke für deine Hilfe!
Zitat:Wo siehst du den Unterschied zwischen P-C-Struktur und QMH, wenn es um die Ansteuerung eines Motors geht?
Bei P-C sendet ein Producer Befehle an einen Comsumer, der den Motor ansteuert. Bei der QMH sendet auch ein Producer Befehle an einen Handler, der den Motor ansteuert. Und beide verwenden eine Queue…
Das stimmt. Danke für den Hinweis; das hatte ich nicht bedacht. In der Zwischenzeit habe ich auch alle Anteile des Programms die nicht zur Motorsteuerung und DAQmx gehören vom Producer in den Consumer Loop verschoben.
Zitat:Das könnte an deinem Programm liegen. Oder an den Geräten.
Welche Antworten erwartest du bei dieser Informationslage?
Auch hier sorry. Da ist die Informationslage tatsächlich etwas dünn.
Als DAQ Gerät ist eine PCIe-6320 Karte eingebaut. Der PC ist mit einem Intel Xeon E3-1230v2, 24 GB RAM und einer Samsung 860Evo SSD ausgestattet.
Mit schlechter Performance meinte ich zum einen, dass die UI eher träge reagiert und zum anderen, dass die Graphen die Daten nur "abgehackt" darstellen oder mit einer halben Sekunde Verzögerung einen Messimpuls darstellen.
Durch deinen ersten Tipp hat sich das schon merklich verbessert.
Wenn ich nun allerdings einen dritten Logging Loop hinzufügen will wird die UI wieder träge und die Graphen stellen die Daten nur noch teilweise dar.
Hier stoße ich dann leider an meine Grenzen.
Vielleicht könnt ihr mir ja den ein oder anderen Tipp geben?
Das Projekt habe ich angehängt.
Viele Grüße
Thomas
Hallo tom,
Zitat:Wenn ich nun allerdings einen dritten Logging Loop hinzufügen will wird die UI wieder träge und die Graphen stellen die Daten nur noch teilweise dar.
Da hast du auch einen groben Fehler eingebaut! Du versuchst an zwei Stellen aus ein und der selben Queue zu lesen: wer bekommt da wohl welche Daten ab?
Eine Queue sollte (üblicherweise) immer als "N Producer, 1 Consumer" verwendet werden.
Nur, wenn es egal ist, wer welche Daten in welcher Reihenfolge abbekommt, kann man sie auch für "N Producer, N Consumer" verwenden!
Wenn du also
alle Daten loggen und
alle Daten auch anzeigen/verarbeiten willst, dann benötigst du zwei Queues! Die Logging-Routine könnte z.B. alle Daten speichern und in eine zweite Queue weiterschieben, die dann von der Rechenloop geleert wird…
Das hätte auch den Vorteil, dass die UI-Loop nicht noch einmal die gleiche Berechnung durchführen muss, die schon in der anderen Loop erledigt wurde!
In eben diesem VI:
[
attachment=61131]
Wenn Autoindizierung, dann ist die Anzahl der Iterationen (hier) unnötig!
Nur ein IndexArray - und auch ohne Index-Konstanten!
Bitte sonst auch auf passende Datentypen und dazu passende Funktionen achten!
Warum ist "Preset Number of Cycles" ein DBL-Wert statt eines Integers? Vergleiche mit float-Werten kräuseln (bei mir) immer die Zehnägel hoch!
Wenn du Pfade bauen willst, dann verwende Pfad-Funktionen! Wenn du Zeitangaben in einen Dateinamen formatieren willst, dann verwende FormatIntoString:
[
attachment=61132](Ich habe den Formatstring nach meinen Vorlieben gestaltet, kannst du ja gern nach deinen Requirements anpassen…)
Hallo Gerd,
Zitat: Da hast du auch einen groben Fehler eingebaut! Du versuchst an zwei Stellen aus ein und der selben Queue zu lesen: wer bekommt da wohl welche Daten ab?
Danke! Das hatte ich nicht bedacht. Aber macht ja Sinn, dass dann immer Daten fehlen werden....
Habe das Programm nach deinen Vorgaben umgebaut und nun funktioniert es schon sehr gut; wesentlich besser als vorher.
Nun habe ich nur noch das Problem, dass mir die zweite Queue beim Releasen den Error Code 1 ausgibt. Möchte ich diesen Code, wie in der NI Knowledge Base beschrieben, ignorieren bzw. löschen, dann stoppt das VI nicht mehr. Was habe ich hier falsch gemacht?
Außerdem wollte ich noch fragen, ob es möglich ist eine waveform entweder komplett zu loggen oder nur die Peaks? Das alles ohne den gesamten Aufbau (Shiftregister, etc.) zu verdoppeln? Habe versucht diese Funktion in das Projekt einzubauen....
Vielen Dank nochmal!
Hallo Tom,
noch ein grober Fehler: du solltest keine "default if unwired"-Tunnel verwenden, wenn du Referenzen durch eine Struktur verdrahtest!
(Main_vi_200818, Logging-Loop, Error-Case)
Du beendest die Logging-Loop, wenn das Dequeue einen Fehler ausgibt. Dummerweise löscht du im Error-Case aber die Referenz der zweiten Queue, sodass das ReleaseQueue natürlich eine Fehlermeldung ausgibt…
Tipp: wenn du in deinen subVIs auch einen ErrorIn-Anschluss vorsiehst (und im subVI verwendest), dann kannst du dir viele MergeError-Nodes sparen!
Super!
Herzlichen Dank! Und wieder was gelernt.
Jetzt läufts. :-)