LabVIEWForum.de - Einfache An/Aus Steuerung mit Sensorwerten - Pufferfehler?

LabVIEWForum.de

Normale Version: Einfache An/Aus Steuerung mit Sensorwerten - Pufferfehler?
Du siehst gerade eine vereinfachte Darstellung unserer Inhalte. Normale Ansicht mit richtiger Formatierung.
Seiten: 1 2
Hallo alle zusammen!

Ich muss zügig eine ganz simple Ein-Aus Steuerung basteln und habe vorher noch nie wirklich mit Labview gearbeitet, also entschuldigt den katastrophalen Programmierstil. Es ist mehr oder weniger aus verschiedenen Beispielen zusammenkopiert.

In dem Programm lese ich 6 Sensoren über ein DAQ System aus (2x Luftfeuchte, 2x Temperatur und 2x CO2 Konzentration). Die jeweiligen Werte zeige ich in einem Kurzzeit-Chart und einem Langzeit-Chart an, um auch die Änderungen über einen längeren Zeitraum zu sehen. Dafür benutze ich eine While Schleife mit Shift-Register.
Neben dem reinen Auslesen habe ich eine manuelle Steuerung von Ausgängen und eine ganz simple, automatische, Ein-Aus Steuerung realisiert. Das heißt sobald z.B. die Temperatur einen gewissen Grenzwert überschreitet, wird ein Ausgang auf "an" gesetzt. Das passiert ebenfalls in der großen While Schleife.

Das funktioniert auch alles soweit. Nur habe ich festgestellt, dass die Zeit auf den Charts "hinterherhinkt", also nicht in Echtzeit abläuft. So habe ich nach vier Stunden messen eine Verzögerung von ungefähr 30 Minuten und nach 12 Stunden kommt ein "Speicher voll"-Fehler. Zur Zeit messe ich mit N samples: 100 to read, 100 Hz. Als ich mal mit 10 to read und 100Hz gemessen hab kam schon nach sehr kurzer Zeit ein Error 200279 "Attempted to read samples that are no longer available". Ich vermute mal, dass der Programmablauf mit den Logikoperatoren zu viel Rechenzeit in Anspruch nimmt und man das Programm irgendwie in verschiedene "unterschleifen?!?" zergliedern muss. Praktisch weiß ich aber nicht wie man das am besten umsetzt. Ich habe auch schon versucht mit globalen Variabeln und zwei While-schleifen zu arbeiten, allerdings hat das auch nicht funktioniert. Bitte bedenkt, dass ich mich noch nicht wirklich mit der Materie auskennt.

Ich bin also für praktische Tipps sehr dankbar! Die Suchfunktion habe ich auch benutzt, aber keinen passenden Beitrag gefunden, vielleicht weiß ich auch nicht genau nach was ich suchen muss.

Viele Grüße,
Hendrik

EDIT jg: Der Link zum Crosspost auf ni.com
Hallo hendrik,

Zitat:Nur habe ich festgestellt, dass die Zeit auf den Charts "hinterherhinkt", also nicht in Echtzeit abläuft. So habe ich nach vier Stunden messen eine Verzögerung von ungefähr 30 Minuten und nach 12 Stunden kommt ein "Speicher voll"-Fehler.
Dann suche mal nach "handling big data"…
- Es ist tödlich, große Datenmengen in Schieberegistern zu sammeln - wie du selbst festgestellt hast!
- Es ist auch unsinnig, solche Datenmengen in Charts/Graphen anzuzeigen: auf ~250px Breite mehr als 250 Datenpunkte darstellen zu wollen ist Blödsinn!

Tipp: LabVIEW-Hilfe lesen! Ein Artikel wäre z.B. "Grundlagen" -> "Leistungs- und Speichermanagment"!

- Es ist auch nicht hilfreich, alles in einer großen Schleife erledigen zu wollen.
- RubeGoldbergs sind nie hilfreich, wozu braucht man Konstrukte wie "IF true THEN true ELSE false"? Hmm
- Wozu legst du Typdefinitionen für einzelne numerische Controls an?

Zitat:Ich muss zügig eine ganz simple Ein-Aus Steuerung basteln und habe vorher noch nie wirklich mit Labview gearbeitet
"zügig" und "noch nie mit LabVIEW gearbeitet" schließen sich gegenseitig aus - auch wenn das NI-Marketing ständig etwas anderes betet…
Hallo Gerd,

vielen Dank soweit!
Ich habe das ganze jetzt etwas umgestrikt. Und zwar wieder in die zwei-While-Schleifen Anordnung. Eine Schleife zum Lesen und eine zum Visualisieren & Steuern.

Das Diagramm zum Anzeigen der Langzeitwerte habe ich länger gemacht, allerdings frage ich mich wie ich auf der x-Achse eine genauere Unterteilung der Zeit hinbekomme, dazu habe ich nichts gefunden in den Chart-Eigenschaften.

