Problem mit Lcd Menü

Hi Leute

Ich versuche gerade mithilfe dieses Videos ein Menü zu bauen.

Eigentlich funktioniert auch alles ganz gut. Nur habe ich Probleme eine zurück Taste mit einzubinden.

Hier der Code

/* Sketch for Tutorial 14
Author: Maximilian Hentsch
Sketch zu Arduino Tutorial 14 - Displaymenü
https://www.youtube.com/watch?v=DuAG98P9Seo
*/

#include <Wire.h>
#include <Adafruit_INA219.h>
#include <LiquidCrystal.h>

LiquidCrystal lcd(16,17,5,18,23,19);

Adafruit_INA219 ina219;

int upButton = 4;
int downButton = 2;
int selectButton = 15;
int exitButton = 0;
int menu = 1;
int menuA = 1;


void setup() {
   Serial.begin(115200);
  while (!Serial) {
      // will pause Zero, Leonardo, etc until serial console opens
      delay(1);
  }

  uint32_t currentFrequency;
  
  // Initialize the INA219.
 
  if (! ina219.begin()) {
    Serial.println("Failed to find INA219 chip");
    while (1) { delay(10); }
  }
  // To use a slightly lower 32V, 1A range (higher precision on amps):
  ina219.setCalibration_32V_1A();
  // Or to use a lower 16V, 400mA range (higher precision on volts and amps):
  //ina219.setCalibration_16V_400mA();

  Serial.println("Measuring voltage and current with INA219 ...");  
  
  lcd.begin(16, 2);
  
  pinMode(upButton, INPUT_PULLUP);
  pinMode(downButton, INPUT_PULLUP);
  pinMode(selectButton, INPUT_PULLUP);
  pinMode(exitButton, INPUT_PULLUP);
  updateMenu();
}

void loop() {
  delay(500);
  if (!digitalRead(downButton)){
    menu++;
    updateMenu();
    delay(100);
    while (!digitalRead(downButton));
  }
  if (!digitalRead(upButton)){
    menu--;
    updateMenu();
    delay(100);
    while(!digitalRead(upButton));
  }
  if (!digitalRead(selectButton)){
    executeAction();
    updateMenu();
    delay(100);
    while (!digitalRead(selectButton));
  }
}

void updateMenu() {
  switch (menu) {
    case 0:
      menu = 1;
      break;
    case 1:
      lcd.clear();
      lcd.print(">Aktuell");
      lcd.setCursor(0, 1);
      lcd.print(" Vorauswahl");
      break;
    case 2:
      lcd.clear();
      lcd.print(" Aktuell");
      lcd.setCursor(0, 1);
      lcd.print(">Vorauswahl");
      break;
    case 3:
      lcd.clear();
      lcd.print(">MenuItem3");
      lcd.setCursor(0, 1);
      lcd.print(" MenuItem4");
      break;
    case 4:
      lcd.clear();
      lcd.print(" MenuItem3");
      lcd.setCursor(0, 1);
      lcd.print(">MenuItem4");
      break;
    case 5:
      menu = 4;
      break;
  }
}

 void executeAction() {
   switch (menu) {
    case 1:
      Aktuell();
      break;
    case 2:
      Vorauswahl();
      break;
    case 3:
      action3();
      break;
    case 4:
      action4();
      break;

  }
}

                            void Aktuell() {
                              //lcd.clear();
                            
                              
                              
                             
                              
                            
                              float shuntvoltage = 0;
                              float busvoltage = 0;
                              float current_mA = 0;
                              float loadvoltage = 0;
                              float power_mW = 0;
                            
                            
                              shuntvoltage = ina219.getShuntVoltage_mV();
                              busvoltage = ina219.getBusVoltage_V();
                              current_mA = ina219.getCurrent_mA();
                              power_mW = ina219.getPower_mW();
                              loadvoltage = busvoltage + (shuntvoltage / 1000);
                            
                              //Serial ausgabe
                              Serial.print("Bus Voltage:   "); Serial.print(busvoltage); Serial.println(" V");
                              Serial.print("Shunt Voltage: "); Serial.print(shuntvoltage); Serial.println(" mV");
                              Serial.print("Load Voltage:  "); Serial.print(loadvoltage); Serial.println(" V");
                              Serial.print("Current:       "); Serial.print(current_mA); Serial.println(" mA");
                              Serial.print("Power:         "); Serial.print(power_mW); Serial.println(" mW");
                              Serial.println("");
                                   
                                    
                                // LCD ausgabe
                                lcd.begin(16, 2);
                                //lcd.clear();
                                lcd.print("Aktuell:");
                                
                                lcd.print(current_mA);
                                lcd.print("mA");
                            
                                lcd.setCursor(0,1); 
                                lcd.print(busvoltage);
                                lcd.print("V");
                                lcd.print("   ");
                                lcd.print(power_mW);
                                lcd.print("mW"); 
                                delay(2000);
                                 
                              

                               if (!digitalRead(exitButton)){
                                updateMenu();
                                delay(100);
                                while (!digitalRead(exitButton));
                               
                                }
                                
                                else{
                                Aktuell();
                                }
                            }
                            


      void Vorauswahl() {
  
          delay(500);
         if (!digitalRead(downButton)){
          menuA++;
          auswahlMenu();
          delay(100);
          while (!digitalRead(downButton));
        }
        if (!digitalRead(upButton)){
          menuA--;
          auswahlMenu();
          delay(100);
          while(!digitalRead(upButton));
        }
        if (!digitalRead(selectButton)){
          executeActionA();
          auswahlMenu();
          delay(100);
          while (!digitalRead(selectButton));
        }
        else{
          auswahlMenu();
          delay(100);
        }
      }



                  void auswahlMenu() {
                    switch (menuA) {
                      case 0:
                        menuA = 1;
                        auswahlMenu();
                      case 1:
                        lcd.clear();
                        lcd.print(">12V 5W");
                        lcd.setCursor(0, 1);
                        lcd.print(" 12V 10W");
                        Vorauswahl();
                      case 2:
                        lcd.clear();
                        lcd.print(" 12V 5W");
                        lcd.setCursor(0, 1);
                        lcd.print(">12V 10W");
                        Vorauswahl();
                      case 3:
                        lcd.clear();
                        lcd.print(">MenuItem3");
                        lcd.setCursor(0, 1);
                        lcd.print(" MenuItem4");
                        Vorauswahl();
                      case 4:
                        lcd.clear();
                        lcd.print(" MenuItem3");
                        lcd.setCursor(0, 1);
                        lcd.print(">MenuItem4");
                        Vorauswahl();
                      case 5:
                        menuA = 4;
                        auswahlMenu();
                    }
                  }

                   void executeActionA() {
                   switch (menuA) {
                    case 1:
                      Aktuell();
                      break;
                    case 2:
                      Vorauswahl();
                      break;
                    case 3:
                      action3();
                      break;
                    case 4:
                      action4();
                      break;
                  }
                }

}

Das soll die zurück Funktion sein.

 if (!digitalRead(exitButton)){
           updateMenu();
           delay(100);
           while (!digitalRead(exitButton));
                               
  }

Immer wen ich den Knopf drücke, um zurück ins Hauptmenü zu kommen ist das Hauptmenü nur so lange da wie ich den Knopf gedrückt halte. Sobald ich ihn loslasse, springt das Programm zurück an die stelle, wo die if Funktion ist und macht dann mit void Vorauswahl() weiter.

Kann mir bitte jemand sagen wie ich das verhindern kann?

Entprellen ! ? !!

combie:
Entprellen ! ? !!

Das würde mir ja nur helfen, wen ich zu viele eingaben von dem Taster habe oder?

Mein Problem ist ja, dass er beim Betätigen kurz zu updateMenu(); springt und dann aber an der stelle weiter macht, wo nach der Taster Eingabe kommt also bei void Vorauswahl()

Moto20x:
Kann mir bitte jemand sagen wie ich das verhindern kann?

Da Dein Sketch sehr schlecht lesbar ist, habe ich ihn erst gar nicht angeguckt.

Mach' ihn „hübsch“. Insbesondere: Einheitliche und übersichtliche Klammerungen und Einrückungen. Mich würde nicht wundern, wenn Du die Ursache Deines Problems beim Aufhübschen selbst entdeckst.

Gruß

Gregor

Ich habe jetzt einfach mal ein kleines Beispiel Programm gemacht, wo der gleiche Fehler auftritt.

#include <LiquidCrystal.h>
LiquidCrystal lcd(16,17,5,18,23,19);

int upButton = 4;
int downButton = 2;
int selectButton = 15;
int exitButton = 0;
int menu = 1;

float B = 0;


