Serial liefert Zeichen…

Was du mit deinem Eingriff gemacht hast, ist auch leere Zeilen empfangen zu können.

Die Eingaberoutine ist unbrauchbar für das Nextion, weil dieses keine CR/LF als Zeilentrenner benutzt.
Es benutzt nicht einmal immer drei 0xFF, viele Befehle geben auch einfach 4 Bytes zurück, mit binärem Inhalt.

Hallo,
"Es benutzt nicht einmal immer drei 0xFF, viele Befehle geben auch einfach 4 Bytes zurück, mit binärem Inhalt."

Ja, und? Darum geht es doch überhaupt nicht.

"Die Eingaberoutine ist unbrauchbar für das Nextion, weil dieses keine CR/LF als Zeilentrenner benutzt."

Ja, und? Liest Du auch mal aufmerksam mit?
Ich gebe nichts ein, und ich sende nichts an das Nextion?

Ich löse mit einem Hotspot auf dem Nextion ein Event aus.
Eben- print "\r".
*Das- "\r" sendet das Nextion an den Arduino.

Das wird vom Arduino ausgewertet und verarbeitet.
Gruß und Spaß
Andreas

  • last edit- damit es klarer wird

Dir ist nicht zu helfen. Bye.

Hallo Whandall,
ich bin wieder runtergekommen, Du auch?
Gruß
Andreas

Nachdem mein Nextion anfangs etwas zickte, benimmt es sich jetzt dokumentationsgemäß.

In die Nextion Library habe ich mal einen Blick geworfen und mich dann mit Grausen abgewendet.
Das geht mit Sicherheit viel besser (ohne Strings, mit F(), ohne delay(), ohne blockierende whiles).
Der Kode ist so gruselig, dass man das am Besten ganz neu schreibt.

Hier ein Programm mit dem man dem Nextion genau auf die Finger sehen kann.
Der eingetippte Text wird an das Nextion weitergegeben (mit den drei 0xFF).

Ich hatte keine Probleme mit irgenwelchen -1en. :wink:

SSerial.h und SSerial.cpp musste ich wegen der 9000 Zeichen anhängen.

Vorn steht woher die Nachricht kam, in den eckigen Klammern die Länge der Nachricht,
gefolgt von ihrem Text (wenn sie nicht binär ist), oder ihrem Dump.

Serial(250000) + 3 0xFF -> Nextion(9600) on Serial2
con: [0A] 'get t0.txt'
 in: [0A] 70 32 33 34 2C 33 34 FF FF FF string
con: [09] 'get bkcmd'
 in: [08] 71 03 00 00 00 FF FF FF number
con: [08] 'c0.val=1'
 in: [04] 01 FF FF FF OK
con: [0A] 'get c0.val'
 in: [08] 71 01 00 00 00 FF FF FF number
#include <SSerial.h>

void conHandler(const char* buf);
void nxiHandler(const char* buf);

SSerial Con(Serial, conHandler);
SSerial Nxi(Serial2, nxiHandler);

void setup() {
  Con.begin(64, optEmptyToo | optIgnoreLF);
  Nxi.begin(64, optTripleFF | optKeepDlm);
  Serial.begin(250000);
  Serial2.begin(9600);
  Serial.println(F("Serial(250000) + 3 0xFF -> Nextion(9600) on Serial2"));
  //testDecoder();
}

void loop() {
  Con.loop();
  Nxi.loop();
}

void testDecoder() {
  for (int i = 0; i < 256; i++) {
    if (interpretRetHeadByte(i)) {
      Serial.print(F(" = 0x"));
      printHex(i);
      Serial.println();
    }
  }
}

void conHandler(const char* buf) {
  report(PSTR("con"), (const byte*)buf);
  Serial2.print(buf);
  Serial2.write(0xFF);
  Serial2.write(0xFF);
  Serial2.write(0xFF);
}

void nxiHandler(const char* buf) {
  report(PSTR(" in"), (const byte*)buf);
}