Die Typdefinitionen waren noch ein überbleibsel, genauso wie die merkwürdigen Konstrukte, die sind nun ebenfalls gelöscht.

Jetzt habei ich ein Problem mit den Queues. Anscheinend kann man keine Waveform-Type Variablen in die Queue als Element hinzufügen? Kann man das Problem irgendwie umgehen?

Viele Grüße,
Hendrik
Hallo Hendrik,

Zitat:Und zwar wieder in die zwei-While-Schleifen Anordnung. Eine Schleife zum Lesen und eine zum Visualisieren & Steuern.
So weit, so gut…

Zitat:Das Diagramm zum Anzeigen der Langzeitwerte habe ich länger gemacht, allerdings frage ich mich wie ich auf der x-Achse eine genauere Unterteilung der Zeit hinbekomme, dazu habe ich nichts gefunden in den Chart-Eigenschaften.
Das du den Chart breiter machst, ändert nichts an seiner Historie oder an der Menge der Daten, die du darstellen lässt…

Zitat:Die Typdefinitionen waren noch ein überbleibsel, genauso wie die merkwürdigen Konstrukte, die sind nun ebenfalls gelöscht.
Big Grin

Zitat:Jetzt habei ich ein Problem mit den Queues. Anscheinend kann man keine Waveform-Type Variablen in die Queue als Element hinzufügen? Kann man das Problem irgendwie umgehen?
Wieso soll das ein Problem sein? Du schreibst doch munter Waveforms in die Queues hinein?!

Deine Probleme sind ganz woanders!
THINK DATAFLOW!
- Deine zwei Schleifen haben eine Datenabhängigkeit und laufen deshalb nacheinander statt parallel.
- Deine erste Schleife (wo die Daten in die Queues geschrieben werden) ist generell "Blödsinn": sie läuft ungebremst, schreibt deshalb dauernd Daten in die Queues. Außerdem schreibst sie dauernd die selben Daten in die Queue: THINK DATAFLOW!
- Was soll es hier bringen, die Waveforms weiterhin ständig zu erweitern, um dann immer noch größere Datenmengen in die Queue zu stopfen? Willst du "auf Teufel komm raus" den Speicher vollmüllen?

Bitte überdenke deinen Programmaufbau.
Schau dir an, wie man echte Producer-Consumer-Strukturen erstellt, LabVIEW bringt dazu fertige Beispiele mit!
Schau dir die oben genannten Punkte in der LabVIEW-Hilfe an!
THINK DATAFLOW!
Der entscheidende Fehler, der das Hinterherhinken erklärt, ist:
Fortwährendes Erfassen einer endlichen Anzahl von Samples in einer Schleife ist nicht dasselbe wie kontinuierliches Messen. Bei jedem Duchlauf in der Schleife hat man so eine Lücke zwischen den Datenerfassungen, die das Nachhinken in der Zeit erklärt.
Also: Datenerfassung auf "Kontinuierlich" umstellen, Sampleanzahl pro Scheifendurchlauf (100) so lassen wie sie ist. Dein umständliches Gedöns mit dem Zusammenfügen der einzelnen Erfassungen pro Schleifendurchlauf solltest Du dann ändern, das wird viel einfacher. (Wenn Du dazu Hilfe brauchst, melde Dich)
Edit: Die erwähnte Lücke setzt sich aus zwei Teilen zusammen. Einmal muss sich der DAQ-Assistent beim Aufruf jedes Mal neu konfigurieren, bevor er den Task mit endlicher Anzahl Samples neu startet. Das dauert ca. 10 ms, d.h. Dir geht jedes Mal eine Sample verloren. Zum anderen wird der DAQ-Assistent ja nicht sofort neu aufgerufen, sondern der datenabhängige Rest des Codes der sonst noch in der Schleife ist, wird erst mal noch abgearbeitet. Dauer? Weiß nicht. Bei kontinuierlicher Erfassung spielt beides kein Rolle, die Datenerfassung auf der Karte läuft in Echtzeit parallel und unterbrechungsfrei im Dauerbetrieb.
Super! Vielen Dank für die Hinweise!
Mein ursprüngliches Programm scheint mit dem Tipp von Lucki zu funktionieren!

Allerdings hat mich jetzt der Ehrgeiz gepackt und ich würde es gerne auch mit der Producer-Consumer Struktur hinbekommen! Das sieht zumindest äußerlich etwas ordentlicher aus, als mein erster Gehversuch.
Ich komme an mehreren Stellen nicht weiter und bin für jeden Hinweis dankbar! Es tut mir nach wie vor Leid wenn ich hier sehr dumme Fragen stelle, aber ich hab zumindest das Gefühl so langsam ein bisschen zu verstehen was in dem Programm vor sich geht. So einfach wie beim Kauf gepredigt ist es allerdings trotzdem nicht, da kann ich Gerd nur zustimmen.

