Reading multiple Digital Buttons

So im trying to create a menu interface on my lcd that I have. I've been doing lots of research and the code is driving me bonkers. I'm hoping im going in the right direction, im trying to make it so when a button is pressed it displays a number on the screen. As it sits right now im just trying to get a good way of reading what button was pressed and return a value to the main function. Any input is greatly appreciated.

As it is right now i think my case statement is wrong cause it displays both the text lines on the lcd and doesn't wait for the button input to change.

The Code:

  #include <string.h>
  #include <avr/pgmspace.h>
  #include "SystemFont5x7.h"    // system font
  #include <ks0108.h>           // LCD
  
  prog_char string_0[] PROGMEM =   "1. Enter User ID";  //0
  prog_char string_1[] PROGMEM =   "2. Thanks for the Input!";  //1
  prog_char string_2[] PROGMEM =   "3.";  //2
  prog_char string_3[] PROGMEM =   "4.";  //3
  prog_char string_4[] PROGMEM =   "5.";  //4
  prog_char string_5[] PROGMEM =   "6.";  //5
  prog_char string_6[] PROGMEM =   "7.";
  prog_char string_7[] PROGMEM =   "8.";
  prog_char string_8[] PROGMEM =   "9.";
  prog_char string_9[] PROGMEM =   "10.";
  prog_char string_10[] PROGMEM =   "11.";
  
  PGM_P PROGMEM StringTable[] = 
  {
    string_0, string_1, string_2, string_3, string_4, string_5, string_6, string_7, string_8, string_9, string_10
  };

  
  #define escBtn 42
  #define button1 43
  #define button2 44
  #define button3 45
  
  int state[4];

  
  void setup()                    // run once, when the sketch starts
  {
    UnitSetup(); //get the screen up and running
    MainMenu();
    pinMode(escBtn,INPUT);
  }
  
  void loop()                                       // run over and over again
  {

  }
  
  void MainMenu() 
  {
    byte whichkey, Screen = 0;
    whichkey = PollKey();
    
    do 
    {           
      switch(Screen) 
      {
        case 1:
          GLCD.GotoXY(5,10); 
          PrintLCD_P(0);          
          if (digitalRead(escBtn) == HIGH)
          {
            Screen++;
          }
        case 2:
          GLCD.GotoXY(5,10); 
          PrintLCD_P(1);
          if (digitalRead(escBtn) == HIGH)
            {
              Screen++;
            }
        
        case 3:
        break;
      }
               
    } while (digitalRead(button1) != HIGH);
  }
  
  byte UnitSetup() 
  {
    GLCD.Init(NON_INVERTED);   // initialise the library, non inverted turns on written pixels
    GLCD.ClearScreen(); 
    GLCD.SelectFont(System5x7);
      
    pinMode(escBtn,INPUT);        //set pin as input
 
  } 

  void PrintLCD_P(int which) 
  {
     char buffer[21];
     strcpy_P(buffer, StringTable[which]);
     GLCD.Puts(buffer);
     delay(40);
  }
  
  char PollKey() 
  {
    
    
    /*char whichkey;
    
    if (digitalRead(escBtn) == HIGH)
    { 
      //whichkey = 1;
    }
    if (digitalRead(button1) == HIGH)
    { 
      
    }
    if (digitalRead(button2) == HIGH)
    { 
      
    }
    if (digitalRead(button3) == HIGH)
    { 
      
    }

    
    return whichkey;*/
  }

You did not switch all button pins to input. And you did not enable the pullup resistors.

Udo

You need some "break"s in your switch/ case, probably.

doesn't wait for the button input to change

Maybe because you've commented-out all the code in the key polling routine?

I don't know what you mean enabled the pull up resistors. the resistors are wired with a resistor in circuit so its low to start. I also changed the code to enable all the buttons as input but still the code doesn't seem right, nothing on the screen still when using the switch/cases.

  #include <string.h>
  #include <avr/pgmspace.h>
  #include "SystemFont5x7.h"    // system font
  #include <ks0108.h>           // LCD
  
  prog_char string_0[] PROGMEM =   "1. Enter User ID";  //0
  prog_char string_1[] PROGMEM =   "2. Thanks for the Input!";  //1
  prog_char string_2[] PROGMEM =   "3.";  //2
  prog_char string_3[] PROGMEM =   "4.";  //3
  prog_char string_4[] PROGMEM =   "5.";  //4
  prog_char string_5[] PROGMEM =   "6.";  //5
  prog_char string_6[] PROGMEM =   "7.";
  prog_char string_7[] PROGMEM =   "8.";
  prog_char string_8[] PROGMEM =   "9.";
  prog_char string_9[] PROGMEM =   "10.";
  prog_char string_10[] PROGMEM =   "11.";
  
  PGM_P PROGMEM StringTable[] = 
  {
    string_0, string_1, string_2, string_3, string_4, string_5, string_6, string_7, string_8, string_9, string_10
  };

  
  #define escBtn 42
  #define button1 43
  #define button2 44
  #define button3 45
  
  int state[4];

  
  void setup()                    // run once, when the sketch starts
  {
    UnitSetup(); //get the screen up and running
    MainMenu();
  }
  
  void loop()                                       // run over and over again
  {

  }
  
  void MainMenu() 
  {
    byte whichkey, Screen = 0;
    whichkey = PollKey();
    
    do 
    {           
      switch(Screen) 
      {
        case 1:
          GLCD.GotoXY(5,10); 
          PrintLCD_P(0);          
          if (digitalRead(escBtn) == HIGH)
          {
            Screen++;
          }
        case 2:
          GLCD.GotoXY(5,10); 
          PrintLCD_P(1);
          if (digitalRead(escBtn) == HIGH)
            {
              Screen++;
            }
        
        case 3:
        break;
      }
               
    } while (digitalRead(button1) != HIGH);
  }
  
  byte UnitSetup() 
  {
    GLCD.Init(NON_INVERTED);   // initialise the library, non inverted turns on written pixels
    GLCD.ClearScreen(); 
    GLCD.SelectFont(System5x7);
      
    pinMode(escBtn,INPUT);    //set pin as input
    pinMode(button1,INPUT);
    pinMode(button2,INPUT);
    pinMode(button3,INPUT);
 
  } 

  void PrintLCD_P(int which) 
  {
     char buffer[21];
     strcpy_P(buffer, StringTable[which]);
     GLCD.Puts(buffer);
     delay(40);
  }
  
  char PollKey() 
  {
    
    
    /*char whichkey;
    
    if (digitalRead(escBtn) == HIGH)
    { 
      //whichkey = 1;
    }
    if (digitalRead(button1) == HIGH)
    { 
      
    }
    if (digitalRead(button2) == HIGH)
    { 
      
    }
    if (digitalRead(button3) == HIGH)
    { 
      
    }

    
    return whichkey;*/
  }

You need some "break"s in your switch/ case, probably.


I had them all there but nothing, how does the break statement work, because I can't have it running through the same case the whole time, it will flicker my lcd text.

Could you maybe restructure that last sentence so that is understandable?

Let me rephrase :slight_smile:

How does the break; command work?

Follow the example http://arduino.cc/en/Reference/SwitchCase: Include "break;" as the last item before your next "case"

The other problem, not related to switch-case-break is that you have no "idle" state, ie, dont call the LCD stuff unless one of the menubuttons has changed state since the last time through the loop. (and include a debounce interval, too)

Ok so I added the debounce, and played around with the code a bit its starting to look alright.

Thanks for the help :slight_smile: