LCD Menü

Guten Abend ich habe versucht ein kleines Programm zu erstellen bzw um zu schreiben.
Habe mir ein Teil zusammengesucht.

Es soll wie folgt funktioniern.
Ich will über 2 Tasten up and down also hoch und runter auswählen können
wenn ich zb Wiskey gewählt habe mit einer Enter Taste dann soll das Programm in ein untermenü gehen und was 2cl oder 4cl anzeigen

dies tut das Programm leider nicht. Auch wenn ich zu oft hoch oder runter drücke geht das Menü zurück zur Willkommen meldung.
Habt ihr eine einfache Idee.
hier der code:

#include <LiquidCrystal.h>
#define RS 32
#define E  33
#define D4 34
#define D5 35
#define D6 36
#define D7 37
#define COLS 16
#define ROWS 2
LiquidCrystal lcd(RS, E, D4, D5, D6, D7);

const int OK = 26;
const int up = 24;
const int down = 25;
const int zurueck = 27; 
int start =1;
int run =0;
int sel =0;
int sub=0;
void screen(unsigned char x);

void setup()
{
  pinMode(OK, INPUT);
  pinMode(up, INPUT);
  pinMode(down, INPUT);
  pinMode(zurueck, INPUT);
  lcd.begin(16,2);
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("LOADING");
  delay(500);
  lcd.setCursor(8,0);
  lcd.print(".");
  delay(500);
  lcd.setCursor(9,0);
  lcd.print(".");
  delay(500);
  lcd.setCursor(10,0);
  lcd.print(".");
  delay(1000);
  		
}

 
void loop()
{
    
    screen('a');
         
    while(start==1)
    {
        if(digitalRead(OK)==HIGH)
        {
            screen('b');
            run=1;
            start=0;
            sel=0;
           
        }
        
        else
        {
             run=0;
             start=1;
             sel=0;
         
         }
    }
    
    while(run==1)
    {
         
        if(digitalRead(OK)==HIGH)
        {
             screen('d');
             sel=1;
         }while(digitalRead(OK)==HIGH);
        
        if((digitalRead(up)==HIGH)||(digitalRead(down)==HIGH))
        {
              screen('c');
              run=2;
        } while((digitalRead(up)==HIGH)||(digitalRead(down)==HIGH));
        
        if(digitalRead(zurueck)==HIGH)
        {
              screen('a');
              sel=0;
              run=0;
              start=1;
            
        } while(digitalRead(zurueck)==HIGH);
    }
    
        while(run==2)
    {
      
        if(digitalRead(OK)==HIGH)
        {
             screen('f');
             sel=2;
            
        }while(digitalRead(OK)==HIGH);
        
        if((digitalRead(up)==HIGH)||(digitalRead(down)==HIGH))
        {
              screen('b');
              run=1;
        }while((digitalRead(up)==HIGH)||(digitalRead(down)==HIGH));
        
        if(digitalRead(zurueck)==HIGH)
        {
              screen('a');
              sel=0;
              run=0;
              start=1;
        }while(digitalRead(zurueck)==HIGH);
    }
    
        while(sel==1)
    {
      
        if(digitalRead(OK)==HIGH)
        {
             screen('g');
             sub=1;
        } while(digitalRead(OK)==HIGH);
        
        if((digitalRead(up)==HIGH)||(digitalRead(down)==HIGH))
        {
              screen('e');
              sel=3;
             
        } while((digitalRead(up)==HIGH)||(digitalRead(down)==HIGH));
        
        if(digitalRead(zurueck)==HIGH)
        {
              screen('b');
              sel=0;
              run=1;
              sub=0;
        }  while(digitalRead(zurueck)==HIGH);
    }
   
    
        while(sel==2)
    {
      
        if(digitalRead(OK)==HIGH)
        {
             screen('i');
        }while(digitalRead(OK)==HIGH);
        
        if((digitalRead(up)==HIGH)||(digitalRead(down)==HIGH))
        {
              while((digitalRead(up)==HIGH)||(digitalRead(down)==HIGH));
        }
        
        if(digitalRead(zurueck)==HIGH)
        {
              screen('c');
              sel=0;
              run=2;
              sub=0;
             
        }while(digitalRead(zurueck)==HIGH);
    }
   
       while(sel==3)
    {
      
        if(digitalRead(OK)==HIGH)
        {
             screen('h');
             sub=2;
         }while(digitalRead(OK)==HIGH);
        
        if((digitalRead(up)==HIGH)||(digitalRead(down)==HIGH))
        {
              screen('d');
              sel=1;
              
        }while((digitalRead(up)==HIGH)||(digitalRead(down)==HIGH));
        
        if(digitalRead(zurueck)==HIGH)
        {
              screen('b');
              run=1;
              
         }while(digitalRead(zurueck)==HIGH);
    }
   
       
  } 
  
