Nextion Display Buttons

Guten Abend,

ich stehe gerade vor einem Problem und zwar:
Ich habe 3 Seiten auf meinem Display, die funktionieren soweit auch. Auf der ersten Seite sind Textfelder die ich fülle, das ohne Probleme. Auf der zweiten Seite sind DualStateButtons. Die bekomme ich aber nicht zum laufen.

Mein Problem habe ich schon herunter gebrochen:
Benutze ich den Beispielsketch (siehe unten) und die Beispiel TFT, funktioniert alles. Habe ich aber mehrere Seiten auf meinem Display, funktioniert dieser Code nicht mehr.
Kurz um: ist eine Seite auf dem Display klappt alles. Wird eine zweite hinzugefügt, funktioniert der Button nicht mehr.

Hat jemand mit so einem Problem Erfahrung?

Freue mich auf eine Rückmeldung.

#include "Nextion.h"

/*
 * Declare a dual state button object [page id:0,component id:1, component name: "bt0"]. 
 */
NexDSButton bt0 = NexDSButton(0, 1, "bt0");

NexText t0 = NexText(0, 2, "t0");


char buffer[100] = {0};

/*
 * Register a dual state button object to the touch event list.  
 */
NexTouch *nex_listen_list[] = 
{
    &bt0,
    NULL
};

/*
 * Dual state button component pop callback function. 
 * In this example,the button's text value will plus one every time when it is released. 
 */
void bt0PopCallback(void *ptr)
{
    uint32_t dual_state;
    NexDSButton *btn = (NexDSButton *)ptr;
    dbSerialPrintln("b0PopCallback");
    dbSerialPrint("ptr=");
    dbSerialPrintln((uint32_t)ptr); 
    memset(buffer, 0, sizeof(buffer));

    /* Get the state value of dual state button component . */
    bt0.getValue(&dual_state);
    if(dual_state) 
    {
        t0.setText("HI! OPEN STATE");
    }
    else
    {
        t0.setText("HI! OFF STATE");
    }
}

void setup(void)
{    
    /* Set the baudrate which is for debug and communicate with Nextion screen. */
    nexInit();

    /* Register the pop event callback function of the dual state button component. */
    bt0.attachPop(bt0PopCallback, &bt0);
    
    dbSerialPrintln("setup done"); 
}

void loop(void)
{   
    /*
     * When a pop or push event occured every time,
     * the corresponding component[right page id and component id] in touch event list will be asked.
     */
    nexLoop(nex_listen_list);
}

Hallo,
Du nutzt die "Nextion.h".
Hier im Forum ist die als Schrott angehaucht.
Versuche es doch einmal ohne- ist wesentlich einfacher und auch übersichtlicher.
Gruß und Spaß
Andreas

Sorry, aber Hilfe wird schwer.
Evtl. liegt der Fehler im Bildaufbau, den wir nicht kennen.
Ein weiteres Problem ist die Verwendung der Nextion-Library.
Die verwendet kaum einer, daher fehlt hier die Erfahrung.

Mh okay,
vielen Dank für eure Antworten. Das die Library unter die Kategorie "Schrott" zählt, habe ich ehrlich gesagt noch nicht gelesen... naja, dann werde ich mich vllt. doch auf dem manuellen Weg probieren.

Falls jemand aber für die Library eine Lösung hat, nur her mit :wink:

Schönen Abend euch!

Da hat sich wohl doch schon die erste Frage ergeben :wink:

Ich habe einfach mal das Software Serial Beispiel genommen um die Buttoneingabe zu erkennen.
Es kommt zwar was an aber nur so was hier: "e???".

Text in ein Textfeld bekomme ich aber über SoftwareSerial geschrieben.

Kann mir hier kurz jemand auf die Sprünge helfen?

#include <SoftwareSerial.h>

SoftwareSerial swSer(2, 12, false, 256);

void setup() {
  Serial.begin(9600);
  swSer.begin(9600);

  Serial.println("\nSoftware serial test started");


  swSer.println("");

}

void loop() {
  while (swSer.available() > 0) {
    Serial.write(swSer.read());
  }
  while (Serial.available() > 0) {
    swSer.write(Serial.read());
  }

}

Dann sieh dir doch mal an, was dein Button senden soll.

ich erwarte irgendwas in dieser Form. (Laut dem Instruction Set)

0x65 0x00 0x01 0x01 0xFF 0xFF 0xFF

0x00 sollte die Seite sein
0x01 sollte die ID sein
0x01 gedrückt
oder
0x00 los gelassen

Das passt doch zu deinem "Es kommt zwar was an aber nur so was hier: "e???".".

okay, und wie? ::slight_smile:

e ist 0x65, 0 ergibt keine Ausgabe, 1 ergibt keine Ausgabe, ? ist 0xFF.

Gib doch mal die numerischen Werte der empfangenen Daten aus und nicht nur deren Characterdarstellung.

Hi

ODER, gibt die Zeichen nur als Zeichen aus, wenn Diese >=32 und <=127 sind, wenn drunter oder drüber gibt's einen Punkt (.) und in eckigen Klammern dahinter den HEX-Wert.

        if (temp < 32 || temp > 127) {
          Serial.print(".[");
          if (temp < 0x10) Serial.print("0");
          Serial.print(temp, HEX);
          Serial.print("]");
        } else {
          Serial.write(temp);
        }

Hier ist das Zeichen in der Variable 'temp' enthalten.

MfG

Edit
.write gibt das Zeichen als Zeichen aus - eine 48 wird als 0 (Null) ausgegeben, da die Null das ASCII-Zeichen 48(DEZ) ist.
Bei .print wird die Übergabe 'interpretiert' - also eine 1023 wird als Zahl gesehen und ziffernweise ausgegeben - hierbei kann man dann auch noch angeben, ob man BIN, OCT, DEZ, HEX haben will.

