Arduino LCD Keypad Shield – Basic Menu System

LCD1After recently purchasing an LCD and Keypad Shield for my Arduino Uno. I thought I best test it out and write a quick sketch to use with it.

The shield has a 16×2 (LCD1602) LCD and 6 Button Keypad , extremely useful for controlling your projects without hooking the Arduino board up to anything. I believe this cost me just under £4 delivered and is well worth the money.

I have made a basic options selection menu which will allow you to scroll through a list of entries and select one of them, using the least amount of screen updates. It doesn’t yet support sub-menus, but it’s dead easy to implement using this code found below.

For reference the allocation of pins for the LCD Shield are the following (also found on the DFRobot website shown below):

PinFunction
Analog 0Button (select, up, right, down and left)
Digital 4DB4
Digital 5DB5
Digital 6DB6
Digital 7DB7
Digital 8RS (Data or Signal Display Selection)
Digital 9Enable
Digital 10Backlit Control

You can find a data sheet and schematic for this shield from the DFRobot website by clicking here. Once you have hooked it up to the Arduino, you can select any of the example sketches from the Arduino IDE under Examples > LiquidCrystal

Before you can use any of the examples you need to change the default pin allocation in the code. The correct allocation for this LCD Shield is the following:

After changing this in the examples you should now be able to run any of the provided example code and have the information sent to your LCD.

Now for something a little different…. menus!

Now that you have verified the LCD is in-fact working as it should. We will take a look at creating a basic menu system. All this does is assign each menu entry an integer number, then the up and down button will change this value accordingly. If this value is different from the last value it processed then something has changed and should trigger the screen to update.

The complete sketch for a basic menu system is below.

The menu is very basic, scrolling through entries and using the select button to trigger an option. Once an option has been triggered and displayed on screen then you can carry on pressing up or down to go through the menu again and select another item.

This will use the least amount of updates to the LCD screen; as we don’t want it updating the LCD on every loop cycle – It only checks if the previous state does not equal the current state. Screenshots of the menu are shown below (apologies the photos are not great):

LCD2       LCD3

If you have any questions or would like to show off your LCD please feel free to leave a comment below and we’ll get back to you.

Email this to someoneShare on Google+Pin on PinterestTweet about this on TwitterShare on RedditShare on Facebook

