GUI auf TFT Display

Hallo!

Ich möchte gerne eine GUI für meine Wetterstation auf mit meinem NodeMCU machen. Ich habe überhaupt keine Arduino Erfahrung, aber würde es einfach gerne selbst programmieren ohne ein Hilfsprogramm. Kann mir irgendjemand vielleicht sein Beispielprogramm mit Erklärung dazu zeigen?

Bisher bin ich bei dem Schritt, dass man auf das Display drückt und sich eine neue Seite öffnet. Wie kriege ich es z.B. hin, dass bei erneutem Drücken wieder die ursprüngliche bzw. Startseite dargestellt wird?

Danke im Vorraus für alle hilfreichen Antworten!

Im englischen Teil des Forum müssen die Beiträge und Diskussionen in englischer Sprache verfasst werden. Deswegen wurde diese Diskussion in den deutschen Teil des Forums verschoben.

mfg ein Moderator.

Welcher NodeMCU (ESP8266 oder ESP32)?
Im Einfachsten Fall macht man das mit einer Website auf dem ESP.

Ansonsten welches Display (Link bitte) und zeige uns Deinen bisherigen Sketch bitte ordentlich formatiert und in Codetags. Wie das geht, steht hier.

Gruß Tommy

Es ist ein ESP8266. Ich habe mittlerweile eine andere Möglichkeit gefunden, aber danke für die schnelle Rückmeldung!

Ich hätte aber noch eine andere Frage zu meinem Projekt😅
Wie kann ich die Messwerte aus meinem BME in einem Array speichern und diese als Diagram darstellen lassen? Es sollen die letzten 20 Werte gespeichert werden.
Sketch dazu kann ich noch nicht schicken, weil ich noch keine Idee hatte wie ich dieses Problem lösen kann.

LG

Informiere Dich mal zum Stichwort Ringpuffer, wenn Du das fortlaufend speichern willst. Ob und wie Du Grafik sinnvoll darstellen kannst, ist von Deinem Display abhängig.

Gruß Tommy

Hallo,
du willst das auf dem TFT machen.? Dann schau dir mal Beispiele dazu an. Es gibt bestimmt Methoden um ein Pixel zu setzen, oder einen linie von -bis zwischen den Messwerten zu zeichnen.

Um die Werte in ein Array zu bekommen musst Du halt einen Variable als Schreibzeiger und eine zweite als Lesezeiger führen. (Ringpuffer ) Wenn das Array dann voll ist gehts wieder vorne los.
Für eine Webseite wurde sowas hier im Forum mal als chart gemacht.
mir fehlt halt im Moment der Link dahin

Heinz
Nachtrag hier [gelöst] Fetch API mit Json - #15 by Rentner

Könntest du mir das mit dem Schreibzeiger und Lesezeiger erklären bzw. ein Beispielsktech zeigen ?

Hallo,
Du kannst mal nach Ringpuffer Googlen , oder in dem Link oben unter #26 Beispiel findest Du zwei functionen bei denen das verwendet wird.

Heinz

Hallo,
Fang doch erst mal damit an auf deinem Display eine Grafik anzuzeigen bei der feste Werte aus einem Array mit den 20 Werten angezeigt werden. Nutze erst mal Werte die auf die x,y Koordinaten des Displays passen. Umrechnen kannst du später machen.
Beispiel Display 128x64 Pixel
dann nimmst Du erst mal die x Positionen 0,5,10,15....95 macht 20 Werte
y Werte von 0-63.

Die Punkte kannst Du auf Deinem Display als Pixel zeichnen oder Linien zwischen den einzelnen Koordinaten zeichnen. line(x, y, x-+1, y+1) etwa so. Je nach Methode der verwendeten lib.
Ja das ist alles ein bisschen fummelig. Eventuell kann die Lib das aber auch schon irgendwie. Ich kenne das nur von einem 0,96" OLED Display , da hab ich so was mal gemacht, ziemlich mühselig.

Wenn das läuft denkst Du darüber nach wie Du die Werte des Sensors in das Array rein bekommst und was passiert wenn die 20 Werte alle drin sind.
Heinz

@Rentner hat recht, das GUI auf dem TFT ist vermutlich die größere Herausforderung...

Nichtsdestotrotz habe ich mal auf die Schnelle ein Beispiel geschrieben, mit dem man das Prinzip (hoffentlich) nachvollziehen kann:


const int MaxDaten = 5;  // Die Anzahl der Daten um eins höher als die gewünschte Menge setzen
                         // vereinfacht die Ringpufferverwaltung
int Daten[MaxDaten];
int SchreibePos = 0;
int LesePos     = 0;

void LesePosWeiter(){
      LesePos++;
      if (LesePos >= MaxDaten) LesePos = 0;
  }