void screen(unsigned char x)
{
    switch(x)
    {

	case 'a':
		lcd.clear();					
		lcd.setCursor(0,0);
                lcd.print("Willkommen");
		delay(800);
       	        lcd.setCursor(0,0);
                lcd.print("Bitte Enter");
                lcd.setCursor(1,1);
                lcd.print("druecken");
                
		break;

	case 'b':

		lcd.clear();
        	lcd.setCursor(0,0); 
                lcd.print("1> Wiskey   <");
                lcd.setCursor(0,1);
                lcd.print("2> Rum");
                delay(1000);
          	break;

        case 'c':
        
                lcd.clear();    
		lcd.setCursor(0,0);
                lcd.print("1> Wiskey");
		lcd.setCursor(0,1);
                lcd.print("2> Rum  <");
		break;
					

	case 'd':

		lcd.clear();
        	lcd.setCursor(0,0); 
                lcd.print("1> 2 cl  < ");
		lcd.setCursor(0,1);
                lcd.print("2> 4 cl");
		break;
/*
	case 'e':

		lcd.clear();
        	lcd.setCursor(0,0); 
                lcd.print("1> 2 cl ");
		lcd.setCursor(0,1);
                lcd.print("2> 4 cl     <");
		break;


	case 'f':

	        lcd.clear();
        	lcd.setCursor(0,0); 
                lcd.print("1> TRIGGER ");
		lcd.setCursor(0,1);
                lcd.print("OK value");
		break;
        case 'g':
                
                lcd.clear();
                lcd.setCursor(0,0);
                lcd.print("dist value");
                
   */             
                
         case 'h':
                 
                 
                lcd.clear();
                lcd.setCursor(0,0);
                lcd.print("2 cl");
                
    }
 }

Nimm dieses Menü: Projekt: LCDMenuLib / LCDMenuLib2 ( LCDML ) - Menü mit mehreren Ebenen - Deutsch - Arduino Forum

Da lernt er aber nicht wie er ein Menü selbst basteln kann. M.E. ist das das Ziel.

Dortmunder85:
Habt ihr eine einfache Idee.

Meine einfache Idee: Bevor man Ballett tanzen kann, sollte man geradeaus gehen können.

Und deshalb würde ich dafür plädieren, das Menü möglichst einfach zu halten: Also nicht vorwärts, rückwärts, seitwärts, ran, und dann noch ein paar Schritte zurück, halbe Drehung und eine Piroutte mit Sprung ins Plié.

Sondern das Ganze mit ein bisschen Struktur: Benannte Konstanten statt überall Zahlenwüste, Teilaufgaben in Funktionen untergliedert.

Dazu geradeaus, mein Vorschlag wäre ein Menü mit drei Knöpfen:

  • Button zur Getränkewahl (einfach zum Durchsteppen)
  • Button zur Mengenwahl (einfach zum Durchsteppen)
  • Button zum Starten (wenn Getränk und Menge gewählt sind, irgendwas starten, sonst nichts machen)
    Dann hättest Du den vierten Button noch frei für Sonderfunktionen.
#include <LiquidCrystal.h>

// Symbolische Konstanten für die Getränke
enum {KEINS, COLA, RUM, WASSER, WEIN, WEINBRAND, WHISKEY};
// LCD-Namen für die Getränke
char getraenkenamen[][10]={"Nichts","Cola", "Rum", "Wasser", "Wein", "Weinbrand", "Whiskey"};

// Symbolische Konstanten für die Mengen
enum {NICHTS, CL2, CL4};
// LCD-Namen für die Mengen
char mengennamen[][4]={"---","2CL", "4CL"};

// Symbolische Konstanten für die Buttons
enum {GETRAENKEWAHL, MENGENWAHL, FREIERBUTTON, START};
// I/O-Pins für die Buttons
byte buttons[]={A1, A2, A3, A4};
byte buttontype= INPUT_PULLUP;  // may be INPUT or INPUT_PULLUP

LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  lcd.begin(16,2);
  for (int i=0;i<4;i++)
  {
    pinMode(buttons[i],buttontype);
  }
  lcdWelcome();
}

void lcdWelcome()
{
  lcd.clear();
  lcd.print("Willkommen"); 
  lcd.setCursor(0,1);
  lcd.print("Ihre Auswahl?");
}