void report(const char* on, const byte* buf) {
  Serial.print((__FlashStringHelper*)on);
  Serial.print(F(": ["));
  byte trueLen = buf[-1];
  printHex(trueLen);
  Serial.print(F("]"));
  byte len = strlen((const char*)buf);
  if (len != trueLen || NULL != memchr(buf, 0xFF, trueLen)) {
    for (byte x = 0; x < buf[-1]; x++) {
      Serial.write(' ');
      printHex(buf[x]);
    }
  } else {
    Serial.print(F(" '"));
    Serial.print((const char*)buf);
    Serial.print(F("'"));
  }
  if (trueLen >= 4 && buf[trueLen - 3] == 0xFF && buf[trueLen - 2] == 0xFF && buf[trueLen - 1] == 0xFF) {
    Serial.write(' ');
    interpretRetHeadByte(buf[0]);
  }
  Serial.println();
}

void printHex(byte inB) {
  if (inB < 16) {
    Serial.write('0');
  }
  Serial.print(inB, HEX);
}

void printDec2(byte inB) {
  if (inB < 10) {
    Serial.write(' ');
  }
  Serial.print(inB);
}

// Nextion special

#define NEX_RET_INVALID_CMD             (0x00)
#define NEX_RET_CMD_FINISHED            (0x01)
#define NEX_RET_INVALID_COMPONENT_ID    (0x02)
#define NEX_RET_INVALID_PAGE_ID         (0x03)
#define NEX_RET_INVALID_PICTURE_ID      (0x04)
#define NEX_RET_INVALID_FONT_ID         (0x05)
#define NEX_RET_INVALID_BAUD            (0x11)
#define NEX_RET_INVALID_CURVE           (0x12)
#define NEX_RET_INVALID_VARIABLE        (0x1A)
#define NEX_RET_INVALID_OPERATION       (0x1B)
#define NEX_RET_INVALID_ASSIGN          (0x1C)
#define NEX_RET_EEPROM_FAILED           (0x1D)
#define NEX_RET_PARM_QUANTITY           (0x1E)
#define NEX_RET_IO_FAILED               (0x1F)
#define NEX_RET_BAD_ESCAPE              (0x20)
#define NEX_RET_TOO_LONG_VAR            (0x23)
#define NEX_RET_EVENT_TOUCH_HEAD            (0x65)
#define NEX_RET_CURRENT_PAGE_ID_HEAD        (0x66)
#define NEX_RET_EVENT_POSITION_HEAD         (0x67)
#define NEX_RET_EVENT_SLEEP_POSITION_HEAD   (0x68)
#define NEX_RET_STRING_HEAD                 (0x70)
#define NEX_RET_NUMBER_HEAD                 (0x71)
#define NEX_RET_EVENT_SLEEP             (0x86)
#define NEX_RET_EVENT_WAKE_UP           (0x87)
#define NEX_RET_EVENT_LAUNCHED          (0x88)
#define NEX_RET_EVENT_UPGRADED          (0x89)
#define NEX_RET_TRANS_DONE              (0xFD)
#define NEX_RET_TRANS_READY             (0xFE)

const char PROGMEM pmsOk[] = "OK";
const char PROGMEM pmsId[] = "id";
const char PROGMEM pmsEvt[] = "event";
const char PROGMEM pmsLau[] = "launched";
const char PROGMEM pmsUpg[] = "upgraded";
const char PROGMEM pmsTou[] = "touch";
const char PROGMEM pmsPos[] = "position";
const char PROGMEM pmsSle[] = "sleep";
const char PROGMEM pmsPag[] = "page";
const char PROGMEM pmsStr[] = "string";
const char PROGMEM pmsNum[] = "number";
const char PROGMEM pmsInv[] = "invalid";
const char PROGMEM pmsCmd[] = "cmd";
const char PROGMEM pmsCom[] = "component";
const char PROGMEM pmsPic[] = "picture";
const char PROGMEM pmsFon[] = "font";
const char PROGMEM pmsBau[] = "baud";
const char PROGMEM pmsVar[] = "variable";
const char PROGMEM pmsOpe[] = "operation";
const char PROGMEM pmsCur[] = "curve";
const char PROGMEM pmsAss[] = "assignment";
const char PROGMEM pmsEep[] = "EEPROM";
const char PROGMEM pmsFai[] = "failed";
const char PROGMEM pmsIo[] = "I/O";
const char PROGMEM pmsBad[] = "bad";
const char PROGMEM pmsEsc[] = "escape";
const char PROGMEM pmsWup[] = "wake-up";
const char PROGMEM pmsTra[] = "transparent";
const char PROGMEM pmsDon[] = "done";
const char PROGMEM pmsRdy[] = "ready";
const char PROGMEM pmsToo[] = "too";
const char PROGMEM pmsLng[] = "long";