okay, verstanden :wink:

in dem Bereich habe ich nur absolut keine Erfahrung...(deshalb wollte ich es erst mit der Lib machen...)
Wie gebe ich denn den numerischen Wert aus?

byte data[] = { 0x65, 0x00, 0x01, 0x01, 0xFF, 0xFF, 0xFF, };

void setup() {
  Serial.begin(250000);
  Serial.print(F("als Text \""));
  for (char c : data) {
    Serial.write(c);
  }
  Serial.println(F("\""));
  dump(data, sizeof(data));
}

void loop() {}

void dump(const void* ptr, int len) {
  const byte* adr = (const byte*) ptr;
  byte idx;
  if (len) {
    for (; len > 0; len -= 16, adr += 16) {
      for (idx = 0; (idx < 16) && (idx < len); idx++) {
        phByte(adr[idx]);
        Serial.write(' ');
      }
      Serial.write('"');
      for (idx = 0; (idx < 16) && (idx < len); idx++) {
        Serial.write(adr[idx] < 0x20 ? '.' : adr[idx]);
      }
      Serial.write('"');
      Serial.println();
    }
  }
}

void phByte(byte byt) {
  if (byt < 16) {
    Serial.write('0');
  }
  Serial.print(byt, HEX);
}
als Text "e   ⸮⸮⸮"
65 00 01 01 FF FF FF "e...⸮⸮⸮"

Vielen, vielen Dank!

Das werde ich mir dann wohl morgen zu Gemüte führen müssen.

ähm, moment kurz. Das brauch ich nicht morgen anschauen... Ich verstehe da nur noch Bahnhof...ich möchte doch mein "e???" in was vernünftiges bekommen?
Das heißt, das was rein kommt, will ich in numerische Werte haben?!

Macht der Code nicht aus dem byte data wieder das "e???"?

Mein Kode ändert nichts an den Daten, er gibt die Daten nur auf verschiedene Arten aus.

Für den Empfang der Nextion Daten habe ich mal eine Klasse gebastelt,
hier ein Beispiel für ein Nextion an Serial1.

#include <WhandallSerial.h>  // https://github.com/whandall/WhandallSerial

// simple handler just prints some infos about the received line

void processLine(const char* buf) {
  Serial.print(F("len = "));
  Serial.print((uint8_t)buf[-1]);
  Serial.print(F(", strlen = "));
  Serial.print(strlen(buf));
  Serial.print(F(", "));
  dump(buf, buf[-1]);
}

void processConsoleLine(const char* buf) {
  Serial.print(F("sent \""));
  Serial.print(buf);
  Serial.println(F("\""));
  Serial1.print(buf);
  Serial1.write(0xFF);
  Serial1.write(0xFF);
  Serial1.write(0xFF);
}

SSerial console(Serial, processConsoleLine); // used serial and handler
SSerial nextionSerial(Serial1, processLine); // used serial and handler

void setup() {
  Serial.begin(250000);
  console.begin(64, optIgnoreLF); // buffer size and options
  Serial1.begin(115200);
  nextionSerial.begin(64, optTripleFF | optKeepDlm); // buffer size and options
}

void loop() {
  console.loop();         // collect chars and call handler for each line
  nextionSerial.loop();   // collect chars and call handler for each line
}

void dump(const void* ptr, int len) {
  const byte* adr = (const byte*) ptr;
  byte idx;
  if (len) {
    for (; len > 0; len -= 16, adr += 16) {
      for (idx = 0; (idx < 16) && (idx < len); idx++) {
        phByte(adr[idx]);
        Serial.write(' ');
      }
      Serial.write('"');
      for (idx = 0; (idx < 16) && (idx < len); idx++) {
        Serial.write(adr[idx] < 0x20 ? '.' : adr[idx]);
      }
      Serial.write('"');
      Serial.println();
    }
  }
}

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

Welche Pins sind in dieser Library RX und TX?
(Benutzen ein WemosD1mini Board)

Ich benutze die normalen Serial Serial1 ... Objekte,
wie du denen auf deinem ESP die Pins zuweisen kannst, kann ich dir nicht sagen.

Eigentlich musst du doch nichts ändern, vorher hast du Serialx behandelt,
jetzt macht das eine Klasse und ruft dich auf, wenn eine Zeile vollständig ist.

Verbunden wird die Klasse mit dem Objekt im Konstruktor,
im Beispiel für zwei Schnittstellen mit unterschiedlichem Format.

SSerial console(Serial, processConsoleLine); // used serial and handler
SSerial nextionSerial(Serial1, processLine);

  console.begin(64, optIgnoreLF); // buffer size and options
  nextionSerial.begin(64, optTripleFF | optKeepDlm); // buffer size and options

Die Konfiguration der Schnittstelle, begin und open werden von der Library nicht benutzt,
lediglich available und read.

verstehe ich das richtig? Du nutzt die „normalen“ RX und TX Pins?

Das hat ja aber zur Folge, dass ich auf dem serial Monitor keine Ausgaben erzeugen kann?!

Wenn du das Nextion da anklemmst ist das auch zu erwarten.
Selbst mein Beispielprogramm nutzt zwei Schnittstellen,
eine für die Konsole eine für das Nextion.

Das Arduino Framework benutzt für die Seriellen Objekte welche Pins auch immer,
meine Library benutz nur die fertigen Objekte.

Ich fürchte ich kann das nicht besser erklären als ich es schon getan habe.

Was leuchtet dir daran nicht ein, dass meine Library sich nicht für Pins interessiert?