Hier zusammengestellt sind diverse Unterprogramme,
die allgemein für die LabVIEW-Programmierung hilfreich sind.
Da die meisten in LabVIEW 2009 erstellt sind,
gibt es jeweils auch Bilder von deren Funktionsplan,
zum Nachmalen und Verstehen.
Prozess-Steuerung: Zeitverlaufs-Array (etwa wie CSV-Daten) bei Abarbeitung mit Fortschrittsbalken hinterlegen — Video (animiertes GIF bei heller Windows7-Kontrastdarstellung)
Teil von SuperMessung: Automatische Zuordnung von Signalen zu Achsen anhand von (gleichen) Einheiten, Achsenbeschriftung farbig passend zur Plotfarbe (hier: LabVIEW 2010): Testprogramm, Screenshot
Runden von zwei Zahlenwerten als Endwerte einer Skale: Auf angebbare Genauigkeit (auch gebrochen), der obere Wert auf-, den unteren Wert abrundend. Die Nachkommastellen als Ergebnis dienen der Formatierung der Zahlen.
Modalanalyse per Soundkarte, mittels Impulshammer und Messsonde. War mal als Scherz zur Doktorverteidigung gedacht, ist aber tatsächlich produktiv einsetzbar.
(Ehemaliger) Versuchsstand Motorspindel = 2 Motoren mit Zahnriemen und Schaltschrank, 6 kapazitive Sensoren rund um die Werkzeugspindel messen Fluchtabweichung, Bonbon: 3D-Darstellung der Verkippungen
So hübsch LabVIEW auch aussehen mag,
früher oder später stößt man auf unlösbare Probleme:
Hohe Abtastrate führt zu „rätselhaften“ Problemen
bei der Verarbeitung der Messdaten.
Konzeptloser Umgang mit Mehrkanal-Signalen.
Speicherleck (böse!), verschwindet erst beim Beenden von LabVIEW,
nicht beim Beenden eines Mess-VIs.
Verhindert „zuverlässig“ Langzeitmessungen.
Kein Datenfluss (wie versprochen), sondern Unterprogramme:
Liefern Daten erst bei Beendigung, nicht kontinuierlich.
Widersinniges „Programmier“-Konzept mit Schleifen.
Unklare Zuordnung von VI-spezifischen Zustandsvariablen
Explodierende LabVIEW-Projekte beim Erweitern,
insbesondere der GUI, Modularisierung schlecht
Wie kombiniert man mehrere Measurement Tasks zu einer?
Synchrone oder rationale Abtastrate untereinander?
Einige NI-Messkarten erfordern getrennte Measurement Tasks.
Wie ist es dann mit dem Gleichlauf?
GUI erscheint als Fremdkörper: Komische Dialogelemente,
keine Hotkeys, keine Default-Buttons u.v.a. Probleme
Was nimmt man nun zum Speichern von Messdaten?
Zu viele Möglichkeiten, nichts davon übersichtlich.
Deshalb diese Eigenkreation (Waveform.llb).
Es wimmelt von hinterhältigen Bugs (auch mathematische) — wohin damit?
Bspw. gibt das VI Re+Im→Betrag+Phase, angewendet auf Signal,
keinen Betrag aus, wenn man die Phase unangeschlossen belässt.
Nur statische Einheitenzuordnung; benötigt werden dynamische
Fehlplatzierte, unveränderliche Einheiten in Grafen
Fehlende Arrays von Arrays
Was passiert, wenn man nebenbei ein .PDF lesen muss? CHAOS!
Denn ALT+TAB (Schnelle Taskumschaltung) funktioniert nicht wie gewohnt.
LabVIEW als Fremdkörper, nicht als Windows-Mitbürger
Versions-Wettrüsten: LabVIEW-Programme (VIs) sind niemals abwärtskompatibel,
zwingt Anwender beim Datenaustausch zur jeweils neuesten Version
Bloatware
(Software ist selbst bei Minimal-Installation riesengroß, viel zu lahme Installation)
Fehlende Exception-Behandlung, dafür ist das umständliche
Durchschleifen von Fehler-Clustern üblich
Umständliche Objektorientierung (hält den Durchschnittsanwender ab),
passt ohnehin nicht sonderlich zum grafischen Programmierkonzept
Vergleichbar mit Skriptsprachen haftet so auch LabVIEW
das Manko der schwierigen Skalierbarkeit für größer werdende Vorhaben an.
Abgesehen davon, dass man sich mit Gedeih und Verderb
an die Politik von National Instruments klammert
und mit den undokumentierten VI-Dateien
niemals echten Quelltext vor sich hat.
Datenerfassung ohne Löcher
Ein häufiges praktisches Problem ist eine Datenerfassung,
die nicht aussetzen darf.
Hingegen sind Verzögerungen in der Weiterverarbeitung kein Problem.
Die Abtastrate oder Kanalzuordnung sollte zur Laufzeit änderbar sein,
und die Datenerfassung bei wackeliger Schnittstelle selbst „recovern“.
(Dann und nur dann sind Löcher unvermeidbar und zulässig.)
Grundsäzlich sind Messdaten in Stücke von 100 ms Länge zu packen,
um den besten Kompromiss von Rechenlast und Antwortverhalten zu erreichen.
Der Datentyp „Signal“ (Waveform) ist stets zu bevorzugen.
Lösung:
2 Warteschlangen einrichten:
Eine Steuer-Warteschlange mit 1 Cluster (oder Melder), Tiefe = 1, Timeout = ∞
Eine Daten-Warteschlange mit Array of Waveform, Tiefe = ∞, Timeout = ∞
1 Sub-VI erstellen, welches von der Steuer-Warteschlange
Parameter liest („Status lesen“) und bei Erfolg („Element vorhanden“)
die Datenerfassung blockierend durchführt.
Die Daten kommen in die Daten-Warteschlange („Element einfügen“).
Ist die Steuer-Warteschlange leer, muss blockiert werden.
Dieses Sub-VI beendet sich nur beim Fehlen der Steuer- oder
Daten-Warteschlange und hat keinen Ausgang!
Es erfolgt außer im Fehlerfall kein Zugriff auf GUI-Elemente.
Hilfreich ist es, eine Referenz zu einem GUI-Element
(zweckmäßig: System-Tabelle) mitzuliefern,
damit Fehlermeldungen nicht als Messagebox erscheinen müssen.
Dieses Sub-VI wird auf „erhöhte Priorität“ gesetzt.
Das Haupt-VI startet dieses Sub-VI einmalig als nebenläufigen
Thread außerhalb jeglicher Schleifen.
Dieser Thread ist durch das Befüllen der Steuer-Warteschlange
startbar und durch Leeren anhaltbar.
(Man beachte, dass LabVIEW das echte Erzeugen und Beenden von Threads
nur mit dynamisch ladbaren VIs zulässt, das ist sehr umständlich
und geht erst ab neueren LabVIEW-Versionen!)
Wichtig ist, dass:
die Datenerfassung in einem gegenüber der GUI
höher priorisierten Thread läuft
die Datenerfassung (am Besten per Hardware) blockiert,
d.h. Rechenzeit freigibt bis tatsächlich Daten kommen.
Bei NI-Messhardware (PCI, PXI oder USB) sowie GPIB ist dies generell der Fall.
Kein GUI-Zugriff erfolgt, außer im Fehlerfall
Kann man mehrere derartige Sub-VIs parallel laufen lassen?
Ja, allerdings geht deren zeitliche Übereinstimmung flöten.
Man muss sich daher im Hauptprogramm um das Angleichen
(Resampling) der Messdaten der zusätzlichen Sub-VIs kümmern,
wenn das erforderlich ist — es ist fast immer erforderlich!
Sonstige eigene Beispiele
Auslesen Durchflussmesser SD6000 (dazu Mikrocontroller-Schaltung zur USB-Anbindung)
Diese USB-Anbindung erfordert keinen NI-Gerätetreiber!
6-Achs-Schrittmotorsteuerung mit koordinierter Freiform-Bahnfahrtmöglichkeit
(angeschlossen an serieller Schnittstelle)
Herausgewursteltes
Immer wieder stört es mich, nicht sinnvoll dynamische Einheiten
verwenden zu können,
etwa eine Einheit aus einem Double-Eimgabefeld herauszuholen.
Die Antwort ist simpel: Es geht nicht!
Die Einheitenzuordnung ist statisch
(wie oben bereits bemerkt).
Nun, über ein Variant geht es doch!
Den Variant kann man mittels Variant to Flattened String
in einen String (enthält den Wert) und ein mysteriöses Int16-Array
aufteilen.
Dieses Int16-Array enthält:
die Gesamtlänge in Bytes
ein Flag-Integer (uninteressant)
eine Liste der Basiseinheiten und deren Exponenten
ab dem 2. Int16-Arrayelement
den Namen der Variable als String mit vorangestellter Länge
Die Liste der Basiseinheiten ist wie folgt aufgebaut:
Int16 Anzahl der Basiseinheiten, mindestens 1, maximal 8
paarweise
Int16 Basiseinheit-Enum 0..8
Int16 Basiseinheit-Exponent ≠0(logischerweise ganzzahlig, man
hat mal wieder nicht an µA/√Hz gedacht!)
Für den Basiseinheit-Enum habe ich folgende
Zuordnungen gefunden:
rad (ebener Winkel, mit Umrechnung: deg)
sr (Raumwinkel in Steradiant)
s (Zeit: Sekunde, mit Umrechnung h u.ä.)
m (Länge: Meter)
kg (Masse: Kilogramm)
A (Elektrischer Strom: Ampère)
K (Temperatur: Kelvin; mit Umrechnung: °C;
LabVIEW-Falle: degC = °C
aber Cdeg = K!)
mol (Stoffmenge)
cd (Lichtstärke in Candela)
Wichtig: Einheitenvorsätze werden nicht weitergegeben!
Man weiß also nicht, ob ein Wert in °C oder K angegeben wurde,
es wird stets in K umgerechnet.
Eine Ähnlichkeit zur Einheitenkodierung im USB-HID-Deskriptor
drängt sich auf; dort passt sie nibbleweise komplett in ein DWORD.
Raumwinkel und Stoffmenge hat man da allerdings „vergessen“.
Eine Echse portabel machen
Auf die schlaue Idee, aus dem LabVIEW-Programm eine .EXE zu machen
um diese auf einem anderen PC laufen zu lassen kam wohl schon fast jeder.
Aber Pustekuchen, die Echse benötigt eine
NI-Laufzeitumgebung!
Muss zur Jahreszahl passen!
Man kann beim Erstellen der .EXE auch angeben,
dass neuere Laufzeitumgebungen zulässig sind,
aber das Häkchen muss man erst setzen.
Service Pack (SP) ist egal
Muss 32 Bit sein!
Installationspaket ca. 500 MByte!
Installationsdauer mit Virenscanner etwa 1/2 Stunde, permanente Anwesenheit erforderlich wegen Rückfragen
(Kostenlose) Registrierung bei NI erforderlich
Keine Seriennummer erforderlich
Booten
Ist diese endlich installiert, stellt man schließlich fest,
dass „Gerätetreiber“ zum Zugriff auf die Hardware fehlen.
Das betrifft zumeist eine serielle Schnittstelle
sowie NI-Hardware, oftmals ein NI USB-6008.
Dazu muss dann noch einmal Software heruntergeladen werden:
Installationspaket ca. 2 GByte!!
Installationsdauer mit Virenscanner etwa 2 Stunden, permanente Anwesenheit erforderlich wegen Rückfragen
Zu installieren ist — jeweils für LabVIEW gleiche Jahreszahl:
NI VISA (alles was quasi seriell arbeitet: USB, COM-Port, GPIB)
(das installiert die wichtigen gelben Sub-VIs unter
„Instrumenten-I/O → VISA“)
NI Serial (für COM-Port)
NI 488 (für GPIB)
NI USB (für solche USB-Geräte, für die man eine INF-Datei generiert hatte)
NI DAQmx ADE (Data Acquisition Mixed Application Development)
(für alle NI-Hardware, in PCI-Steckplätzen oder USB-Geräte,
das installiert die wichtigen braunen Sub-VIs unter
„Mess-I/O → DAQmx - Datenerfassung“)
Das zieht den Rattenschwanz mit Measurement & Automation Explorer (MAX) hinterher.
(Kostenlose) Registrierung bei NI erforderlich
Keine Seriennummer erforderlich
Booten
Dann sollte die Echse auf dem Zielrechner endlich funktionieren.
Will man, dass die Software „probeweise“ auf einem Zweitrechner
nur zur Datenauswertung ohne Treiber läuft,
muss man die Hardware zugreifenden VIs dynamisch laden.
I.a. zu viel Aufwand!
Dann kann man sich an das Deinstallieren nicht benötigter Softwareteile machen.
Unbedingt drauf bleiben muss das was in der Grafik rot markiert ist.
Beim Deinstallieren muss man höllisch aufpassen, wer was dereferenziert!
Man muss tatsächlich sowohl das im Bild zu sehende .NET-Geraffel
als auch das LabWindows/CVI-Geraffel drauf lassen!
TDM Excel, VIPM und Netzwerkbrowser kann IMHO weg.
I/O Trace vermutlich auch.
Das PXI-Zeug muss anscheinend drauf bleiben,
auch wenn man kein PXI (= externes PCI oder PCIexpress,
dass ist die ganz teure NI-Hardware) hat.
Vorteil einer Echse
Hat, auf einem Rechner mit installiertem LabVIEW,
eine Echse einen Vorteil gegenüber einer LLB-Datei?
Ja, äußerst mager:
Man kann das Icon festlegen
Man kann die Echse einfacher mehrfach starten (?)
Das war's auch schon!!
Probleme einer Echse
Das benutzerdefinierte Laden eines VIs nach Namen
ist aus der .EXE-Datei heraus nicht möglich;
EXE-Dateien sind keine LLB-Dateien.
Beim Compilieren gibt es keine entsprechende Fehlermeldung oder Warnung.
Nur statische VI-Referenzen dürften funktionieren. Vielleicht.
In einem Fall wollte ich LabVIEW-Datengenerator-Threads
(die Daten von A/D-Wandlern aufnehmen)
sowie Linearisierungs-VIs (die diese Daten umrechnen)
vom Anwender auswählbar gestalten.
Schön modular also.
In eine .EXE compiliert funktioniert nichts mehr davon.
Wie kommt man von LabVIEW los?
Für den portablen oder mehrfachen Einsatz von Hardware
ist der Einsatz von LabVIEW sowie der teuren NI-Messtechnik
schlichtweg zu teuer und umständlich.
Das kann man niemandem verkaufen!
LabVIEW ist gut fürs Prototyping!
Heißt aber auch, dass man's nachher nochmal schreiben muss.
Keine NI-Hardware kaufen / einsetzen
Da NI-Hardware immer über den Measurement & Automation Explorer (MAX) läuft,
sollte diese nicht eingesetzt werden. Nein, niemals!
Der Ärger hört nicht auf. Wirklich nicht!
Alternativen sind, je nach erforderlicher Rechenleistung:
Eigene Mikrocontroller-Lösung mit serieller oder USB-Schnittstelle, beispielsweise:
Datenlogger mit Raspberry Pi und 24-bit-A/D-Wandler-Shield
Embedded PC
(= Windows-basiertes Entwicklungsboard)
RedPitaya (= FPGA-Board)
Zusätzlich muss man geeignete A/D-Wandler,
D/A-Wandler und Relaiskarten finden oder basteln.
Machen die Chinesen auch so.
C oder C++ oder (notfalls) C# oder Python programmieren
Aber nichts anderes!
Insbesondere kein VisualBasic.
Sonst kommt der Ärger wieder,
und man schießt sich schon wieder ins Knie.
Auf WebUSB setzen
Seit 2019 gibt es WebUSB
für Google Chrome, und mittlerweile (2022) für alle gängigen Browser
außer Firefox.
Insbesondere funktioniert es mit Smartphones;
für diese wird ein geeignetes USB-Kabel benötigt.
Der Einsatz von WebUSB erfordert, dass die Interaktion
mit dem Untersuchungsobjekt ausschließlich über einen
selbst zu programmierenden USB-Mikrocontroller läuft.
Als Ausgangspunkt dafür eignet sich Arduino Leonardo mit ATmega32U4
(nicht Arduino Uno, Arduino Mega),
Arduino Due, STM32F1xx „Blue Pill“ sowie jeder Mikrocontroller
mit USB-Device-Interface, wie PIC16F1459.
(Software-Pingpong-USB wie OBDevs V-USB geht auch ist aber weitestgehend
obsolet weil low-performant.)
Ein Raspberry ist nicht das richtige, hierfür gibt es vergleichbare
Lösungen via Ethernet,
Stichwort WebSocket.
WebUSB erspart es, für USB-Geräte ein Bedienfeld erstellen zu müssen,
häufig Siebensegmentanzeigen und Tasten.
Dies übernimmt eine mit Javascript gepickte Webseite,
deren Adresse das Gerät dem Host beim Anstecken mitteilt.
Zudem kann der Host (auch das Smartphone) das USB-Gerät mit Strom versorgen,
und man muss sich nicht mit der Stromversorgung herumärgern.
(Eigenversorgte) WebUSB-Geräte können autonom arbeiten
und sind nicht von den Launen des Host-PCs (Abstürze, Updates) abhängig.
Das ist vor allem für langwierige Prozesse
sowie sicherheitsrelevante Aufgaben erforderlich.
Die Anwendung wird in Javascript erstellt.
Von Nutzen ist es, vorgefertigte Komponenten für die Grafdarstellung
in einem canvas einzusetzen, aber letztlich kein Muss.