void SchreibePosWeiter(){
      SchreibePos++;
      if (SchreibePos >= MaxDaten) SchreibePos = 0;
      if (SchreibePos == LesePos) LesePosWeiter();
  }


void SchreibeDatum(int Wert){
    Daten[SchreibePos] = Wert;
    Serial.println("Position "+String(SchreibePos)+" <- "+String(Wert));
    SchreibePosWeiter();
  }

int LeseDatum(){
    if (LesePos != SchreibePos) {
      Serial.println("Position "+String(LesePos)+" -> "+String(Daten[LesePos]));
      LesePosWeiter();
    } else {
      Serial.println("Keine weiteren Daten vorhanden!");
      }  
  }


void RingBufferAnwendung(){
    String line = "";
    char c;
    do 
      if (Serial.available()){
        c = Serial.read();
        if (c != '\r') line += c;
      }
    while (c != '\r');
    if (line.length() == 0) {
      LeseDatum();
    } else {
      SchreibeDatum(line.toInt());  
    }
 }


void setup() {
  // put your setup code here, to run once:
 Serial.begin(115200);
}

void loop() {
  // put your main code here, to run repeatedly:
  RingBufferAnwendung(); 
}
  1. Sketch auf ein Board laden

  2. Seriellen Monitor mit 115200 Baud starten

  3. Bedienung:

    • Zahlen eingeben, mit Return-Taste abschließen -> schreibt den Wert in die nächste Position des Ringpuffers
    • Return-Taste alleine eingeben -> gibt nach und nach solange Daten aus dem Ringpuffer aus, bis die aktuelle Schreibposition erreicht wird

Benötigt man x Daten, dann MaxDaten = x+1 Speicherplätze reservieren. Es werden nur die letzten (MaxDaten-1) Werte ausgegeben; theoretisch könnte man noch den letzten Wert "retten", so ist es aber am Einfachsten.

Im Beispiel sind es vier gewünschte Daten, daher MaxDaten = 5.

P.S.: Gibt man eine ungültige Zeichenfolge ein (z.B. Text), wird das als 0 gewertet.

Hallo,
ich hab da auch noch einen in der Bastelkiste gefunden und etwas angepasst.
jede Sekunde wird ein Wert in den Ringpuffer geschrieben. Es wird die nächste Schreibposition zurückgegeben. Alle 5s wird der gesamte Puffer ab der letzten Schreibposition im Ring auf dem Monitor ausgegeben. Das kannst Du aber auch mit jedem anderen Ereignis machen. Ausgegeben werden dann immer die letzten 20 Werte. Bei Dir müsste das dann wie in #9 angedacht auf Dein TFT "gezeichnet" werden. Wenn Du mit der Ausgabe links beginnst hast Du die zeitlich ältesten Werte links.
Zum Testen wird eine Zählervariable verwendet. Alternativ ein simulierter zufälliger Messwert um die 500.
Wenn Du die Messwerte eines BME280 verwenden willst musst Du eventuell den Ringpuffer als float anlegen , oder mit normierten Integern für die TFT Pixel arbeiten.

Heinz

/* Beispiel Ringpuffer
    Puffergrösse 20 Integer
    Ausgabe des gesamten Puffers auf Monitor
    lesen und schreiben mit unterschiedlichem Zyklus

*/

int puffer[20];
int messwert;
int anzahl = sizeof(puffer) / sizeof(puffer[0]);
int wzeiger;
uint32_t altzeit, altzeit2;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  Serial.println(anzahl);

}

void loop() {
  // put your main code here, to run repeatedly:

  if (millis() - altzeit > 1000) { // Puffer schreiben
    altzeit = millis();
    wzeiger = writepuffer(messwert);
    messwert = messwert + 1;
    //messwert = 500 + random(-100, 100);
  }
  if (millis() - altzeit2 > 5000) { // Puffer anzeigen
    altzeit2 = millis();
    readpuffer(wzeiger);
  }

}

uint16_t writepuffer( int wert) {
  static int wz;
  puffer[wz] = wert;
  Serial.print("schreibzeiger"); Serial.print(wz);
  Serial.print("  Wert "); Serial.println(wert);
  wz++;
  if (wz >= anzahl) {
    wz = 0;
  }
  return wz;
}

void readpuffer(int z) {
  int rz = 0;
  int wert;

  while (rz < anzahl) {
    z--;
    if (z < 0) z = anzahl - 1;
    wert = puffer[z];
    rz++;

    Serial.print(wert); Serial.print(";");
  }
  Serial.println();

}

Danke für eure schnellen Antworten!
Ich habe mir alles durchgelesen und auch selbst noch ein wenig recherchiert und bin zu einer relativ guten Lösung gekommen...

Nochmal danke, dass ihr euch so schnell die Zeit genommen habt und LG!

Armin

Möchtest Du mitteilen wie die aussieht?