Menüproblem 2 Ebenen mit Editfunktion und 80x160 RGB Display

Ich habe viele Beispiele gesucht, das Forum durchwühlt und sogar ChatGPT gefragt, aber zu meinem Bedarf habe ich nicht wirklich eine funktionierende Lösung gefunden. Ich bin kein Programmierprofi, aber Anfänger auch keiner mehr... Also habe ich versucht mir das slebst zu programmieren, habe aber einen Fehler, an dem ich mir seit 2 Wochen die Zähne ausbeisse und nicht weiter komme - und bitte daher um HILFE ;-)

Was ich brauche:
Ein Menü mit 2 Seiten.
Erstes Menü hat 2 Menüpunkte ohne Editfunktion. Wähle ich Menüpunkt 1, springt man in eine Menüseite wo ich einen RTC einstellen kann (Editfunktion). Menüpunkt 2 springt ins nächste Menü mit 4 Einträgen (ohne Editfunktion). Jeder Eintrag führt auf die letzte Menüseite mit einem mehrzeiligen Untermenü in dem ich jeden Menüpunkt editieren möchte (ON/OFF, heiss/kalt, Wert einstellen 1-10 usw. und das Ganze im EEPROM speichern. Wenn jemand ein funktionierendes Beispiel dafür für mein 80x160 RGB Display hat wäre SUUUPER!

Das Problem:
Ich habe mein Menü auf das notwendigste reduziert um es hier posten zu können. Es macht prinzipjell was es machen soll (ein BUG bei der Tasterauswertung ist trotzdem vorhanden, interessierrt hier aber nicht). Menü1 hat 2 Einträge, man kann damit zu Menü2 springen und mit EXIT vom Menü 2 zu Menü 1 zurückkehren. Ist man im Menü2 kann ich 2 Werte die zu den 2 Einträgen gehören ON/OFF umschalten und speichern. Soweit OK. Wenn beide Einträge auf ON stehen und ich vom Menü1 ins Menü2 springe, wird der erste Eintrag auf OFF umgestellt und gespeichert. Genau DAS darf nicht passieren.

Ich habe den Wert MenuPage den ich als Seite definiere, beim Schalten mit dem Button (BTN_SELECT) mit Serial.printLn(menuPage) überprüft und bekomme unsinnige Ergebnisse. Nach dem Drücken ist menuPage = 0, beim nächsten Drücken springt menuPage auf 1 und erst nach weiterem Drücken von (BTN_SELECT) geht menuPage auf 2. Dann funktionier auch die Menüseite 2. Warum geht manuPage auf NULL obwohl das nirgends deiniert wird??? Oder wie kann ich dieses Phenomen beheben?

Bzw. wie bekomme ich die Menüstruktur so hin, wie ich sie brauche?

[code]
#include <UTFT.h>
#include <EEPROM.h>

// Declare which fonts we will be using
extern uint8_t SmallFont[];
extern uint8_t BigFont[];
// Initialize display
//SDI=11  SCL=12  /CS =10  /RST=8  D/C=9
UTFT myGLCD(ST7735S_4L_80160, 11, 12, 10, 8, 9);

// Buttons (anpassen)
const int BTN_MENU = 3;
const int BTN_UP = 4;
const int BTN_DOWN = 5;
const int BTN_SELECT = 6;

int i;
bool Selecting = false;

int values[2];
String menu1Items[] = {"Menu 1-1", "Menu 1-2"};
String menu2Items[] = {"Menu 2-1", "Menu 2-2", "EXIT"};

int menuIndex = 0;     // Pos im Menü nach Upload
int menuPage = 1;      // Auswahl Menüseite nach Upload
int maxMenu1Items = 1; // Einträge jeder Menüseite, 1 = 2 Einträge
int maxMenu2Items = 2; // Einträge jeder Menüseite, 2 = 3 Einträge

void setup() {

  // Setup the LCD
  myGLCD.InitLCD(1);
  myGLCD.clrScr();
  myGLCD.setFont(SmallFont);
  myGLCD.setColor(255, 255, 255);

  pinMode(BTN_MENU, INPUT_PULLUP);
  pinMode(BTN_UP, INPUT_PULLUP);
  pinMode(BTN_DOWN, INPUT_PULLUP);
  pinMode(BTN_SELECT, INPUT_PULLUP);

  EEPROM.update(0, 1); // INITIALISIERUNG DES EEPROM Platzes, nach 1. Upload auskommentieren
  EEPROM.update(1, 1); // INITIALISIERUNG DES EEPROM Platzes, nach 1. Upload auskommentieren

  if (menuPage == 1) displayMenu1();
  if (menuPage == 2) displayMenu2();
}

void loop() {

  if (buttonPressed(BTN_UP)) {
    if (!Selecting) {
      menuIndex = (menuIndex - 1);
      if (menuIndex < 0) menuIndex = 0;
      if (menuPage == 1) displayMenu1();
      if (menuPage == 2) displayMenu2();
    } else {
      values[menuIndex]++;
      if (menuPage == 1) displayMenu1Select();
      if (menuPage == 2) displayMenu2Select();
    }
    delay(200);
  }

  if (buttonPressed(BTN_DOWN)) {
    if (!Selecting) {
      menuIndex = (menuIndex + 1);
      if (menuPage == 1) {
        if (menuIndex > maxMenu1Items) menuIndex = maxMenu1Items;
        displayMenu1();
      }
      if (menuPage == 2) {
        if (menuIndex > maxMenu2Items) menuIndex = maxMenu2Items;
        displayMenu2();
      }
    } else {
      values[menuIndex]--;
      if (menuPage == 1) displayMenu1Select();
      if (menuPage == 2) displayMenu2Select();
    }
    delay(200);
  }

  if (buttonPressed(BTN_SELECT)) {
    Serial.println(menuPage);
    if (menuPage == 1) displayMenu1Select();
    if (menuPage == 2) Selecting = !Selecting; displayMenu2Select();
    delay(200);
  }
}

bool buttonPressed(int pin) {
  return digitalRead(pin) == LOW;
}

void displayMenu1() {
  Serial.println(menuIndex);
  myGLCD.setColor(255, 255, 255);
  for (i = 0; i <= maxMenu1Items; ++i)
    if (menuIndex == i) {
      myGLCD.setColor(0, 0, 255);
      myGLCD.print(menu1Items[i], 15, i * 15 + 20);
    }
    else {
      myGLCD.setColor(255, 255, 255);
      myGLCD.print(menu1Items[i], 15, i * 15 + 20);
    }
}

void displayMenu1Select() {
  menuPage = 2; menuIndex = 0; myGLCD.clrScr(); displayMenu2();
}

void displayMenu2() {

  values[0] = EEPROM.read(0);
  values[1] = EEPROM.read(1);

  myGLCD.setColor(255, 255, 255);
  for (i = 0; i <= maxMenu2Items; ++i) {
    if (menuIndex == i) {
      myGLCD.setColor(0, 0, 255);
      myGLCD.print(menu2Items[i], 15, i * 15 + 20);
    }
    else {
      myGLCD.setColor(255, 255, 255);
      myGLCD.print(menu2Items[i], 15, i * 15 + 20);
    }
    if (i < maxMenu2Items) {
      if (values[menuIndex] == 0 ) {
        myGLCD.setColor(255, 0, 0);
        myGLCD.print("OFF", 90, i * 15 + 20);
      }
      if (values[menuIndex] == 1 ) {
        myGLCD.setColor(0, 255, 0);
        myGLCD.print("ON ", 90, i * 15 + 20);
      }
    }
  }
}

void displayMenu2Select() {

  if (menuIndex == 0) {
    values[menuIndex] = 1 - values[menuIndex];
    if (values[menuIndex] == 0 ) {
      myGLCD.setColor(255, 0, 0);
      myGLCD.print("OFF", 90, menuIndex * 15 + 20);
    }
    if (values[menuIndex] == 1 ) {
      myGLCD.setColor(0, 255, 0);
      myGLCD.print("ON ", 90, menuIndex * 15 + 20);
    }
    EEPROM.update(0, values[menuIndex]);
    Selecting = 0;
  }
  if (menuIndex == 1) {
    values[menuIndex] = 1 - values[menuIndex];
    if (values[menuIndex] == 0 ) {
      myGLCD.setColor(255, 0, 0);
      myGLCD.print("OFF", 90, menuIndex * 15 + 20);
    }
    if (values[menuIndex] == 1 ) {
      myGLCD.setColor(0, 255, 0);
      myGLCD.print("ON ", 90, menuIndex * 15 + 20);
    }
    EEPROM.update(1, values[menuIndex]);
    Selecting = 0;
  }
  if (menuIndex == maxMenu2Items) {
    Selecting = 0;
    menuPage = 1;
    menuIndex = 0;
    myGLCD.clrScr();
    displayMenu1();
  }
}
[/code]

Willkommen im Forum!

Prellt die Taste vielleicht?
Testweise mal ein kleines delay() einfügen und testen, ob es besser wird. Falls ja, dann richtig machen.

bool buttonPressed(int pin) {
  delay(30);
  return digitalRead(pin) == LOW;
}

Außerdem fehlt meiner Meinung nach ein Serial.begin(115200); im setup().

Du hast einige male

---> in eine Funktion auslagern

Wenn du den Code formatierst

Siehst du , das das so nicht geht:

if (buttonPressed(BTN_SELECT)) {
    Serial.println(menuPage);
    if (menuPage == 1) displayMenu1Select();
    if (menuPage == 2) Selecting = !Selecting;
    displayMenu2Select();
    delay(200);
  }

Da fehlen Klammern: displayMenu2Select(); wird immer aufgerufen.

Hier mal der komplette Code neu formatiert (aber noch mit Fehlern):

#include <UTFT.h>
#include <EEPROM.h>

// Declare which fonts we will be using
extern uint8_t SmallFont[];
extern uint8_t BigFont[];
// Initialize display
//SDI=11  SCL=12  /CS =10  /RST=8  D/C=9
UTFT myGLCD(ST7735S_4L_80160, 11, 12, 10, 8, 9);

// Buttons (anpassen)
const int BTN_MENU = 3;
const int BTN_UP = 4;
const int BTN_DOWN = 5;
const int BTN_SELECT = 6;

int i;
bool Selecting = false;

int values[2];
String menu1Items[] = {
  "Menu 1-1",
  "Menu 1-2"
};
String menu2Items[] = {
  "Menu 2-1",
  "Menu 2-2",
  "EXIT"
};

int menuIndex = 0; // Pos im Menü nach Upload
int menuPage = 1; // Auswahl Menüseite nach Upload
int maxMenu1Items = 1; // Einträge jeder Menüseite, 1 = 2 Einträge
int maxMenu2Items = 2; // Einträge jeder Menüseite, 2 = 3 Einträge

void setup() {

  // Setup the LCD
  myGLCD.InitLCD(1);
  myGLCD.clrScr();
  myGLCD.setFont(SmallFont);
  myGLCD.setColor(255, 255, 255);

  pinMode(BTN_MENU, INPUT_PULLUP);
  pinMode(BTN_UP, INPUT_PULLUP);
  pinMode(BTN_DOWN, INPUT_PULLUP);
  pinMode(BTN_SELECT, INPUT_PULLUP);

  EEPROM.update(0, 1); // INITIALISIERUNG DES EEPROM Platzes, nach 1. Upload auskommentieren
  EEPROM.update(1, 1); // INITIALISIERUNG DES EEPROM Platzes, nach 1. Upload auskommentieren

  if (menuPage == 1) displayMenu1();
  if (menuPage == 2) displayMenu2();
}

void loop() {

  if (buttonPressed(BTN_UP)) {
    if (!Selecting) {
      menuIndex = (menuIndex - 1);
      if (menuIndex < 0) menuIndex = 0;
      if (menuPage == 1) displayMenu1();
      if (menuPage == 2) displayMenu2();
    } else {
      values[menuIndex]++;
      if (menuPage == 1) displayMenu1Select();
      if (menuPage == 2) displayMenu2Select();
    }
    delay(200);
  }

  if (buttonPressed(BTN_DOWN)) {
    if (!Selecting) {
      menuIndex = (menuIndex + 1);
      if (menuPage == 1) {
        if (menuIndex > maxMenu1Items) menuIndex = maxMenu1Items;
        displayMenu1();
      }
      if (menuPage == 2) {
        if (menuIndex > maxMenu2Items) menuIndex = maxMenu2Items;
        displayMenu2();
      }
    } else {
      values[menuIndex]--;
      if (menuPage == 1) displayMenu1Select();
      if (menuPage == 2) displayMenu2Select();
    }
    delay(200);
  }

  if (buttonPressed(BTN_SELECT)) {
    Serial.println(menuPage);
    if (menuPage == 1) displayMenu1Select();
    if (menuPage == 2) Selecting = !Selecting;
    displayMenu2Select();
    delay(200);
  }
}

bool buttonPressed(int pin) {
  return digitalRead(pin) == LOW;
}

void displayMenu1() {
  Serial.println(menuIndex);
  myGLCD.setColor(255, 255, 255);
  for (i = 0; i <= maxMenu1Items; ++i)
    if (menuIndex == i) {
      myGLCD.setColor(0, 0, 255);
      myGLCD.print(menu1Items[i], 15, i * 15 + 20);
    }
  else {
    myGLCD.setColor(255, 255, 255);
    myGLCD.print(menu1Items[i], 15, i * 15 + 20);
  }
}

void displayMenu1Select() {
  menuPage = 2;
  menuIndex = 0;
  myGLCD.clrScr();
  displayMenu2();
}

void displayMenu2() {

  values[0] = EEPROM.read(0);
  values[1] = EEPROM.read(1);

  myGLCD.setColor(255, 255, 255);
  for (i = 0; i <= maxMenu2Items; ++i) {
    if (menuIndex == i) {
      myGLCD.setColor(0, 0, 255);
      myGLCD.print(menu2Items[i], 15, i * 15 + 20);
    } else {
      myGLCD.setColor(255, 255, 255);
      myGLCD.print(menu2Items[i], 15, i * 15 + 20);
    }
    if (i < maxMenu2Items) {
      if (values[menuIndex] == 0) {
        myGLCD.setColor(255, 0, 0);
        myGLCD.print("OFF", 90, i * 15 + 20);
      }
      if (values[menuIndex] == 1) {
        myGLCD.setColor(0, 255, 0);
        myGLCD.print("ON ", 90, i * 15 + 20);
      }
    }
  }
}

void displayMenu2Select() {

    if (menuIndex == 0) {
      values[menuIndex] = 1 - values[menuIndex];
      if (values[menuIndex] == 0) {
        myGLCD.setColor(255, 0, 0);
        myGLCD.print("OFF", 90, menuIndex * 15 + 20);
      }
      if (values[menuIndex] == 1) {
        myGLCD.setColor(0, 255, 0);
        myGLCD.print("ON ", 90, menuIndex * 15 + 20);
      }
      EEPROM.update(0, values[menuIndex]);
      Selecting = 0;
    }
    if (menuIndex == 1) {
      values[menuIndex] = 1 - values[menuIndex];
      if (values[menuIndex] == 0) {
        myGLCD.setColor(255, 0, 0);
        myGLCD.print("OFF", 90, menuIndex * 15 + 20);
      }
      if (values[menuIndex] == 1) {
        myGLCD.setColor(0, 255, 0);
        myGLCD.print("ON ", 90, menuIndex * 15 + 20);
      }
      EEPROM.update(1, values[menuIndex]);
      Selecting = 0;
    }
    if (menuIndex == maxMenu2Items) {
      Selecting = 0;
      menuPage = 1;
      menuIndex = 0;
      myGLCD.clrScr();
      displayMenu1();
    }
  }

Danke - Taste entprellen habe ich schon mehrfach mit längeren Entprellzeiten und an mehreren Stellen versucht - bringt keine Änderung.

Da ich kein Serial.print im Code habe, habe ich das für das Beispiel ausgebaut.
Das ist auch keine Fehlerursache, also irrelevant. Kann jeder einbauen, wer es braucht...

Und was ist das?

Scheint so aussehen als wurde das für Uno, Nano geschrieben, wenn ja dann hast du ein falsches Display dir ausgesucht.
Ist das der?


das ist ein 3,3V Display, bedeutet auf den Display Pins darf keine 5 V anliegen, Uno Nano ist ein 5 V System = auf SDI=11 SCL=12 /CS =10 /RST=8 D/C=9 kommen 5V raus.
Das Display wird wahrscheinlich kurze Zeit funktionieren.

Abgesehen das displayMenu2Select();ist an falscher stelle,
Warum sollte das nicht gehen ?

 if (buttonPressed(BTN_SELECT)) {
    Serial.println(menuPage);
    if (menuPage == 1) displayMenu1Select();
    if (menuPage == 2) Selecting = !Selecting; displayMenu2Select();
    delay(200);
  }

So was

 if (buttonPressed(BTN_SELECT)) { Serial.println(menuPage); if (menuPage == 1) displayMenu1Select();    if (menuPage == 2) Selecting = !Selecting; displayMenu2Select(); delay(200);  }

funktioniert auch das dass ist fast nicht lesbar ist andere Sache.

Was für UTFT Bibliothek nutzt du, vom Henning Karlsen, Rinky-Dink Electronics ist die nicht den so was

UTFT myGLCD(ST7735S_4L_80160, 11, 12, 10, 8, 9);

kennt die nicht.

Weil displayMenu1Select() sofort durch displayMenu2Select() überschrieben wird.

Ich dachte du bemängelt die Schreibweise, in die Logik habe nicht geachtet, das ganze ist so wie so murks, erstmal soll @stefan-007 antworten auf gestellte Fragen.

Wie geschrieben - ich bin kein Profiprogrammierer. Hab mir alles selber beigebracht und stosse manchmal an meine Grenzen. Habe heute eine Lösung gefunden. Auch wenn ich nicht verstehe, warum das passiert - bzw. wie ich das "einfacher" hätte lösen müssen. Neuer Code anbei...

Ich habe es jetzt so gelöst:
Zustand jedes Menüs wird gemerkt. Wenn ins Menü 2 gesprungen wird und Zustand von Manü 1 < 2 ist, dann soll das "Problem" (Menü2SELECT) übersprungen werden. Das macht er das erste Mal und dann passen die Werte wie sie sein sollen und es funktioniert alles.

Ich habe mich wirklich tot gesucht nach einem solchen Beispiel. Kann es wirklich sein, daß es das nirgends gibt? Ein Menü für OLED Displays mit 2-3 Ebenen wo man auch noch auf ein paar Seiten Werte einstellen kann und andere nur ein Menü mit Auswahl sind?

#Weil displayMenu1Select() sofort durch displayMenu2Select() überschrieben wird.

DAS ist eine brauchbare Antwort. Aber warum passiert das? Und wie kann ich es verhindern?

[code]
#include <UTFT.h>
#include <EEPROM.h>

// Declare which fonts we will be using
extern uint8_t SmallFont[];
extern uint8_t BigFont[];
// Initialize display
//SDI=11  SCL=12  /CS =10  /RST=8  D/C=9
UTFT myGLCD(ST7735S_4L_80160, 11, 12, 10, 8, 9);

// Buttons (anpassen)
const int BTN_MENU = 3;
const int BTN_UP = 4;
const int BTN_DOWN = 5;
const int BTN_SELECT = 6;

int i;
int lastMenu;
bool Selecting = false;

int values[2];
String menu1Items[] = {"Menu 1-1", "Menu 1-2"};
String menu2Items[] = {"Menu 2-1", "Menu 2-2", "EXIT"};

int menuIndex = 0;     // Pos im Menü nach Upload
int menuPage = 2;      // Auswahl Menüseite nach Upload
int maxMenu1Items = 1; // Einträge jeder Menüseite, 1 = 2 Einträge
int maxMenu2Items = 2; // Einträge jeder Menüseite, 2 = 3 Einträge

void setup() {

  Serial.begin(9600);

  // Setup the LCD
  myGLCD.InitLCD(1);
  myGLCD.clrScr();
  myGLCD.setFont(SmallFont);
  myGLCD.setColor(255, 255, 255);

  pinMode(BTN_MENU, INPUT_PULLUP);
  pinMode(BTN_UP, INPUT_PULLUP);
  pinMode(BTN_DOWN, INPUT_PULLUP);
  pinMode(BTN_SELECT, INPUT_PULLUP);

  EEPROM.update(0, 1); // INITIALISIERUNG DES EEPROM Platzes, nach 1. Upload auskommentieren
  EEPROM.update(1, 1); // INITIALISIERUNG DES EEPROM Platzes, nach 1. Upload auskommentieren

  if (menuPage == 1) displayMenu1();
  if (menuPage == 2) displayMenu2();
}

void loop() {

  if (buttonPressed(BTN_UP)) {
    if (!Selecting) {
      menuIndex = (menuIndex - 1);
      if (menuIndex < 0) menuIndex = 0;
      if (menuPage == 1) displayMenu1();
      if (menuPage == 2) displayMenu2();
    } else {
      values[menuIndex]++;
      if (menuPage == 1) displayMenu1Select();
      if (menuPage == 2) displayMenu2Select();
    }
    delay(200);
  }

  if (buttonPressed(BTN_DOWN)) {
    if (!Selecting) {
      menuIndex = (menuIndex + 1);
      if (menuPage == 1) {
        if (menuIndex > maxMenu1Items) menuIndex = maxMenu1Items;
        displayMenu1();
      }
      if (menuPage == 2) {
        if (menuIndex > maxMenu2Items) menuIndex = maxMenu2Items;
        displayMenu2();
      }
    } else {
      values[menuIndex]--;
      if (menuPage == 1) displayMenu1Select();
      if (menuPage == 2) displayMenu2Select();
    }
    delay(200);
  }

  if (buttonPressed(BTN_SELECT)) {
    Serial.println(menuPage);
    if (menuPage == 1) displayMenu1Select();
    if (menuPage == 2) Selecting = !Selecting; displayMenu2Select();
    delay(200);
  }
}

bool buttonPressed(int pin) {
  return digitalRead(pin) == LOW;
}

void displayMenu1() {
  Serial.println(menuIndex);
  myGLCD.setColor(255, 255, 255);
  for (i = 0; i <= maxMenu1Items; ++i)
    if (menuIndex == i) {
      myGLCD.setColor(0, 0, 255);
      myGLCD.print(menu1Items[i], 15, i * 15 + 20);
    }
    else {
      myGLCD.setColor(255, 255, 255);
      myGLCD.print(menu1Items[i], 15, i * 15 + 20);
    }
}

void displayMenu1Select() {
  lastMenu = 2; menuPage = 2; menuIndex = 0; myGLCD.clrScr(); displayMenu2();
}

void displayMenu2() {

  values[0] = EEPROM.read(0);
  values[1] = EEPROM.read(1);

  myGLCD.setColor(255, 255, 255);
  for (i = 0; i <= maxMenu2Items; ++i) {
    if (menuIndex == i) {
      myGLCD.setColor(0, 0, 255);
      myGLCD.print(menu2Items[i], 15, i * 15 + 20);
    }
    else {
      myGLCD.setColor(255, 255, 255);
      myGLCD.print(menu2Items[i], 15, i * 15 + 20);
    }
    if (i < maxMenu2Items) {
      if (values[menuIndex] == 0 ) {
        myGLCD.setColor(255, 0, 0);
        myGLCD.print("OFF", 90, i * 15 + 20);
      }
      if (values[menuIndex] == 1 ) {
        myGLCD.setColor(0, 255, 0);
        myGLCD.print("ON ", 90, i * 15 + 20);
      }
    }
  }
}

void displayMenu2Select() {

  if (lastMenu < 1) {
    Selecting = 0;
    lastMenu = 2;
    menuPage = 2;
    goto ENDE;
  }

  if (menuIndex == 0) {
    values[menuIndex] = 1 - values[menuIndex];
    if (values[menuIndex] == 0 ) {
      myGLCD.setColor(255, 0, 0);
      myGLCD.print("OFF", 90, menuIndex * 15 + 20);
    }
    if (values[menuIndex] == 1 ) {
      myGLCD.setColor(0, 255, 0);
      myGLCD.print("ON ", 90, menuIndex * 15 + 20);
    }
    EEPROM.update(0, values[menuIndex]);
    Selecting = 0;
  }
  if (menuIndex == 1) {
    values[menuIndex] = 1 - values[menuIndex];
    if (values[menuIndex] == 0 ) {
      myGLCD.setColor(255, 0, 0);
      myGLCD.print("OFF", 90, menuIndex * 15 + 20);
    }
    if (values[menuIndex] == 1 ) {
      myGLCD.setColor(0, 255, 0);
      myGLCD.print("ON ", 90, menuIndex * 15 + 20);
    }
    EEPROM.update(1, values[menuIndex]);
    Selecting = 0;
  }
  if (menuIndex == maxMenu2Items) {
    Selecting = 0;
    menuPage = 1;
    menuIndex = 0;
    myGLCD.clrScr();
    displayMenu1();
  }

ENDE:;
}
[/code]

Ich habe ein 0,96 80X160(RGB)IPS OLED Display, das an 3V hängt.
Das ganze Projekt wird eine Zeitschaltuhr mit RTC und einem Relais.
Wahrscheinlich muß ich auf einen ArduinoMega wechseln, wenn der Gesamtcode nicht auf meinen ArduinoNano paßt. Plan ist, das am Ende in eine handelsübliche Zeitschaltuhr einzubauen (wenn es platztechnisch geht). Funktion ist incl. Helligkeitsauswertung, automatische Sommer/Winterzeitumstellung und Temperaturberücksichtigung (vom RTC Modul). Was man dann damit machen kann?

  1. Normale Zeitschaltuhr mit mehreren Programmen (deshalb das Menü zum Einstellen)
  2. RTC einstellen, wenn die Batterie gewechselt werden muß (auch Menüsache)
  3. Brunnen einschalten wenn es hell wird - ausschalten wenn es dunkel wird (aber z.B. nur am Wochenende)
  4. Gartenbeleuchtung einschalten wenn es dunkel wird, aber Mitternacht ausschalten.
  5. Frostwächter fürs Gewächshaus oder Lüfter an wenn es zu heiß wird
    Und das alles miteinander kombinierbar - oder auch nicht
    usw. usw.

Wenn du must, will umsteigen, nehme ein ESP32 so wie es jetzt ist machst du das Display kaputt er wird mit 5V befeuert, auch wenn der mit 3.3V versorgt wird, zu dem mit ESP kannst bessere Bibliothek für Display nehmen

ändern in

if (menuPage == 2) {
  Selecting = !Selecting; 
  displayMenu2Select();
}

Hallo Werner,
du schreibst "Weil displayMenu1Select() sofort durch displayMenu2Select() überschrieben wird." Diesen Effekt habe ich vermutet. Aber ich verstehe nicht, warum das passiert. Wenn ich den Select Knopf drücke und definiere, daß in Menu1Select() gegangen werden soll, dann geht es ab in Menu1Select(). - soweit ok. Es gibt dann aber nirgends den Befehl, daß in Menu2Select() gegangen werden soll. Warum wird das dann überschrieben? Wenn ich das verstehe, kann ich es evtl. verhindern und alles ist gut. Magst du mir das bitte erklären? Danke

ändern in

if (menuPage == 2) {
  Selecting = !Selecting; 
  displayMenu2Select();

habe ich gemacht - bringt keine Änderung mit sich!

Ich habe jetzt noch einen Menüpunkt dazugebaut.

  1. Menüpunkt ist displayMenu0 von dem springt man in displayMenu1 und von dem in displayMenu2. Das ganze auch wieder rückwärts mit entsprechenden EXITs im Menü.

Nur... wenn ich jetzt im displayMenu0 die Select Taste drücke, erscheint für 1 Sekunde das displayMenu1 und dann kommt sofort displayMenu3 und der erste Wert wird auch noch von ON auf OFF umgestellt und gespeichert.

Warum passiert das?
Wie kann ich das verhindern?
Wer kann mir helfen so ein Menü so zu bauen, daß es funktioniert?

[code]
#include <UTFT.h>
#include <EEPROM.h>

// Declare which fonts we will be using
extern uint8_t SmallFont[];
extern uint8_t BigFont[];
// Initialize display
//SDI=11  SCL=12  /CS =10  /RST=8  D/C=9
UTFT myGLCD(ST7735S_4L_80160, 11, 12, 10, 8, 9);

// Buttons (anpassen)
const int BTN_MENU = 3;
const int BTN_UP = 4;
const int BTN_DOWN = 5;
const int BTN_SELECT = 6;

int i;
bool Selecting = false;

int values[2];
String menu0Items[] = {"Menu 0-1"};
String menu1Items[] = {"Menu 1-1", "Menu 1-2"};
String menu2Items[] = {"Menu 2-1", "Menu 2-2", "EXIT"};

int menuIndex = 0;     // Pos im Menü nach Upload
int menuPage = 0;      // Auswahl Menüseite nach Upload
int maxMenu0Items = 0; // Einträge jeder Menüseite, 0 = 1 Eintrage
int maxMenu1Items = 1; // Einträge jeder Menüseite, 1 = 2 Einträge
int maxMenu2Items = 2; // Einträge jeder Menüseite, 2 = 3 Einträge

void setup() {

  Serial.begin(9600);

  // Setup the LCD
  myGLCD.InitLCD(1);
  myGLCD.clrScr();
  myGLCD.setFont(SmallFont);
  myGLCD.setColor(255, 255, 255);

  pinMode(BTN_MENU, INPUT_PULLUP);
  pinMode(BTN_UP, INPUT_PULLUP);
  pinMode(BTN_DOWN, INPUT_PULLUP);
  pinMode(BTN_SELECT, INPUT_PULLUP);

  EEPROM.update(0, 1); // INITIALISIERUNG DES EEPROM Platzes, nach 1. Upload auskommentieren
  EEPROM.update(1, 1); // INITIALISIERUNG DES EEPROM Platzes, nach 1. Upload auskommentieren

  if (menuPage == 0) displayMenu0();
  if (menuPage == 1) displayMenu1();
  if (menuPage == 2) displayMenu2();
}

void loop() {

  if (buttonPressed(BTN_UP)) {
    if (!Selecting) {
      menuIndex = (menuIndex - 1);
      if (menuIndex < 0) menuIndex = 0;
      if (menuPage == 0) displayMenu0();
      if (menuPage == 1) displayMenu1();
      if (menuPage == 2) displayMenu2();
    } else {
      values[menuIndex]++;
      if (menuPage == 0) displayMenu0Select();
      if (menuPage == 1) displayMenu1Select();
      if (menuPage == 2) displayMenu2Select();
    }
    delay(200);
  }

  if (buttonPressed(BTN_DOWN)) {
    if (!Selecting) {
      menuIndex = (menuIndex + 1);
      if (menuPage == 0) {
        if (menuIndex > maxMenu1Items) menuIndex = maxMenu0Items;
        displayMenu0();
      }
      if (menuPage == 1) {
        if (menuIndex > maxMenu1Items) menuIndex = maxMenu1Items;
        displayMenu1();
      }
      if (menuPage == 2) {
        if (menuIndex > maxMenu2Items) menuIndex = maxMenu2Items;
        displayMenu2();
      }
    } else {
      values[menuIndex]--;
      if (menuPage == 0) displayMenu0Select();
      if (menuPage == 1) displayMenu1Select();
      if (menuPage == 2) displayMenu2Select();
    }
    delay(200);
  }

  if (buttonPressed(BTN_SELECT)) {
    Serial.println(menuPage);
    if (menuPage == 0) displayMenu0Select();
    if (menuPage == 1) displayMenu1Select();
    if (menuPage == 2) Selecting = !Selecting; displayMenu2Select();
    delay(200);
  }
}

bool buttonPressed(int pin) {
  return digitalRead(pin) == LOW;
}

void displayMenu0() {
  Serial.println(menuIndex);
  myGLCD.setColor(255, 255, 255);
  for (i = 0; i <= maxMenu0Items; ++i)
    if (menuIndex == i) {
      myGLCD.setColor(0, 0, 255);
      myGLCD.print(menu0Items[i], 15, i * 15 + 20);
    }
    else {
      myGLCD.setColor(255, 255, 255);
      myGLCD.print(menu0Items[i], 15, i * 15 + 20);
    }
}

void displayMenu0Select() {
  menuPage = 1; menuIndex = 0; myGLCD.clrScr(); displayMenu1();
}

void displayMenu1() {
  Serial.println(menuIndex);
  myGLCD.setColor(255, 255, 255);
  for (i = 0; i <= maxMenu1Items; ++i)
    if (menuIndex == i) {
      myGLCD.setColor(0, 0, 255);
      myGLCD.print(menu1Items[i], 15, i * 15 + 20);
    }
    else {
      myGLCD.setColor(255, 255, 255);
      myGLCD.print(menu1Items[i], 15, i * 15 + 20);
    }
}

void displayMenu1Select() {
  menuPage = 2; menuIndex = 0; myGLCD.clrScr(); displayMenu2();
}

void displayMenu2() {

  values[0] = EEPROM.read(0);
  values[1] = EEPROM.read(1);

  myGLCD.setColor(255, 255, 255);
  for (i = 0; i <= maxMenu2Items; ++i) {
    if (menuIndex == i) {
      myGLCD.setColor(0, 0, 255);
      myGLCD.print(menu2Items[i], 15, i * 15 + 20);
    }
    else {
      myGLCD.setColor(255, 255, 255);
      myGLCD.print(menu2Items[i], 15, i * 15 + 20);
    }
    if (i < maxMenu2Items) {
      if (values[menuIndex] == 0 ) {
        myGLCD.setColor(255, 0, 0);
        myGLCD.print("OFF", 90, i * 15 + 20);
      }
      if (values[menuIndex] == 1 ) {
        myGLCD.setColor(0, 255, 0);
        myGLCD.print("ON ", 90, i * 15 + 20);
      }
    }
  }
}

void displayMenu2Select() {

  if (menuIndex == 0) {
    values[menuIndex] = 1 - values[menuIndex];
    if (values[menuIndex] == 0 ) {
      myGLCD.setColor(255, 0, 0);
      myGLCD.print("OFF", 90, menuIndex * 15 + 20);
    }
    if (values[menuIndex] == 1 ) {
      myGLCD.setColor(0, 255, 0);
      myGLCD.print("ON ", 90, menuIndex * 15 + 20);
    }
    EEPROM.update(0, values[menuIndex]);
    Selecting = 0;
  }
  if (menuIndex == 1) {
    values[menuIndex] = 1 - values[menuIndex];
    if (values[menuIndex] == 0 ) {
      myGLCD.setColor(255, 0, 0);
      myGLCD.print("OFF", 90, menuIndex * 15 + 20);
    }
    if (values[menuIndex] == 1 ) {
      myGLCD.setColor(0, 255, 0);
      myGLCD.print("ON ", 90, menuIndex * 15 + 20);
    }
    EEPROM.update(1, values[menuIndex]);
    Selecting = 0;
  }
  if (menuIndex == maxMenu2Items) {
    Selecting = 0;
    menuPage = 1;
    menuIndex = 0;
    myGLCD.clrScr();
    displayMenu1();
  }
}
[/code]

Noch einmal: Das macht nicht das was du wahrscheinlich willst.

if (buttonPressed(BTN_SELECT)) {
    Serial.println(menuPage);
    if (menuPage == 0) displayMenu0Select();
    if (menuPage == 1) displayMenu1Select();
    if (menuPage == 2) Selecting = !Selecting; 
    displayMenu2Select();
    delay(200);
  }

So siehst du besser was wirklich passiert. Da fehlen die Klammern.

Auch das sieht seltsam aus.

Weißt du, wie du mit Serial.print debuggen kannst?

Ein Semikolon schließt eine Anweisung ab.
So wie Du das schreibst, gehört displayMenu2Select(); NICHT mehr zur „if“ Anweisung und wird immer ausgeführt!

Wenn das so gewollt ist ok. Dann wäre es aber eindeutiger das entweder so

if (menuPage == 2) { Selecting = !Selecting; }
displayMenu2Select();

oder so

if (menuPage == 2) 
  Selecting = !Selecting;
displayMenu2Select();

zu schreiben.

Ist das nicht gewollt, musst du es so schreiben:

if (menuPage == 2) { 
  Selecting = !Selecting; 
  displayMenu2Select();
}

Danke! Das habe ich verstanden. Es bringt aber trotzdem keine Änderung mit sich...