void twoWithBlank(const char* first, const char* second) {
  Serial.print((__FlashStringHelper*)first);
  Serial.write(' ');
  Serial.print((__FlashStringHelper*)second);
}

void threeWithBlank(const char* first, const char* second, const char* third) {
  twoWithBlank(first, second);
  Serial.write(' ');
  Serial.print((__FlashStringHelper*)third);
}

bool interpretRetHeadByte(byte deco) {
  switch (deco) {
    case NEX_RET_CMD_FINISHED:
      Serial.print((__FlashStringHelper*)pmsOk);
      break;
    case NEX_RET_EVENT_LAUNCHED:
      twoWithBlank(pmsEvt, pmsLau);
      break;
    case NEX_RET_EVENT_UPGRADED:
      twoWithBlank(pmsEvt, pmsUpg);
      break;
    case NEX_RET_EVENT_TOUCH_HEAD:
      Serial.print((__FlashStringHelper*)pmsTou);
      break;
    case NEX_RET_EVENT_POSITION_HEAD:
      Serial.print((__FlashStringHelper*)pmsPos);
      break;
    case NEX_RET_EVENT_SLEEP_POSITION_HEAD:
      twoWithBlank(pmsSle, pmsPos);
      break;
    case NEX_RET_CURRENT_PAGE_ID_HEAD:
      twoWithBlank(pmsPag, pmsId);
      break;
    case NEX_RET_STRING_HEAD:
      Serial.print((__FlashStringHelper*)pmsStr);
      break;
    case NEX_RET_NUMBER_HEAD:
      Serial.print((__FlashStringHelper*)pmsNum);
      break;
    case NEX_RET_INVALID_CMD:
      twoWithBlank(pmsInv, pmsCmd);
      break;
    case NEX_RET_INVALID_COMPONENT_ID:
      twoWithBlank(pmsInv, pmsCom);
      break;
    case NEX_RET_INVALID_PAGE_ID:
      twoWithBlank(pmsInv, pmsPag);
      break;
    case NEX_RET_INVALID_PICTURE_ID:
      twoWithBlank(pmsInv, pmsPic);
      break;
    case NEX_RET_INVALID_FONT_ID:
      twoWithBlank(pmsInv, pmsFon);
      break;
    case NEX_RET_INVALID_BAUD:
      twoWithBlank(pmsInv, pmsBau);
      break;
    case NEX_RET_INVALID_VARIABLE:
      twoWithBlank(pmsInv, pmsVar);
      break;
    case NEX_RET_INVALID_OPERATION:
      twoWithBlank(pmsInv, pmsOpe);
      break;
    case NEX_RET_INVALID_CURVE:
      twoWithBlank(pmsInv, pmsCur);
      break;
    case NEX_RET_INVALID_ASSIGN:
      twoWithBlank(pmsInv, pmsAss);
      break;
    case NEX_RET_EEPROM_FAILED:
      twoWithBlank(pmsEep, pmsFai);
      break;
    case NEX_RET_IO_FAILED:
      twoWithBlank(pmsIo, pmsFai);
      break;
    case NEX_RET_BAD_ESCAPE:
      twoWithBlank(pmsBad, pmsEsc);
      break;
    case NEX_RET_TOO_LONG_VAR:
      threeWithBlank(pmsVar, pmsToo, pmsLng);
      break;
    case NEX_RET_EVENT_SLEEP:
      twoWithBlank(pmsEvt, pmsSle);
      break;
    case NEX_RET_EVENT_WAKE_UP:
      twoWithBlank(pmsEvt, pmsWup);
      break;
    case NEX_RET_TRANS_DONE:
      threeWithBlank(pmsEvt, pmsTra, pmsDon);
      break;
    case NEX_RET_TRANS_READY:
      threeWithBlank(pmsEvt, pmsTra, pmsRdy);
      break;
    default:
      return false;
  }
  return true;
}

SSerial.h (758 Bytes)

SSerial.cpp (1.96 KB)

Hallo Whandall,
ist ja kein Wunder, das wir uns in die Plünnen kriegen…
Nextion.h und SSerial.h nutze ich nicht.

"In die Nextion Library habe ich mal einen Blick geworfen und mich dann mit Grausen abgewendet."

Da sind wir schon zwei.