void setup() {
 
  
  lcd.begin(16, 2);
  
  pinMode(upButton, INPUT_PULLUP);
  pinMode(downButton, INPUT_PULLUP);
  pinMode(selectButton, INPUT_PULLUP);
  pinMode(exitButton, INPUT_PULLUP);
  updateMenu();
}


void loop() {
  delay(500);
  if (!digitalRead(downButton)){
    menu++;
    updateMenu();
    delay(100);
    while (!digitalRead(downButton));
  }
  if (!digitalRead(upButton)){
    menu--;
    updateMenu();
    delay(100);
    while(!digitalRead(upButton));
  }
  if (!digitalRead(selectButton)){
    executeAction();
    updateMenu();
    delay(100);
    while (!digitalRead(selectButton));
  }
}

void updateMenu() {
  switch (menu) {
    case 0:
      menu = 1;
      break;
    case 1:
      lcd.clear();
      lcd.print(">action1");
      lcd.setCursor(0, 1);
      lcd.print(" action2");
      break;
    case 2:
      lcd.clear();
      lcd.print(" action1");
      lcd.setCursor(0, 1);
      lcd.print(">action2");
      break;
    case 3:
      lcd.clear();
      lcd.print(">action3");
      lcd.setCursor(0, 1);
      lcd.print(" action4");
      break;
    case 4:
      lcd.clear();
      lcd.print(" action3");
      lcd.setCursor(0, 1);
      lcd.print(">action4");
      break;
    case 5:
      menu = 4;
      break;
  }
}

 void executeAction() {
   switch (menu) {
    case 1:
      action1();
      break;
    case 2:
      action2();
      break;
    case 3:
      action3();
      break;
    case 4:
      action4();
      break;

  }
}

void action1() {
 delay(500);
 lcd.clear();
 lcd.print("Breite");

    if (!digitalRead(exitButton)){
    delay(100);
    while (!digitalRead(exitButton));
    updateMenu();
    delay(500);
    }
    else{
    action1();
  }
     
}


void action2() {
  lcd.clear();
  lcd.print("Breite");

  lcd.setCursor(0,1); 
  lcd.print(B);
  lcd.print("cm");
   
    
  delay(500);
  
  if (!digitalRead(downButton)){
    B--;
    action2();
    delay(20);
    
  }
  if (!digitalRead(upButton)){
    B++;
    action2();
    delay(20);
    
  }
  if (!digitalRead(selectButton)){ 
    delay(100);
    while (!digitalRead(selectButton));
    action2B();
     
  }
  if (!digitalRead(exitButton)){
    delay(100);
    while (!digitalRead(exitButton));
    updateMenu();
 }
  else{
    action2();
  }
} 

void action2B() {
  lcd.clear();
  lcd.print("Breite");

  lcd.setCursor(0,1); 
  lcd.print(B);
  lcd.print("cm");
   
    
  delay(500);
  
  if (!digitalRead(downButton)){
    B=B-0.1;
    action2B();
    delay(20);
    
}
  if (!digitalRead(upButton)){
    B=B+0.1;
    action2B();
    delay(20);
    
}
  if (!digitalRead(selectButton)){
    delay(100);
    while (!digitalRead(selectButton));
    action1();
    exit;
}
  
  if (!digitalRead(exitButton)){
    delay(100);
    while (!digitalRead(exitButton));
    action2();
    exit;
}
  else{
    action2B();
  }
} 


void action3() {
  lcd.clear();
  lcd.print(">Executing #3");
  
  delay(1500);
    
}
void action4() {
  lcd.clear();
  lcd.print(">Executing #4");
  delay(1500);
}

In dem code ist ein Menü eingebaut das mit 4 Tastern gesteuert wird.
Aufrufen kann man 4 Funktionen.
Das Problem welche sich habe ist Folgendes:

Wen ich zuerst Action 1 aufrufen kann ich ohne Problem mit dem exitButton zurück in das Hauptmenü.
Geh ich aber zuerst in Action2 welche am Ende auf Action 1 zurückgeführt. Kann ich mit dem exitButton nicht mehr zurück ins Hauptmenü da er mich immer in Action 2 zurückwirft.

Ich hoffe, ihr versteht was ich meine. Das ist etwas schwer zu erklären.

Kann mir jemand sagen was ich ändern muss das ich bei dem Tastendruck des exitButtons immer im Hauptmenü lande?

Hi

