Arduino has 13 digital I/O pins and in this D10, D11 and D12 is reserved for action buttons. Others can be classified as output. Here I am using I2C module with 16x2 LCD which is a very great choice it reduce the number of connections. Using this we can display anything on screen via 2 wire interface connected on A4(SDA) and A5(SCL). Up, down and select buttons are internally pulled up and only a single 5v battery is needed as a power source. I want to make a vending machine for chips and chocolates. 

But for this I have to combine a lot of electronics and mechanical parts together and one of them is LCD interface. That’s why I am learning how to make a simple LCD user interface to select a variety of things from menu. Here for now I am using 3 button LCD interface controlled by Arduino UNO/NANO to control four LED lights. The circuit is very simple and a very few components are required for it. It is my first LCD menu project and in future I will come with more version of the same project.

Either we can use a better screen like OLED and TFT or a better selecting knob instead of tactile buttons. A rotatory encoder is the best option of it. I am using my own made Arduino Nano which is designed by me and PCB fabricated from Custom PCB service.

Components required:

  • I2C 16x2 LCD screen
  • Arduino NANO/UNO
  • Tactile switches
  • Battery
  • Connecting wires, Breadboard or PCB

Circuit diagram:

Arduino has 13 digital I/O pins and in this D10, D11 and D12 is reserved for action buttons. Others can be classified as output. Here I am using I2C module with 16x2 LCD which is a very great choice it reduce the number of connections. Using this we can display anything on screen via 2 wire interface connected on A4(SDA) and A5(SCL). Up, down and select buttons are internally pulled up and only a single 5v battery is needed as a power source.

Output LEDs can be connected as per mentioned digital pins in the code. And for now these four LEDs are connected on Digital pin D3, D4, D5 and D6.

Arduino Code Explained:

1) First I initialize the code by defining the libraries, wire for I2C and Liquidcrystal for LCD. These libraries can be installed from manage library section under tools menu.

#include <Wire.h>
#include <LiquidCrystal_I2C.h>

2) The all the input, output pins and counter is defined with initial positions.

LiquidCrystal_I2C lcd(0x27, 16, 2);
int upButton = 10;
int downButton = 11;
int selectButton = 12;
int menu = 1;
int LedOut1 = 3;
int LedOut2 = 4;
int LedOut3 = 5;
int LedOut4 = 6;
int Timer = 0;
int Timer_1 = 0;
int Timer2 = 0;
int Timer3 = 0;

3) Next step is to define the pin as input/ output and LCD startup routines.

lcd.init();
  lcd.backlight();
  pinMode(upButton, INPUT_PULLUP);
  pinMode(downButton, INPUT_PULLUP);
  pinMode(selectButton, INPUT_PULLUP);
  pinMode(LedOut1, OUTPUT);
  pinMode(LedOut2, OUTPUT);
  pinMode(LedOut3, OUTPUT);
  pinMode(LedOut4, OUTPUT);

4) To start with the main code I defined a counter menu with function updateMenu() in loop area. In this function the menu kept increasing and switch with case program is used.

void updateMenu() {
  switch (menu) {
    case 0:
      menu = 1;
      break;
    case 1:
      lcd.clear();
      lcd.print(">LED1");
      lcd.setCursor(0, 1);
      lcd.print(" LED2");
      break;
    case 2:
      lcd.clear();
      lcd.print(" LED1");
      lcd.setCursor(0, 1);
      lcd.print(">LED2");
      break;
    case 3:
      lcd.clear();
      lcd.print(">LED3");
      lcd.setCursor(0, 1);
      lcd.print(" LED4");
      break;
    case 4:
      lcd.clear();
      lcd.print(" LED3");
      lcd.setCursor(0, 1);
      lcd.print(">LED4");
      break;
    case 5:
      menu = 4;
      break;
  }
}

Loop section is used for switching detection. And a small delay is required between each step so that there will be no false triggering.

void loop() {
  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();
...
Read more »