11 thoughts on “Arduino LCD Keypad Shield – Basic Menu System

  1. Hi I’m trying to create a menu system with submenus but have run into some trouble trying to get it to work. Is it possible to do using just switch and case like you did here? or should I be going about it another way?

  2. Get problem data not update / looping ,, i try to make counter button using your display menu,

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

    int currentMenuItem = 0;
    int lastState = 0;

    //COUNTER 1
    int switchPin1 =2; // choose the input pin (for a pushbutton)
    int val1 = 0; // variable for reading the pin status
    int counter1 = 0;
    int currentState1 = 0;
    int previousState1 = 0;

    void setup() {
    Serial.begin(9600);
    lcd.begin(16, 2); // start the library
    clearPrintTitle();
    pinMode(switchPin1, INPUT); // declare pushbutton as input

    }

    void loop(){
    mainMenu();
    counter();

    }

    void mainMenu() {
    //State = 0 every loop cycle.
    int state = 0;
    //Refresh the button pressed.
    int x = analogRead (0);
    //Set the Row 0, Col 0 position.
    lcd.setCursor(0,0);

    //Check analog values from LCD Keypad Shield
    if (x < 50) {
    //Right
    } else if (x < 250) {
    //Up
    state = 1;
    } else if (x < 450){
    //Down
    state = 2;
    } else if (x < 650){
    //Left
    } else if (x < 850){
    //Select
    state = 3;
    }

    //If we are out of bounds on th menu then reset it.
    if (currentMenuItem = 4) {
    currentMenuItem = 0;
    }

    //If we have changed Index, saves re-draws.
    if (state != lastState) {
    if (state == 1) {
    //If Up
    currentMenuItem = currentMenuItem – 1;
    displayMenu(currentMenuItem);
    } else if (state == 2) {
    //If Down
    currentMenuItem = currentMenuItem + 1;
    displayMenu(currentMenuItem);
    } else if (state == 3) {
    //If Selected
    selectMenu(currentMenuItem);
    }
    //Save the last State to compare.
    lastState = state;
    }
    //Small delay
    delay(5);
    }

    //Display Menu Option based on Index.
    void displayMenu(int x) {
    switch (x) {
    case 1:
    clearPrintTitle();
    lcd.print (“->Counter 1 – 2″);
    break;
    case 2:
    clearPrintTitle();
    lcd.print (“->Counter 3 – 4″);
    break;
    case 3:
    clearPrintTitle();
    break;
    }
    }

    //Print a basic header on Row 1.
    void clearPrintTitle() {
    lcd.clear();
    lcd.setCursor(2,0);
    lcd.print(“Select Menu”);
    lcd.setCursor(0,1);

    }

    void menu_counter(){
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print(“C1:”);
    lcd.setCursor(10,0);
    lcd.print(counter1);

    }

    //Show the selection on Screen.
    void selectMenu(int x) {
    switch (x) {
    case 1:
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print(counter1);

    break;
    //Call the function that belongs to Option 1
    case 2:
    lcd.setCursor(0,0);
    lcd.print(“Good”);
    //Call the function that belongs to Option 2
    break;

    }
    }

    void counter(){
    val1 = digitalRead(switchPin1); // read input value

    if (val1 == HIGH) { // check if the input is HIGH (button released)
    currentState1 = 1;
    }
    else {
    currentState1 = 0;
    }

    if(currentState1 != previousState1){
    if(currentState1 == 1){
    counter1++;
    //Serial.println(counter1);
    //lcd.print(counter1);
    }
    }

    previousState1 = currentState1;
    delay(10);

    }

  3. Hi,
    Im lost, how can i use this with submenu and user input options please? simple example would be a great help!

  4. Really nice guide!
    A Question how can i restart the menu?
    Like if have a function called from 3
    “//Call the function that belongs to Option 3″
    When the function is finished i want to restart the menu system…

    • @ Peter E

      What i did to reset the menu, isn’t actually a reset, but a return to last place on the menu..
      What i did was add a small delay after the lcd.print on the case in the selectMenu (purely cosmetic to let the user know something actually happened)
      Then i added clearPrintTitle(); to clear the screen
      Then i added displayMenu(currentMenuItem); to resume function of the menu

      so this does the following:
      user is at option 3
      user clicks select
      screen shows “Item 3 used….” for 2500ms
      screen clears
      screen is back at option 3, waiting for user input

  5. i have error when uploading the code:

    are there any library that i need to include?
    This report would have more information with
    “Show verbose output during compilation”
    enabled in File > Preferences.
    Arduino: 1.0.6 (Windows 7), Board: “Arduino Mega 2560 or Mega ADK”
    sketch_feb13a:1: error: expected constructor, destructor, or type conversion before ‘<' token
    sketch_feb13a.ino: In function 'void setup()':
    sketch_feb13a:12: error: 'lcd' was not declared in this scope
    sketch_feb13a.ino: In function 'void mainMenu()':
    sketch_feb13a:28: error: 'lcd' was not declared in this scope
    sketch_feb13a.ino: In function 'void displayMenu(int)':
    sketch_feb13a:77: error: 'lcd' was not declared in this scope
    sketch_feb13a.ino: In function 'void clearPrintTitle()':
    sketch_feb13a:96: error: 'lcd' was not declared in this scope
    sketch_feb13a.ino: In function 'void selectMenu(int)':
    sketch_feb13a:107: error: 'lcd' was not declared in this scope
    sketch_feb13a:124: error: expected }' at end of input
    sketch_feb13a:124: error: expected
    }' at end of input

  6. How would one go about having sub-menu items with this?

    i.e.
    Menu:
    Option 1 -> [subOption1, subOption2, subOption3, subOption4]
    Option 2
    Option 3 -> [subOption1, subOption2]

    The reason i ask, is i plan on using the LCD keypad to send commands to GRBL over serial.
    so menu would really be something like:
    Jog X -> [+100, -100, +10, -10] //sends command to grbl : G0 X100.000 F2500
    Reset GRBL // Sends command to grbl : CTRL+X
    Pause/Resume -> [Pause Job, Resume Job] //sends command to grbl ~ / !

    The command part i can do, just wondering what you think would be the best way to impliment this.
    I ask, because in your code, you reset the menu when scrolling past option 4, so i’m not sure how to go about adding submenu items, without losing that functionality.

Leave a Reply to nisya Cancel reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">