- Im oberen Teil der Producer-Schleife schreibe ich doch die gemessenen Waveform Werte als Array-Element in die Queue? Stimmt das? Und falls ja, mit welcher Funktion bekomme ich die Werte aus dem zweiten Messbaustein in der Consumer Schleife damit kombiniert.

- Wie bekomme ich die Datenabhängigkeit aus den Schleifen? Also dass diese wirklich parallel laufen?

- Und wie bekomme ich die Elemente dann wieder gezielt aus der Queue in der Consumer Schleife heraus? Also ohne "leere Elemente" zu lesen und mir dadurch Fehler zu erzeugen. Ich würde ja gerne kontinuierlich, also über 24h Messen und bei einem bestimmten Ereignis einen Ausgang schalten.
Hallo Hendrik,

Zitat:Wie bekomme ich die Datenabhängigkeit aus den Schleifen? Also dass diese wirklich parallel laufen?
Ich glaube kaum, dass in den offiziellen Beispielen zur Producer-Consumer-Struktur die Queue-Referenz vom QueueErstellen über eine FeedbackNode zur zweiten Schleife weitergereicht wird. Und das man die Queue erst nach der Producerschleife erstellt, ist dort ganz sicher auch nicht gezeigt worden!
THINK DATAFLOW!
Warum nicht einfach QueueErstellen vor beiden Schleifen aufrufen und die so erhaltene Queuereferenz an beide Schleifen verdrahten?
Hmm

Zitat:Und wie bekomme ich die Elemente dann wieder gezielt aus der Queue in der Consumer Schleife heraus? Also ohne "leere Elemente" zu lesen und mir dadurch Fehler zu erzeugen.
Du weißt, wie eine Queue funktioniert? FIFO?
Wenn "leere Elemente" aus der Queue herauspurzeln, dann hast du diese irgendwo auch hineingestopft. Und da liegt dann dein Problem…

Zitat:Im oberen Teil der Producer-Schleife schreibe ich doch die gemessenen Waveform Werte als Array-Element in die Queue? Stimmt das?
Du schreibst ein "Array of Waveform" in die Queue…
Hallo Gerd,

Das folgende Beispiel wollte ich nachbauen: http://www.ni.com/white-paper/3023/en/

Ich muss also erst einen "array of waveforms" außerhalb der Schleife erzeugen und den an den Element Data Type von der Obtain Queue verdrahten??

Wie erstelle ich einen blanko "array of waveforms"?
Habe mir das neue VI noch nicht angesehen. Muß Dir nur sagen, dass ich den Wert eine Producer-Consumer-Struktur hier nicht erkenne. Und zwar deshalb.
Die Struktur Producer-Consumer ist: Producer- und Consumer-Code laufen parallel, und die Datenübertragung zwischen beiden findet über einen Fifo-Puffer statt.
Aber genau diese Struktur hat man bereits, wenn man für die Datenerfassung NI-Karten verwendet. Der Producer ist die Karte mit darauf befindlichem Echtzeitsystem. dazwischen liegt ein Puffer, und die Datenverarbeitung macht das Labview-Programm auf dem PC.
Wenn man also jetzt nochmal eine Producer-Consumer Struktur installiert, so ist das in Wirklichkeit eine Struktur "Producer - Puffer1(NI-Karte) - Puffer2(Queue-Struktur) - Consumer", also redundant. Allerdings muss man auch zugeben: Es kommt mehr Ästhetik in das Programm rein -Redundanz hin oder her. Nur eine funktionelle Verbesserung sollest Du Dir nicht davon versprechen.
Etwas anderes ist hingegen ganz wichtig:
Die beiden Datenerfassungen bei Dir sollten in parallelen Strukturen stattfinden. So wie es jetzt ist, bestimmt die langsamere der beiden Erfassungen das Tempo, und es kann dann zum Pufferüberlauf bei der schnelleren Erfassung kommen. Zwar hast Du bei beiden Erfassungen die gleichen Parameter eingestellt, aber sicher wäre ich mir da trotzdem nicht, dass es im Langzeitbetrieb zum Stau in einem der beiden Puffer kommen kann.
Hallo Hendrik,

Zitat:Wie erstelle ich einen blanko "array of waveforms"?
Entweder packst du erst eine Array-Konstante in dein BD und schiebst dort eine Waveform-Konstante hinein
ODER du erstellst eine passende Konstante per Rechtsklick auf den Ausgang der DAQmxRead-Funktion…

Beide Vorgehensweisen sind dermaßen LabVIEW-Basics, dass ich dir unbedingt die Links in meiner Signatur an Herz legen muss!
Seiten: 1 2
Referenz-URLs