Und DAS klappt?
Also, daß aus 'action1(); die Funktion 'action1()' immer wieder aufgerufen wird?
Wenn der Button 'Exit' nicht gedrückt ist, rufst Du die Funktion rekursiv auf - Das müsste eigentlich 'knallen'!
Wenn der Exit-Button gedrückt wurde, beendest Du die Funktion (nachdem das Menu angepasst wurde).

Schalte Mal die Warnungen ein (Voreinstellungen, Vollständige Warnungen beim Kompilieren/Hochladen).

Dann wirst Du eine Warnung erhalten, daß "exit;" ggf. nicht Das macht, was Du willst.

MfG

postmaster-ino:
Und DAS klappt?

Ja funktioniert. Nur beim Beenden macht es Probleme.

Falls jemand auf das Thema stößt und ein ähnliches Problem hat, ich hab jetzt eine Lösung gefunden.

Man muss das Menü mit while schleifen aufbauen dann funktioniert die Navigation.

Hier ist mein code:

#include <Wire.h>
#include <Adafruit_INA219.h>
#include <LiquidCrystal.h>

LiquidCrystal lcd(16,17,5,18,23,19);
Adafruit_INA219 ina219;

//variablen für Menü
int upButton = 4;
int downButton = 2;
int selectButton = 15;
int exitButton = 0;
int menu = 1;

//Variablen für untermenüs
int MeAkt = 0;
int MeW = 0;
int MeV = 0;

//werte für Sensor
float shuntvoltage = 0;
float busvoltage = 0;
float current_mA = 0;
float loadvoltage = 0;
float power_mW = 0;

//wert für Custom
int W = 0;
int LS = 12;


void setup() {
  
  Serial.begin(115200);
  
  while (!Serial) {
  delay(1);
  }

  uint32_t currentFrequency;
  
  // Initialize the INA219.
 
  if (! ina219.begin()) {
    Serial.println("Failed to find INA219 chip");
    while (1) { delay(10); }
    }
    
  // To use a slightly lower 32V, 1A range (higher precision on amps):
  ina219.setCalibration_32V_1A();
  // Or to use a lower 16V, 400mA range (higher precision on volts and amps):
  //ina219.setCalibration_16V_400mA(); 
  
  lcd.begin(16, 2);
  
  pinMode(upButton, INPUT_PULLUP);
  pinMode(downButton, INPUT_PULLUP);
  pinMode(selectButton, INPUT_PULLUP);
  pinMode(exitButton, INPUT_PULLUP);
  updateMenu();
}



void loop() {
 delay(500);
  if (!digitalRead(downButton)){
    menu++;
    updateMenu();
    delay(100);
    while (!digitalRead(downButton));
  }
  if (!digitalRead(upButton)){
    menu--;
    updateMenu();
    delay(100);
    while(!digitalRead(upButton));
  }
  if (!digitalRead(selectButton)){
    executeAction();
    updateMenu();
    delay(100);
    while (!digitalRead(selectButton));
  }
}

void updateMenu() {
  switch (menu) {
    case 0:
      menu = 1;
      break;
    case 1:
      lcd.clear();
      lcd.print(">Aktuell");
      lcd.setCursor(0, 1);
      lcd.print(" Custom");
      break;
    case 2:
      lcd.clear();
      lcd.print(" Aktuell");
      lcd.setCursor(0, 1);
      lcd.print(">Custom");
      break;
    case 3:
      lcd.clear();
      lcd.print(">MenuItem3");
      lcd.setCursor(0, 1);
      lcd.print(" MenuItem4");
      break;
    case 4:
      lcd.clear();
      lcd.print(" MenuItem3");
      lcd.setCursor(0, 1);
      lcd.print(">MenuItem4");
      break;
    case 5:
      menu = 4;
      break;
  }
}

 void executeAction() {
   switch (menu) {
    case 1:
      Aktuell();
      break;
    case 2:
      Watt();
      break;
    case 3:
      action3();
      break;
    case 4:
      action4();
      break;

  }
}

