Hallo,
ich programmiere seit vielen Jahren in textbasierten Sprachen, wie Java und PHP. Die Umstellung auf das Datenflussmodell von Labview war denkbar groß. In meinem Programm zur Anlagenüberwachung und Steuerung laufen viele Prozesse nebeneinander ab und benötigen Werte aus anderen Teilen wie z.B. Temperaturen auslesen, die dann von mehrern anderen Codeteilen genutzt werden. Damit mein Code nicht wie ein Sprinnennetz aussieht verwendete ich eine Menge lokaler Variablen. Wie ich jetzt weiß klappt das irgendwann nicht mehr, da nicht sicher ist, welcher Codeteil wann ausgeführt wird. Ganz anders als bei textbasierten Sprachen. Dem entsprechende Probleme treten in meinem Programm nun auf. Nun meine Fragen:
Gibt es eine Möglichkeit lokale Variablen so zu nutzen, wie man es aus textbasierten Sprachen her kennt? Also das der Wert erst gelesen wird, wenn er an andere Stelle beschrieben wurde?
Welche Strategien sind erfahrungsgemäß am besten, um sicher zu stellen, das Fragmente vor anderen ausgeführt werden?
In einem Teil habe ich durch eine logische Schaltung sichergestellt, das ein ansonsten unabhängiges Fragment aus mehreren SubVIs garantiert vor einem anderen ausgeführt wird. Das allgemein zu machen macht das Programm aber sehr komplex und unübersichtlich. Die direkte Verkabelung sähe noch schlimmer aus.
PS: Geschwindigkeit und Speicherbedarf sind für die Problemlösung absolut irrelevant.
Hi Rob,
Wenn du von mehreren Stellen auf Daten zugreifen möchtest, bieten sich
Funktional Globale Variablen (FGV) an. Wenn du parallel ausführbare Programmteile hast, musst du trotzdem noch selber darauf achten, dass du Werte erst verwendest wenn sie gültig sind. Das ist in textbasierten Sprachen auch nicht anders. Da benutzt man für Parallelität Threads. In LabVIEW muss man "nur" den Datenfluss verzweigen.
Es gibt auch andere Möglichkeiten, zB Queues oder eine eigene Klasse für Datenhaltung wenn du OOP benutzt.
Thomas
(27.05.2014 11:10 )RobBoss schrieb: [ -> ]Welche Strategien sind erfahrungsgemäß am besten, um sicher zu stellen, das Fragmente vor anderen ausgeführt werden?
Meinst du das im Sinne von Interrupts oder im Sinne von sequentiellen Abläufen? Dafür gibts eine fertige Schleife (Sequence Loop). Andernfalls eventuell über eine Event Structure? Das sind jetzt die mir auf Anhieb bekannten Möglichkeiten und ich bin ebenfalls noch ziemlicher Anfänger. Da gibt es sicherlich noch weitere Methoden.
Gruß
NoWay
Hallo,
Zitat:Also das der Wert erst gelesen wird, wenn er an andere Stelle beschrieben wurde?
Weitere Möglichkeiten:
- Melder/Notifier, wenn es um Einzelwerte (ohne Historie) geht
- Queues, wenn Daten verlustfrei von einem Producer zu einem Consumer transportiert werden sollen
- die schon angesprochenen FGVs
- Key-Value-Pairs (die innerhalb einer FGV verwaltet werden): dazu gibt es Implementierungen bei NI, z.B.
diese hier
Zitat:Welche Strategien sind erfahrungsgemäß am besten, um sicher zu stellen, das Fragmente vor anderen ausgeführt werden?
- wichtigster Punkt: durchgehende Nutzung des DATAFLOW durch Verdrahtung unter Verzicht auf lokale Variablen!
THINK DATAFLOW! (Das steht ziemlich am Anfang in der LabVIEW-Hilfe…)
- State machines (da gibt es ein Beispiel-Projekt zu)
- Producer-Consumer-Schema (da gibt es ein Beispiel-Projekt zu)
- Queued Message Handler (da gibt es…)
- quasi jedes vernünftige Softwaredesign, welches man sich vor dem eigentlichen Programmieren überlegt hat…
Die Verwendung von lokalen Variablen als Datenspeicher sind eine denkbar schlechte Lösung, wie du bereits richtig erkannt hast. Welcher Codeteil wann ausgeführt wird hängt bei LabVIEW genauso wie bei textbasierten Systemen von deiner Programmierung ab. In LabVIEW ist es nur sehr viel einfacher "mal eben" einen neuen Thread zu starten.
Um deine Fragen zu beantworten:
Lokale Variablen können nicht serialisiert werden. Um Daten innerhalb derselbe Schleife zu puffern sind Schieberegister eine gute Lösung. Zum Senden von Daten aus einer Schleife in eine Andere eignen sich Queues. Wenn du den Zugriff auf Resourcen sperren möchtest gibt es Semaphoren.
Ich gehe davon aus, dass du alle Funktionen in ein VI geschrieben hast (wg. lokaler Variablen). Du solltest dein Programm nach logischen Einheiten und Schrittfolgen untersuchen und diese in einzelne Sub-VIs untergliedern (unter Verwendung der oben genannten Tools, um Daten auszutauschen).
Wenn deine Programmteile immer in einer bestimmten Folge, bzw. abhängig von dem Ergebnis des aktuellen Schrittes verarbeitet werden, solltest du dir die Funktionsweise eines Zustandsautomaten in LabVIEW näher ansehen.
Zwei wichtige Sachen vielleicht noch:
Es ist meist hilfreich SubVIs mit nem Fehlercluster (in und out) auszustatten, selbst wenn die intern gar keine Fehler werfen. Potentiell sollen die das zum einen eventuell irgendwann doch und zum zweiten bietet es sich in der Regel an genau über diesen Fehlercluster die sequentielle ausführung zu Steuern (da man die Fehler halt in der Regel einfach von Anfang bis ende durchschleift).
Außerdem: Um Kabelgewirr zu vermeiden gibt es Cluster. Da kannst du deine Kabel Bündeln und du kannst sogar die einzelnen Clusterelemente mit Namen versehen. Das verhält sich grundsätzlich wie ein Kabel das du durchziehst und mit einem unbundle by name kannst du dir anschließend jeweils "Einzelelemente" rausnehmen (ähnlich wie du es mit Variablen machen würdest) ohne den kompletten Cluster immer aufzuziehen.
P.S: Es wird btw. von NI angeraten maximal eine Monitorfläche pro VI zu benutzen damit die VIs übersichtlich bleiben. Wenn du das einhälst, kann es normalerweise nicht zu unübersichtlichem Kabelgewirr kommen
Wenns größer wird
sollte man schauen wie man geschickt in SUBVIs gliedern und welche eingabedaten man entsprechend Bündeln kann.
Ansonsten, andere Varianten wie man Prozesssteuerung und Parrallelläufigkeit handhabt wurden ja schon weiter oben genannt.