Mal ganz leise…
Ist ja nett von Dir, das Du Dir die Mühe gemacht hast, einen Sketch für das
Nextion zu schreiben, aber-
Zum einem verstehen das nur die Profis- zum anderem, es geht hier nicht darum
Text zum Nextion zu senden. Es geht darum Text vom Nextion zu empfangen.

Arduino ist TextEmpfänger <-> Nextion ist TextSender- alles ohne Library´s

Das ist meine Grundlage (von Serenifly) zum Empfangen auf dem Arduino:

Warum das,

(c == '\r' && c == '\n')

funktioniert hatte ich ja, meiner Meinung nach, "richtig" (#19) erklärt.

Dann ist eingeworfen worden, das es eigentlich nicht- funktionieren kann.
Eine Begründung gab es aber nicht.

Wenn das Nextion etwas senden soll, dann werden vom Nextion eigentlich
keine Escape-Sequenzen angenommen.
Es kommt im Nextion zur Fehlermeldung:
Error: Improper use of escape characters print "\n"… blah, blah

Die üblichen Steuerzeichen sind:

\0 0x00
\a 0x07
\b 0x08
\f 0x0C
\n 0x0A
\r 0x0D *
\t 0x09
\v 0x0B
\\ 0x5C *
\" 0x22 *
\' 0x27

Die mit * markierten rufen im Nextion keine FehlerMeldung auf.
Im Nextion löse ich ein Event aus, das folgendes Kommando ausführt:

print "Test"
print "\r"

Die Ausgabe des Nextion ist:

0x54 0x65 0x73 0x74 0x0D 0x0A

das wird vom Arduino beim Empfang durch

else if ((c == '\n' || c == '\r') || (c == '\r' && c == '\n') && index > 0)

ohne Fehler angenommen. Hatten wir ja schon.
Wenn man aber das SteuerZeichen \r sendet, dann sollte beim Empfänger aber
nur 0x0D ankommen.
Dem ist beim Nextion aber nicht so- es liefert 0x0D 0x0A
Sendet man mit dem Nextion also durch print "\r" wird 0x0D 0x0A ausgegeben.
Das ist eigentlich falsch?

Sendet man mit dem Nextion also durch print "\" wird 0x5C ausgegeben.
Das ist richtig

Sendet man mit dem Nextion also durch print """ wird 0x22 ausgegeben.
Das ist richtig.

Der Arduino verarbeitet und wertet richtig aus:

else if ((c == '\n' || c == '\r') || (c == '\r' && c == '\n') && index > 0)

Hier gibt der Arduino keine FehlerMeldung, wertet aber auch nicht aus

else if ((c == '\n' || c == '\r' || c == '\\') || (c == '\r' && c == '\n') && index > 0)
else if ((c == '\n' || c == '\r' || c == '\\') && index > 0)

Hier gibt der Arduino eine FehlerMeldung

else if ((c == '\n' || c == '\r' || c == '\"') || (c == '\r' && c == '\n') && index > 0)
else if ((c == '\n' || c == '\r' || c == '\"') && index > 0)

Ich bin damit durch, bei mir funktioniert es wie es soll. Das Nextion hat einige Eigenheiten die so einfach wohl nicht zu verstehen sind. Mal sehen was als nächstes kommt.
Also, vielen Dank für Eure Mühe.
Gruß und Spaß
Andreas

P.S.
"Ich hatte keine Probleme mit irgenwelchen -1en"
Die reproduziere ich noch einmal...

Ich benutze keine Nextion.h.

Die SSerial ist von mir und kann entweder mit normalen Zeilen oder binären Daten umgehen,
das veranschaulicht mein Programm.

Du mischst mit deinen prints 'normale' Kommunikation mit der binären Nextion Kommunikation,
die nach wie vor doch wohl stattfindet, auch in Richtung zum Arduino, oder?

Das wird nicht gut funktionieren.

Das natürliche Protokoll der Nextions zu unterstützen ist zunächst mein erstes Ziel,
künstlich ein anderes Protokoll via Aktionen und print zu erzeugen empfinde ich als merkwürdig,
zu merkürdig um mich für Fehler zu interessieren die bei diesem Mischbetrieb anscheinend auftreten,
ehe ich das eingebaute Protokoll vollständig verstehe.

Wenn ich (wie beim Nextion Protokoll geplant) den Klick-Event an den Arduino schicke,
ist der einfacher zu erkennen als ein Text den ich von da aus sende.
Warum sollte man sich Mühe machen um sich das Leben schwerer zu machen?

Hallo,
"Du mischst mit deinen prints 'normale' Kommunikation mit der binären Nextion Kommunikation,
die nach wie vor doch wohl stattfindet, auch in Richtung zum Arduino, oder?"

Das funktioniert ja...

"Das natürliche Protokoll der Nextions zu unterstützen ist zunächst mein erstes Ziel"

Jetzt komme ich langsam dahinter, was Du willst.

Diese SteuerzeichenGeschichte beim Nextion geht mir auch schon langsam auf den Zwickel.
Vielleicht sollte man sich wirklich an den NextionStandart halten.
Dann hört auch dieser "TurmBau zu Babel" auf.

Gruß und Dank
Andreas

Man muss nicht - wie Nextion - mit Objekten für jedes Element arbeiten,
du könntest mein obiges Programm zum Testen oder Teile davon als Grundlage für etwas anderes nehmen.

SSerial ist wirklich flexibel, wenn auch noch nicht dokumentiert.

Ich schreibe vor den Buffer in dem gesammelt wird, die Länge, damit kann man mit einem Pointer auch binäre Daten verarbeiten.

Hallo,
ich habe es im Nextion geändert…
vorher

print „MeinVergleichsText"
print „\r"

diese \r liefert an den Arduino ja 0x0D 0x0A (CR LF)
das lies sich aber nicht mit

else if ((c == '\n' || c == '\r') && index > 0)

abfangen. ich habe es dann geändert in

else if ((c == '\n' || c == '\r') || (c == '\r' && c == '\n') && index > 0)

das funktionierte einwandfrei- aber ein Aufschrei ging durch den Beitrag.
Da hier einige begründete Einwände kamen, und ich mit der Lösung auch nicht
so glücklich war, habe ich einmal die Profis gefragt.

\r wird vom Nextion unterstützt
die Ausgabe 0x0D 0x0A wird vom Nextion nicht unterstützt
\r wird vom Nextion als 2 Bytes gesehen 0x5C 0x72

also muß dieses \r aus dem Event entfernt werden.

Und es gibt eine ganz einfache Lösung um gesendeten Text vom Nextion zu
terminieren- so, das der Arduino es auch versteht.

print „MeinVergleichsText"
printh 0A

oder

print „MeinVergleichsText"
printh 0D

mit printh sendet das Nextion HEX. 0A ist LF und 0D ist CR.

und jetzt kann der Arduino mit

else if ((c == '\n' || c == '\r') && index > 0)

das auch vernünftig bearbeiten und auswerten.

Gruß und Spaß
Andreas

Hallo Whandall,
erst einmal vielen Dank für Deine Mühe.
Im Grunde genommen ist das eine ziemliche EierLegendeWollMilchSau, die jede
Ausgabe des Nextion dokumentiert.

Was an dem Ding besonders interessant ist, das es auch FehlerCode des Nextion
auswertet.

Ob ich- das aber nutzen kann/will weiß ich noch nicht. Mir gefallen Library´s
nicht so.
Und Teile davon? Ich weiß nicht, ob ich das richtig zerlegen kann. Ich habe es
mir aber kopiert und wechgespeichert. Wenn ich mit dem Nextion mal richtig
auf dem Schlauch stehe, dann hole ich es mal hervor.
Ich habe hier noch eine Baustelle mit meinen 48 Werten. Die muß langsam mal
vom Tisch.
Vielen Dank für Deine Mühe und Hilfe.
Gruß und Spaß
Andreas

Die Anzeige der Fehler/Meldungen und Events nimmt den meisten Platz ein.

Das Sammeln und Aufrufen der Aktionsroutine bei empfangenem Datagramm (binär oder CR/LF)
überlasse ich gerne ausgetestetem Kode (der sich dann in einen Library wohlfühlt).

Viele verfügbare Libraries sind fehlerhaft, ineffizient, oder - wie im Fall der Nextion Library -
völlig ohne Verständnis für asynchrone Kommunikation auf einem Single Thread System.

Ich werde also eine neue Library für das Nextion machen, die Wunschliste ist geöffnet. :wink:

Wie würdest du das Display denn am liebsten benutzen?

(Ich stehe auf Eventroutinen, die wird es also an allen Ecken geben).

SkobyMobil:
Nun habe ich mit einem Terminal Programm mal überprüft, was denn tatsächlich
gesendet wird.

Nach "MeinVergleichsText" sendet das Nextion 0x0D 0x0A

und dann zieht

else if ((c == '\n' || c == '\r') && index > 0)

nicht mehr.

Du hast nicht verstanden was der Code macht. Das einzelne LF wird natürlich erkannt. Es wird aus dem Puffer entfernt und dann greift "index > 0" und die Funktion liefert ingesamt false zurück, weil der String leer ist. Also wird nichts ausgewertet

Das ist nicht 100%ig sauber, aber CR+LF geht

Du hast das geändert mit einer Bedingung die die nichts anderes macht weil die neue Teil-Bedingung niemals wahr sein kann. Wenn es da zu einer Verhaltensänderung kam liegt der Grund woanders

Hallo,
das haben wir ja hier alles gebetsmühlenartig rauf und runter gebetet. Sollte wohl auch der letzte
begriffen haben.
Der Drops ist gelutscht.

Aber
"Das ist nicht 100%ig sauber"

wie macht man das

else if ((c == '\n' || c == '\r') && index > 0)

denn "sauber"?
Gruß und Dank
Andreas

Whandall:
Wie würdest du das Display denn am liebsten benutzen?

Keine Antwort ist auch eine Antwort.

Wenn du keine Wünsche hat, auch gut.

Hallo,
drehe mal nicht durch hier, bin gerade dabei...

Hallo,
die meisten, die da ranrobben, sind Anfänger- die auf keinen Fall etwas lesen
wollen- oder sich sonst damit beschäftigen wollen.
Also muß das leicht zu handhaben sein.

Erste Bedingung-
es muß zwingend ein Nextion richtig angeschlossen sein.

Dann
#include "HMINextion.h"

hier die Pin des Anwender, an denen er das Nextion angehängt hat

#define HMINextionTx 9
#define HMINextionRx 10

die TX-Leitung des Nextion auf 9, die RX auf 10

dann die gleichen Ausdrücke wie beim Arduino.

HMINextion.begin(9600);

Jetzt muß Deine Lib selbständig prüfen ob ein Nextion angeschlossen ist,
wenn nicht angeschlossen, Fehler melden.

Gruß und Spaß
Andreas

Software Serial werde ich nicht einbauen,
die Pins gehören nicht in die Library für das Nextion, sondern in das Stream Objekt.

Das begin könnte man durchaus aus dem Library begin aufrufen.

Hallo,
"die Pins gehören nicht in die Library für das Nextion, sondern in das Stream Objekt"

Es ist nicht die Aufgabe des "Wünschenden" zu wissen, was- wie programmiert werden muß.
Wenn Du das vorraussetzt, dann braucht hier keiner Wünsche zu äußern...
Aber ich sehe schon, Du möchtest etwas leichtes...

Also, Ausdrücke wie beim Arduino...

HMINextion.print,0,7("4711");

0 ist die Seite, 7 die ID der Komponente.
Ob dieser oder andere Werte die Eigenschaften der Komponente, mit der ID 7, erfüllen- muß Deine Lib
entscheiden können.

Mir fällt so auf Anhieb wirklich nichts ein, warum oder wozu ich bei dem Nextion eine Lib nutzen sollte.
Ich kann das also nur allgemein vorschlagen.
Was aber auffällt, die Leute haben massive Probleme mit der Übergabe- Annahme von Werten.
Ich habe erst zwei "ah-ha" NextionAnwendungen gesehen, die eine im USA-Forum, die andere bei mir.
Das meiste, was Du auf dem Nextion siehst ist pillepalle. Das fängt schon bei den Grafiken an.

Aber wenn Du für das Nextion eine Lib schreiben willst, dann mache es den Leuten einfach-
das Nextion zu nutzen- so, das der Anwender ohne kryptische Ausdrücke und Parameter auskommt.
Gruß und Spaß
Andreas

SkobyMobil:
"die Pins gehören nicht in die Library für das Nextion, sondern in das Stream Objekt"

Aber ich sehe schon, Du möchtest etwas leichtes...

Dann sind wir ja schon fertig.

Du verstehst nicht einmal, dass das mit leicht oder schwer nichts zu tun hat.

Hallo "Whandall",

da ich auch ein Nextion nutze würde ich mich sehr über eine gute "lib" dazu freuen.
Ich werde gespannt auf Deine Arbeit warten.

Danke

Hannes