int getButton()
{
  static boolean oldStatus[]={false,false,false,false};
  boolean newStatus;
  int i;
  for (i=0;i<4;i++)
  {
    newStatus=digitalRead(buttons[i]);
    if (buttontype==INPUT_PULLUP) newStatus=!newStatus;
    if (newStatus==HIGH &&  oldStatus[i]==false)
    {
      oldStatus[i]=true;
      delay(5);
      return i;
    }  
    else if (newStatus==LOW && oldStatus[i]==true)
     oldStatus[i]=false;
  }
  return -1;
}

void doMenu(byte &getraenk, byte &menge)
{
  int button=getButton();
  if (button<0) return;
  switch (button)
  {
  case GETRAENKEWAHL: getraenk++;
                      if (getraenk>WHISKEY) getraenk=KEINS;
                      break;
  case MENGENWAHL:    menge++;
                      if (menge>CL4) menge=NICHTS; 
                      break;
  case START: if (getraenk!=KEINS && menge !=NICHTS)
              {
                doCocktail(getraenk,menge);
                return;  
              }
              else return;
  }                    
  lcd.clear();
  lcd.print(getraenkenamen[getraenk]);
  lcd.setCursor(0,1);
  lcd.print(mengennamen[menge]);
}

void doCocktail(byte getraenk, byte menge)
{ 
  char linebuf[17];
  lcd.clear();
  lcd.print(getraenkenamen[getraenk]);
  lcd.setCursor(0,1);
  lcd.print("mixen...");
  delay(5000);
  lcd.setCursor(0,1);
  lcd.print("ready!  ");
  delay(5000);
  lcdWelcome();
}

void loop() {
  // put your main code here, to run repeatedly: 
  static byte getraenk, menge;
  doMenu(getraenk, menge);
}

Die im wesentlichen anzupassenden Zeilen in dem Test-Sketch wären:

byte buttons[]={A1, A2, A3, A4};
Da habe ich einfach die Analog-Buttons als Button-Pins verwendet, aber digitale Pins sind natürlich genau so möglich, wenn sie nicht schon vom LCD belegt sind.

byte buttontype= INPUT_PULLUP; // may be INPUT or INPUT_PULLUP
Zur Verwendung von Buttons mit internem PullUp-Widerstand auf INPUT_PULLUP setzen, und wenn Du externe PullDown-Widerstände an den Buttons verwendest, dann INPUT verwenden.

LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
Das wäre die Initialisierung für ein LCD-Keypad-Shield. Wenn Du das LCD anders angeschlossen hast, dann die entsprechenden Pins eintragen.

Hallo Jurs sorry das ich dein Post erst jetzt gelesen habe dein Code den du mir gegeben hast läuft SUPER.
Ich weiß garnicht wie ich mich bei dir für diese Mühe bedanken kann.
Ich freue mich echt riesig das es noch Personen wie dich gibt die Leuten wie mir helfen.
Vielen Vielen Dank!!

Dortmunder85:
Hallo Jurs sorry das ich dein Post erst jetzt gelesen habe dein Code den du mir gegeben hast läuft SUPER.
Ich weiß garnicht wie ich mich bei dir für diese Mühe bedanken kann.
Ich freue mich echt riesig das es noch Personen wie dich gibt die Leuten wie mir helfen.
Vielen Vielen Dank!!

Und ich dachte schon, Du hast diesen Thread nach dem Motto "keine Antwort ist auch eine Antwort" beendet, weil ich Dir ein Menü gepostet hatte, das viel einfacher gestrickt ist und mit nur 3 Buttons funktioniert, statt des von Dir nachgefragten komplexeren Menüs mit einer 4-Button-Steuerung.

Ich hatte mich jedenfalls von der Idee leiten lassen: Wenn das Gerät überhaupt nur drei Funktionen hat (Geränk wählen, Menge wählen, Aktion starten), dann sollte es im einfachsten Fall auch ausreichen, das mit nur drei Buttons zu steuern.

Freut mich, wenn's gefällt!
(Kann man natürlich noch optimieren, je nachdem was noch an Programmlogik drangestrickt werden soll)

Hallo Jury ich habe leider noch ein kleines Problem
Ich habe doch ein Arduino Mega mit Adafruit Motor Shield drauf. Somit sind die Eingänge vorne belegt.

Ich habe in deinen Code nun meine Motor Sequenz eingetragen. Nun ist es aber so wenn Ich das ganze auf mein Arduino schicke funktioniert weder das Menü aber der Motor bewegt sich ohne das ich das will.
Nehme ich die Motor Sequenz wieder raus funktioniert das Menü wieder.
Ich habe die befürchtung das an den vorderen Eingängen irgendein Signal an das Motorshield gegeben wird ohne das ich das will.
Habe mal ein Bild als Anhang damit du sehen kannst wie das ganze gesteckt ist und welche Eingänge somit belegt sind.

Hier der Code mit Motor Sequenzen

#include <LiquidCrystal.h>
#include <AFMotor.h>


//AF_Stepper motor1(200, 1);



#define RS 32
#define E  33
#define D4 34
#define D5 35
#define D6 36
#define D7 37
#define COLS 16
#define ROWS 2
LiquidCrystal lcd(RS, E, D4, D5, D6, D7);


int Led1 = 28; 
int Taster1 = 27;                    // Taster1 - wird an Pin 8 initialisiert
int TasterStatus;

// Symbolische Konstanten für die Getränke
enum {KEINS, COLA, RUM, WASSER, WEIN, WEINBRAND, WHISKEY};
// LCD-Namen für die Getränke
char getraenkenamen[][10]={"Nichts","Cola", "Rum", "Wasser", "Wein", "Weinbrand", "Whiskey"};

// Symbolische Konstanten für die Mengen
enum {NICHTS, CL2, CL4};
// LCD-Namen für die Mengen
char mengennamen[][4]={"---","2CL", "4CL"};

// Symbolische Konstanten für die Buttons
enum {GETRAENKEWAHL, MENGENWAHL, FREIERBUTTON, START};
// I/O-Pins für die Buttons
byte buttons[]={24, 25, 26, 27};
byte buttontype= INPUT_PULLUP;  // may be INPUT or INPUT_PULLUP


void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  
pinMode(Led1, OUTPUT); 
pinMode(Taster1, INPUT); 

// motor1.setSpeed(30);  // 10 rpm 
 

  lcd.begin(16,2);
  for (int i=0;i<4;i++)
  {
    pinMode(buttons[i],buttontype);
  }
  lcdWelcome();
}

void lcdWelcome()
{
  lcd.clear();
  lcd.print("Willkommen"); 
  lcd.setCursor(0,1);
  lcd.print("Ihre Auswahl?");
}

int getButton()
{
  static boolean oldStatus[]={false,false,false,false};
  boolean newStatus;
  int i;
  for (i=0;i<4;i++)
  {
    newStatus=digitalRead(buttons[i]);
    if (buttontype==INPUT_PULLUP) newStatus=!newStatus;
    if (newStatus==HIGH &&  oldStatus[i]==false)
    {
      oldStatus[i]=true;
      delay(5);
      return i;
    }  
    else if (newStatus==LOW && oldStatus[i]==true)
     oldStatus[i]=false;
  }
  return -1;
}

void doMenu(byte &getraenk, byte &menge)
{
  int button=getButton();
  if (button<0) return;
  switch (button)
  {
  case GETRAENKEWAHL: getraenk++;
                      if (getraenk>WHISKEY) getraenk=KEINS;
                      break;
  case MENGENWAHL:    menge++;
                      if (menge>CL4) menge=NICHTS; 
                      break;
  case START: if (getraenk!=KEINS && menge !=NICHTS)
              {
                doCocktail(getraenk,menge);
                return;  
              }
              else return;
  }                    
  lcd.clear();
  lcd.print(getraenkenamen[getraenk]);
  lcd.setCursor(0,1);
  lcd.print(mengennamen[menge]);
}

void doCocktail(byte getraenk, byte menge)
{ 
  char linebuf[17];
  lcd.clear();
  lcd.print(getraenkenamen[getraenk]);
  lcd.setCursor(0,1);
  lcd.print("mixen...");
  delay(5000);
  lcd.setCursor(0,1);
  lcd.print("Fertig!  ");
  delay(5000);
  lcdWelcome();
}

void loop() {
  // put your main code here, to run repeatedly: 
  static byte getraenk, menge;
  doMenu(getraenk, menge);
  
  Serial.println(getraenk);
  
   TasterStatus = digitalRead(Taster1);
   
  if(Taster1 == HIGH && getraenk == 2)
  
//  motor1.step(50, FORWARD, DOUBLE);<------- Motor Sequenz
 delay(1000);

//motor1.step(50, BACKWARD, DOUBLE);   <------- Motor Sequenz
delay(1000);

sany2229.jpg

Benutze bitte die [ code ] [ / code ] Tabs
Grüße Uwe