void Aktuell() {

MeAkt=1;

while(MeAkt=1){
  
        //Daten auslesen
        shuntvoltage = ina219.getShuntVoltage_mV();
        busvoltage = ina219.getBusVoltage_V();
        current_mA = ina219.getCurrent_mA();
        power_mW = ina219.getPower_mW();
        loadvoltage = busvoltage + (shuntvoltage / 1000);

        //Daten ausgabe
        Serial.print("Bus Voltage:   "); Serial.print(busvoltage); Serial.println(" V");
        Serial.print("Shunt Voltage: "); Serial.print(shuntvoltage); Serial.println(" mV");
        Serial.print("Load Voltage:  "); Serial.print(loadvoltage); Serial.println(" V");
        Serial.print("Current:       "); Serial.print(current_mA); Serial.println(" mA");
        Serial.print("Power:         "); Serial.print(power_mW); Serial.println(" mW");
        Serial.println("");

         // LCD ausgabe
        lcd.begin(16, 2);
        //lcd.clear();
        lcd.print("Aktuell:");
        lcd.print(current_mA);
        lcd.print("mA");
                            
        lcd.setCursor(0,1); 
        lcd.print(busvoltage);
        lcd.print("V");
        lcd.print("   ");
        lcd.print(power_mW);
        lcd.print("mW"); 
        delay(2000);

        if (!digitalRead(exitButton)){
        MeAkt=1;
        break;
        delay(100);
        while (!digitalRead(exitButton));
        }

    }
}

void Watt(){

MeW = 1;

while(MeW = 1){

  lcd.clear();
  lcd.print("Leistung W");
  lcd.setCursor(0,1); 
  lcd.print(W);
  lcd.print("W");

  delay(500);

  if (!digitalRead(downButton)){
    W--;
    delay(100);
    while (!digitalRead(downButton));
  }
  
  if (!digitalRead(upButton)){
    W++;
    delay(100);
    while(!digitalRead(upButton));
  }
  
  if (!digitalRead(selectButton)){
   MeW = 0;
   Volt();
   break;
   delay(100);
   while (!digitalRead(selectButton));
  }
  
  if (!digitalRead(exitButton)){
    MeW = 0;
    break;
    delay(100);
    while (!digitalRead(exitButton));
 }
}
}

void Volt(){

MeV=0;

while(MeV=1){

  lcd.clear();
  lcd.print("LadeStrom");
  lcd.setCursor(0,1); 
  lcd.print(LS);
  lcd.print("V");

  delay(500);

  if (!digitalRead(downButton)){
    LS = 12;
    delay(100);
    while (!digitalRead(downButton));
  }
  
  if (!digitalRead(upButton)){
    LS = 24;
    delay(100);
    while(!digitalRead(upButton));
  }
  
  if (!digitalRead(selectButton)){
   MeV=0;
   action3();
   break;
   delay(100);
   while (!digitalRead(selectButton));
  }
  
  if (!digitalRead(exitButton)){
    MeV=0;
    Watt();
    break;
    delay(100);
    while (!digitalRead(exitButton));
 }
}
}

void action3() {
  lcd.clear();
  lcd.print(">Executing #3");
  
  delay(1500);
  
  
  
}
void action4() {
  lcd.clear();
  lcd.print(">Executing #4");
  delay(1500);
}

Der ist noch nicht fertig aber man kann hoffentlich erkennen wie er funktioniert.

Man muss das Menü mit while schleifen aufbauen dann funktioniert die Navigation.

  ...

while(MeAkt=1)

Das solltest du nochmal in Ruhe ansehen. Wenn es tatsächlich funktionieren sollte, kann man das auch weniger verwirrend formulieren.

... auch wäre die Formulierung ...
'ICH musste das Menü mit While-Schleifen aufbauen'
deutlich näher am großen Ganzen.
Deine WHILE blockieren, wo's nur geht - solange derArduino NICHTS Anderes zu tun hat, als das Menü anzuzeigen, mag Das ja nicht schlimm sein - aber sobald Du ernsthaft Etwas mit Deinen Arduinos steuern willst - dann ist das Menü reine Zierde für den Bediener - fällt Dir Das tierisch auf die Füße - alleine die Wartezeit, bis der Button wieder los gelassen wurde, passiert Nichts.
Für eine reine Anzeige - egal - reicht so!
Aber für zukünftige Projekte ist Das, sofern nicht wieder NUR eine Anzeige bei heraus kommen soll, nicht wieder-verwertbar.

Wenn Das hier so klappt: Never change a running system (und wenn: mach VORHER ein Backup ... glaube mir :wink: )

MfG

Es ist schon bemerkenswert, welchen Aufwand du für das Menü treiben möchtest.
Warum willst du das Rad erneut erfinden ?
Das was du machst, gibt es schon als Library fertig und für dich zum einsetzen.
Schau mal hier.