Alle Elemente, die Sie im Nextion ansprechen können sind sogenannte Komponenten. Die meisten davon sind direkt sichtbar wie z. B. ein Schalter (Button), es gibt aber auch unsichtbare Komponenten (z. B. Variablen), deren Existenz im Nextion-Editor unterhalb des Display-Fensters angezeigt wird. Im folgenden Abschnitt werden wir uns alle Komponenten anschauen.
Jede Komponente hat bestimmte Eigenschaften wie die Position oder die Größe, einige davon finden sich (zumindest bei den sichtbaren Objekten) bei allen Komponenten, andere sind spezifisch. Damit ich mich nicht bei allen Komponenten wiederholen muss, werde ich zunächst die allgemeinen Eigenschaften erläutern, die bei allen oder sehr vielen Elementen vorkommen. Bei der Beschreibung der einzelnen Komponenten folgt dann die Erklärung der spezifischen Eigenschaften. Einige Abkürzungen sind nicht gerade leicht nachvollziehbar, deshalb werde ich auch nicht versuchen, eine mögliche Bedeutung zu erraten, sondern den Namen so belassen und beschreiben, was sich dahinter verbirgt.
Einige Eigenschaften können während der Laufzeit geändert werden (grün), die werde ich bei jedem Objekt als veränderliche Größen auflisten. Automatisch aktualisiert wird nach einer Änderung allerdings nur immer die Schlüsseleigenschaft, die im Editor und in der hier folgenden Beschreibung der einzelnen Komponenten grün und fett gedruckt sind.
Eigenschaft | Bezeichnung |
---|---|
id | Jede Komponente erhält vom Editor eine eindeutige id zugewiesen. Sie können diesen Wert zwar ändern, aber Sie können nur Werte vergeben, die noch frei sind. Über diese id können Sie die Komponente mit den einzelnen Befehlen ansprechen. |
objname | Neben der id können Sie einer Komponenten auch einen Namen vergeben, der aussagekräftiger ist, als eine id. Beachten Sie allerdings, dass nicht alle Befehle mit dem Objektnamen funktionieren. Genaue Infos dazu finden Sie bei jedem Befehl in der jeweiligen Beschreibung. |
vscope | Diese Eigenschaft kommt nur dann zum Einsatz, wenn Sie mit mehreren Seiten arbeiten. Sie können hier "local" (standardmäßige Vorgabe) oder "global" wählen. Eine lokale Variable ist nur von Elementen erreichbar, die sich auf der gleichen Seite befinden. Außerdem ist ein Zugriff auf lokale Variablen von außen nur dann möglich, wenn die Seite auch angezeigt wird. Aus diesem Grund kann es auf unterschiedlichen Seiten mehrere Variablen mit dem gleichen Namen und der gleichen id geben, wenn sie als lokal definiert werden. |
style (ab Version 0.39) | Bei einigen Komponenten gibt es jetzt eine Style-Eigenschaft, die die Werte flat, border, 3D_Down (vertieft), 3D_Up (erhöht) oder auch 3D_Auto annehmen kann. Auch wenn die style-Eigenschaft vorhanden ist, sind nicht immer alle Optionen möglich. |
x, y | Die Position der oberen, linken Ecke einer Komponente bezogen auf den Koordinaten-Nullpunkt, der sich ebenfalls in der oberen linken Ecke der Seite befindet. Bei einigen Komponenten mit variablem Inhalt (z. B. Text) bezieht sich die Angabe nicht auf den Inhalt, sondern auf den Rahmen. |
w, h | Die Breite (w) und Höhe (h) der jeweiligen Komponente. Bei Komponenten mit variablem Inhalt (z. B. Text) beziehen sich diese Werte immer auf den Hintergrundrahmen, auch wenn dieser nicht sichtbar ist. |
xcen, ycen | Bei Komponenten mit Rahmen und Inhalt kann der Inhalt auf unterschiedliche Art und Weise im Rahmen angeordnet werden. Die horizontale Anordnung (xcen) erlaubt die Werte: left, center, right. Für die vertikale Ausrichtung (ycen) stehen up, center, down zur Auswahl. |
isbr | Diese Eigenschaft kann auf "True" (Zeilenumbruch) oder "False" (keinen Zeilenumbruch) gesetzt werden. |
spax, spay | Bei zeichenbasiertem Inhalt kann mit "spax" der Abstand zwischen den einzelnen Zeichen festgelegt werden und bei mehreren Zeilen (isbr = "true") auch der Abstand zwischen den Zeilen. |
sta | In der Regel wird über diese Eigenschaft bestimmt, ob Sie ein Bild, ein Bildausschnitt oder eine Füllfarbe für den Hintergrund wählen. Lediglich bei der Komponente "Variable" legen Sie hier fest, ob es sich um eine Zeichenkette oder eine 4-Byte-Variable handelt. |
bco, bco2 | Falls mit einer Füllfarbe gearbeitet wird, können Sie hier die Farbe bestimmen (s. Farbsystem). Verfügt ein Element z. B. über mehrere Zustände (Schalter, Taster), dann kann aus auch eine bco2-Eigenschaft geben. |
pco, pco2 | Mit diesem Parameter wird die Zeichenfarbe bestimmt (s. Farbsystem). Verfügt ein Element z. B. über mehrere Zustände (Schalter, Taster), dann kann aus auch eine pco2-Eigenschaft geben. |
font | Werden bei einer Komponente Zeichen ausgegeben, dann müssen Sie in dieser Eigenschaft den id des Zeichensatzes wählen. |
txt-maxl | Über diese Eigenschaft begrenzen Sie die Länge eines Textes, der bei einer textbasierten Komponete angegeben werden kann. |
Innerhalb des Nextion-Editors können alle der oben genannten Eigenschaften verändert werden. Anders sieht dies während der Laufzeit aus, hier gibt es meist nur einen Parameter, der sich ändern lässt. Im Folgenden wird diese Eigenschaft als "veränderliche Größe" bezeichnet. Ich werde nur die Eigenschaften erklären, die eine spezielle Funktion haben. Die Auswahl des Hintergrundes, des Zeichensatzes etc. sind bei allen Komponenten identisch und deshalb werde ich hier darauf nicht näher eingehen.
Die Seite ist keine Komponente im eigentlichen Sinn, aber auch Sie verfügt über Eigenschaften und vor allem Events. Was sich mir noch nicht so ganz erschließen will, ist der Sinn der Eigenschaft "vscope" für eine Seite, denn Seiten müssen generell global zugänglich sein. Zuerst dachte ich die Eigenschaft bezieht sich auf "bco". Das ist nämlich die einzige zur Laufzeit Veränderliche und wenn sie global ist, könnte sie auch geändert werden, wenn die Seite nicht aktiv ist, aber das funktioniert so nicht. Ich werde es nachtragen, wenn ich dahinter gekommen bin.
Seiten sind extrem hilfreich, um eine komplexe Anwendung in sinnvolle Bereiche zu unterteilen. So können Sie auf einer Seite z. B. die Konfiguration eines Messsystems vornehmen, auf der 2. Seite die Messung starten und stoppen und auf der 3. Seite die Daten auswerten.
Prinzipiell gibt es keine Beschränkung der Seitenzahl, lediglich der Speicher wird irgendwann ein Veto einlegen. Ich habe bei einem 3,2-"-Nextion einmal probeweise 300 Seiten angelegt und es funktionierte problemlos.
Sie können auf jeder Seite entweder ein Hintergrundbild laden oder eine Farbe wählen. Bei jedem Seitenwechsel werden alle Komponenten aktualisiert, es sei denn die Aktualisierung wird explizit gesperrt.
page0.bco=RED
page0.pic=1
Die Textkomponente dient dem Anzeigen von beliebigen Zeichen. Sie wird nicht nur für Textausgaben genutzt, sondern auch für die Darstellung von Fließkommazahlen, da dies mit der Number-Komponente nicht möglich ist.
Achten Sie beim Erstellen Ihrer Oberfläche darauf, dass die korrekte Länge "txt-maxl" im Editor eingestellt wurde, sonst kann es bei längeren Texten zu Fehlern kommen. Auf der anderen Seite gilt: der Compiler reserviert Speicherplatz, von daher sind zu große Werte auch nicht sinnvoll.
text0.txt="ausgabe"
oder text0.txt="1,234"
Reicht der Platz für die Anzeige einer Textinformation nicht aus, können Sie eine Laufschrift wählen. Der Text scrollt dann automatisch in einer vorgegebenen Richtung. Für "maxl-txt" gilt das Gleiche wie bei der Textkomponente.
scroll0.txt="Längerer Text in Laufschrift"
scroll0.en=0
Ein HMI-Device stellt Informationen lediglich dar und arbeitet intern nicht (oder nur sehr begrenzt) mit ihnen. Von daher wäre eine spezielle Number-Komponente nicht wirklich notwendig, denn das könnte genauso gut mit einem Text-Objekt erledigt werden. Trotzdem gibt es gute Gründe für diese Komponente, denn sie erlaubt direkte Manipulationen.
Wenn Sie z. B. den Wert auf einer Anzeige hochzählen wollen, dann müssen Sie bei einer reinen Textanzeige den Inhalt in einer Variablen im Host-Controller speichern, ihn inkrementieren und dann zur Anzeige senden. Nutzen Sie eine Number-Komponente können Sie deren Inhalt mit einem einfachen Inkrement- oder Dekrement-Befehl rauf und runterzählen.
Besonders sinnvoll wird die Anwendung eines Number-Objektes, wenn Sie auf dem Display auch noch Schaltflächen zum Rauf- und Runterzählen integriert haben. Dann verbleibt die gesamte Logik zur Auswahl und Darstellung auf dem Display.
number0.val="ausgabe"
Im Grunde können wir auch mit den vorherigen Komponenten eine Button-Funktion realisieren, denn alle erzeugen die gleichen Touch- bzw. Release-Events. Der Button hat jedoch die spezielle Eigenschaft, dass er die beiden Tasterzustände optisch darstellt. Dazu können Sie entweder 2 Farben wählen oder 2 Bilder. Besonders die letzte Variante kommt häufig zum Einsatz, wenn die beiden Bilder den Taster im gedrückten und nicht gedrückten Zustand darstellen.
Sie brauchen dabei nur die beiden gleichgroßen Bilder bei der Eigenschaft "pic" (Bild für den inaktiven Zustand) und "pic2" (Bild für den gedrückten Zustand) aus der Picture-Galerie auswählen. Das Wechseln übernimmt das Nextion-HMI-Device selbständig.
button0.txt="start"
Mit einem Progressbar wird häufig der Fortschritt eines Prozesses angezeigt, um dem Anwender zu signalisieren, wie weit eine Aufgabe schon bearbeitet wurde. Sie können diese Komponente aber auch sehr gut als Pegelanzeige oder für Temperaturmessungen verwenden.
Wie bei fast allen Komponenten können Sie über das Eigenschaftsfeld "sta" wählen, ob der Hintergrund und der Pegel farblich oder durch 2 Bilder dargestellt wird. Die Bilder müssen dabei gleich groß sein. Das Hintergrundbild wird dabei immer komplett angezeigt, das Vordergrundbild wird dem Hintergrundbild anteilig überlagert.
Beispiel: Bei einem Wert von 20 sehen Sie 20 Prozent vom Vordergrundbild, der Rest ist Hintergrund.
Erstellen Sie am dazu zunächst 2 passende Grafiken. Ich habe mit Magix FotoDesigner einmal 2 Röhren gezeichnet, mit denen ich einen Füllstand angeben möchte. Der Hintergrund ist grau, der Vordergrund rot:
Weil ich eine Füllstandsanzeige damit realisieren möchte, drehe ich die gesamte Grafik um 90° und exportiere dann die einzelnen Säulen z. B. im png-Format. Jetzt lade ich sie in die picture-Library (s. der Nextion-Editor). Ändern Sie "sta" jetzt von "solid color" auf "image". Jetzt doppelklicken Sie das leere Feld hinter "bpic" und wählen als Grafik ihr Hintergrundbild. Das Gleiche führen Sie auch für "ppic" mit dem Vordergrundbild durch. Wenn Sie jetzt den Debug-Modus starten, können Sie in der Input-Area mit dem Befehl "progressbar.val=x" die Höhe des Pegels ändern (die Komponente muss dafür natürlich in "progressbar" umbenannt werden).
Mit der Eigenschaft "dez" (wofür auch immer diese Abkürzung steht) kann die Ausrichtung "horizontal" oder "vertikal" festgelegt werden. Dabei ist zu beachten, dass das Bild selbst nicht gedreht wird, sondern lediglich die Richtung, in der die beiden Bilder überlagert werden. Wenn Sie z. B. eine schmale stehende Röhre darstellen möchten, müssen Sie zunächst auch ein solches Bild erstellen. Deshalb habe ich die Röhre schon in meinem Grafikprogramm korrekt gedreht. Das Ergebnis würde dann bei einem Wert "val=40" wie folgt aussehen:
proBar0.val=50
Die Bildkomponente ist schnell erklärt. Sie können damit an einer beliebigen Stelle auf dem Display ein Bild im Format png oder jpg darstellen. Die Bildgröße wird dabei zunächst von der tatsächlichen Größe bestimmt. Sie können zwar die Werte für "w" und "h" ändern, das eigentliche Bild wird dadurch aber nicht beeinflusst, sondern nur abgeschnitten, wenn x bzw. y kleiner sind als das reale Bild und es wird Hintergrund hinzugefügt, wenn die Werte größer sind. Gezeichnet wird immer von der oberen linken Ecke des Bildes.
picture0.pic=2
Diese Komponente ist zunächst nicht ganz einfach zu verstehen. Egal, wo die Komponente platziert wird, das angegebene Bild wird immer in die obere linke Ecke platziert. Das ist auch bei mehreren crop-Objekten der Fall. Was Sie von dem Bild sehen, wird dann durch die Platzierung des crop-Rahmens bestimmt.
Beispiel: Sie wählen zunächst 2 Crop-Komponenten q0 und q1 und wählen bei beiden Objekten das gleiche Bild. Das Bild wird oben links platziert.
Wenn Sie jetzt die einzelnen Ausschnitte mit dem vis-Befehl ein- und ausschalten, können Sie entweder die linke Seite (vis q0,1 und vis q1,0), die rechte Seite (vis q0,0 und vis q1,1) oder beide Hälften sichtbar schalten oder auch alles unsichtbar machen.
crop1.picc=1
Ein Hotspot ist ein aktiver Bereich, indem bei einer Touchaktivität ein Event ausgelöst wird. Ein Hotspot ist immer dann sinnvoll, wenn nicht das ganze Bild oder der ganze Bereich auf ein Klicken reagieren sollen.
Sie können z. B. das Bild einer Tastatur als Hintergrund wählen und die einzelnen Tasten mit Hotspots versehen.
Den 4 oberen Tasten sind die Hotspots m0, m1, m2 und m3 zugeordnet. Die entsprechenden Events können jetzt die Aktionen auslösen, die Sie wünschen.
Ein Hotspot hat keine zur Laufzeit veränderlichen Eigenschaften.
Der Grundgedanke hinter der Gauge-Komponente ist: Sie haben einen rahmenlosen Kasten mit einem Zeiger und wenn Sie das ganze Bild drehen, dann erweckt das den Eindruck, der Zeiger würde ausschlagen. Überlagern Sie dieses Bild dann noch einem Hintergrund (z. B. Zeigerinstrument), dann haben Sie auch noch eine Skala und ein ansehnliches Aussehen. Allerdings muss die Skala natürlich für die Anwendung passen.
Was die Anwendung allerdings einschränkt, ist die Tatsache, das nur ein Bildausschnitt (crop) genutzt werden kann und nicht etwa das Hintergrundbild der Gauge-Komponente zugeordnet wird. Das heißt, das Hintergrundbild beginnt immer an der oberen linken Ecke. Wenn Sie mehrere Zeiger-Instrumente auf einer Seite platzieren möchten, müssen Sie also ein (vollformatiges) Hintergrundbild mit mehreren Skalen erstellen und die einzelnen Gauge-Komponenten den jeweiligen Instrumenten im Bild überlagern. Das schränkt den Einsatz doch erheblich ein.
Außerdem gibt es einen Fehler: es lassen sich zwar unterschiedliche Werte für die Höhe und Breite eingeben, doch es wird immer ein Quadrat mit der Kantenlänge des zuletzt eingegebenen Wertes gezeichnet.
gauge0.val=90
oder get gauge0.val
Die Waveform-Komponente ist mit Abstand das aufwendigste Element. Der Hintergrund besteht aus einem Gitter, das an ein Oszilloskop erinnert. Die Rastergröße ist in x- und in y-Richtung wählbar. Maximal können 4 Kanäle dargestellt werden und es können maximal 4 Waveform-Komponenten pro Screen angelegt werden. Da einige Eigenschafte sich auf die Kanäle beziehen, ändert sich die Anzahl der Eigenschaften.
Die Auflösung ist immer pixelbezogen, also bei einem 3,2-Zoll-Display und einer formatfüllenden Waveform-Komponente beträgt die Darstellung im Querformat 400 Messpunkte in x-Richtung und 240 Messpunkte in y-Richtung.
Es gibt keine spezielle "val"-Größe, weil die Messwerte bei einem Oszilloskop hintereinander dargestellt werden (s. hierzu auch die speziellen add- und addt-Befehle zum Hinzufügen von Datenpunkten und den cle-Befehl zum Löschen der Daten eines Kanals.
Mit dem Schieberegler können Werte direkt über eine grafische Komponente verändert werden. In der Realität entspricht das einem Lautstärkeregler, einem Drehzahlsteller, einem Helligkeitsregler oder einem ähnlichen Eingabe-Element.
Der Schieberegler kann wieder in den bekannten Betriebsarten "solid color", "crop image" oder "image" für den Hintergrund (Bahn) und "solid" bzw. "image" für den Vordergrund (Knopf) betrieben werden, ausschlaggebend dafür sind die Einstellungen in "sta" (Hintergrund) und "psta" (Vordergrund).
Wenn Sie für beides eine Füllfarbe (solid color bzw. solid) gewählt haben, können Sie für den Schiebeknopf (pco) und die Schiebebahn (bco) wie gewöhnlich beliebige Farben wählen.
Sie können aber auch ganz realistische Effekte erzielen, wenn Sie bei "sta" und "psta" den Eintrag "image" wählen und dann z. B. 2 Bilder für den Knopf und die Bahn wählen. Für dieses Beispiel habe ich 2 ganz simple Grafiken erstellt:
Ich lade diese Bilder dann im Nextion-Editor in die Picture-Galerie und ordne sie dem Slider entsprechend zu. Das Ergebnis sieht schon recht realistisch aus. Sie können natürlich auch richtige Fotos wählen pder eine Skala hinzufügen:
slider0.val=20 oder get slider0.val
Technisch gesehen weist ein Taster ein monostabiles und ein Schalter ein bistabiles Verhalten auf. Ein Taster fällt ohne Betätigung wieder in den Ursprungszustand zurück, ein Schalter verbleibt in der jeweiligen Position. Beim Nextion wird dieses Prinzip nicht ganz konsequent durchgezogen. Im Gegensatz zum Umschalter (dual state button) hat der Taster (button) keine val-Eigenschaft, sondern löst lediglich Touch-Press- bzw. Touch-Release-Ereignisse aus. Letzteres tut auch der Umschalter, er verfügt aber über eine "val"-Eigenschaft, die bei einer Betätigung zwischen "0" und "1" wechselt. Gleichzeitig ändert sich auch das Aussehen, entweder farblich oder wie schon bekannt durch 2 Bilder. Wie der Button verfügt der Dual State Button auch über einen Text, der geändert werden kann.
Der Zustand eines Dual State Buttons ändert sich im Moment des Drückens, so wie es bei einem realen Schalter auch der Fall ist.
Außer als Schalter kann eine solche Komponente aber auch zum Darstellung von Zuständen genutzt werden, z. B. als LED. In diesem Fall wählen Sie z. B. das Bild einer dunklen LED für den Zustand "0" und eine hell leuchtende LED für den Zustand "1".
get switch0.val
oder led0.val=1
Eine Checkbox ist ein Kästchen, das der Anwender markieren kann. Informationstechnisch handelt es sich um nichts anderes als einen Schalter. Allerdings gibt es hier nur Optionen bezüglich der Farben für den Hinter- und Vordergrund, ein Bild kann hier nicht aktiviert werden.
Auch die Checkbox kann sowohl als Eingabe-Komponente wie auch als Ausgabe genutzt werden, um binäre Zuständer anzuzeigen.
cb0.val=1
, Eingabe: get cb0.val
Ein einzelner Radiobutton macht im Grunde keinen Sinn, denn der Name stammt von den sich gegeneinander verriegelten Auswahltasten beim Radio. Bei einer Auswahl aus Langwelle, Mittelwelle oder und Kurzwelle ist es sinnlos, wenn 2 oder mehrere Tasten gleichzeitig gedrückt werden können. Deshalb springt die aktuell aktivierte Taste heraus, wenn eine andere gedrückt wird.
Bei der GUI-Programmierung sieht das normalerweise ähnlich aus. Sie platzieren mehrere Radiobuttons und gruppieren diese. Der Verriegelungsmechanismus ist dann eine interne Funktion der Komponente. Beim Nextion sieht das (zumindest jetzt noch) anders aus, denn jeder Radiobutton ist für sich autonom. Damit gibt es aber keinen Unterschied zur Checkbox. Das heißt nicht so ganz, denn die Checkbox ist eckig, der Radiobutton mehr oder weniger rund. Außerdem verfügt die Checkbox über das "style"-Attribut, der Radiobutton nicht. Zugegeben, das sind eher nebensächliche Unterschiede.
rb0.val=1
, Eingabe: get rb0.val
Neben den visuellen Komponenten, die wir auf dem Nextion-Display sehen können, gibt es momentan noch 2 weitere, die im Hintergrund arbeiten, aber außerordentlich nützlich sind. Wenn Sie diese Komponenten anklicken, erscheinen Sie unter dem Hauptbildschirm unten links. Sie können mehrere unsichtbare Komponenten vom gleichen Typ wählen.
Variablen sind ganz elementare Komponenten, denn sie erlauben das Abspeichern von Informationen direkt im Nextion Device. Zusammen mit den Kontrollbefehlen ermöglichen Sie strukturierte Iterationen oder das Abspeichern von Zählerständen.
Was anfänglich häufig zu Fehlern führt, ist das Verständnis, dass es sich bei einer Nextion-Variablen nicht um die Variable selbst, sondern um ein Variablenobjekt handelt. Eine Zuweisung data1=10
ist somit falsch, denn das Objekt "data1" ist komplex und hat mehrere Attribute, von denen eins mal wieder die "val"-Eigenschaft ist. Richtig muss es also data1.val=10
heißen.
data1.val=20
oder data1.val="text"
oder get data1.val
Timer sind äußerst mächtige Objekte. Sie können damit wiederkehrende Aktionen durchführen oder auch definierte Pausen einlegen. Allerdings ist die Timer-Komponente beim Nextion-Display noch sehr rudimentär.
Sie eine Starttaste ("start"), einen Timer ("timer") und eine Checkbox ("led"). Nach dem Drücken der Starttaste soll die Checkbox (die ein LED repräsentieren soll) für genau 1 Sekunde markiert bleiben und danach wieder in den deaktiven Zustand wechseln. Sie geben für "tim" den Werte 1000 ein und setzen "en" auf 0.
Code für das Touch-Press-Event der Starttaste:
led.val=1
LED einschaltentimer.en=1
Timer starten
Code für das Timer-Event:
led.val=0
LED ausschaltentimer.en=0
Timer wieder ausschalten
Sie wollen den Bereich des Timers im obigen Beispiel mithilfe einer Variablen "min" von 65.535 ms auf 10 Minuten verlängern. Sie wählen dieses Mal für "tim" 60.000 (60 s) und setzen "en" wieder auf 0.
Code für das Touch-Press-Event der Starttaste:
wie oben
Code für das Timer-Event:
min.val++
Wenn min.val das 1. Mal inkrementiert wird, ist genau 1 Minute rumif(min.val==10)
{
timer.en=0
Wenn min.val==10 sind genau 10 Minuten rum und der Timer wird gestopptmin.val=0
Auch die Zählvariable muss wieder auf 0 gesetzt werden.}