Built-in project · Arduino Uno R3

LCD keypad shield buttons on an Arduino Uno

An LCD keypad shield on an Uno: press its five buttons and the LCD names the one held, with the reading on A0 that gave it away. The whole build, an Arduino Uno and 1 more part, runs here in your browser on the firmware below; open it in the editor to change the wiring or the code and run it again.

Teaching? Assign it to your class in one click.

Beginner About 15 minutes to build and run. Runs in your browser. Free, and no account needed.

The parts retail for about $31. On Mokxi they're free.

The circuit runs here once the page has loaded.

What you'll learn

  • Many buttons share one analog pin
  • A resistor ladder makes distinct voltages
  • Using thresholds between expected values
  • Using a shield with a fixed pin layout
  • Difficulty: Beginner
  • Time: About 15 minutes
  • Board: Arduino Uno R3
  • Parts: 2

How it works

The LCD keypad shield has a 16x2 screen and five buttons, and uses only one analog pin for all five buttons. They sit on a ladder of resistors, so each button makes A0 read a different voltage.

Roughly, RIGHT reads about 0, UP 144, DOWN 329, LEFT 505, SELECT 741, and 1023 when none are held. The sketch picks the closest by comparing the reading with the halfway points between them.

The LCD uses pins 4 to 9, set in LiquidCrystal lcd(8, 9, 4, 5, 6, 7). The top line says "Press a button", and the bottom shows the button name and the raw number.

Parts list

2 parts, plus the jumper wires. They retail for about $31; on Mokxi they're free.

Wiring table

Every connection, pin by pin, read from the circuit itself. Each row joins the pin on the left to the pin on the right, by a jumper wire or a breadboard strip.

Part and pinConnects to
LCD keypad shield pin D9Arduino Uno R3 pin 9
LCD keypad shield pin D8Arduino Uno R3 pin 8
LCD keypad shield pin D7Arduino Uno R3 pin 7
LCD keypad shield pin D6Arduino Uno R3 pin 6
LCD keypad shield pin D5Arduino Uno R3 pin 5
LCD keypad shield pin D4Arduino Uno R3 pin 4
LCD keypad shield pin 5VArduino Uno R3 pin 5V
LCD keypad shield pin GNDArduino Uno R3 pin GND
LCD keypad shield pin A0Arduino Uno R3 pin A0

The code

The firmware exactly as the editor opens it. Change a line there and press Run: it compiles in the browser.

sketch.ino · Arduino Uno R3
// The LCD keypad shield: a 16x2 LCD and five buttons on one analog pin.
//
//   LCD RS 8, E 9, D4..D7 on 4..7   (LiquidCrystal lcd(8, 9, 4, 5, 6, 7))
//   the buttons share A0 through a resistor ladder
//
// Each button shorts a different point of the ladder to ground, so A0 reads
// a different voltage for each: about 0 for RIGHT, 144 UP, 329 DOWN, 505
// LEFT, 741 SELECT and 1023 with none held. The sketch sorts a reading into
// the nearest one by the halfway points between them.

#include <LiquidCrystal.h>

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

const char *buttonAt(int reading) {
  if (reading < 72) return "RIGHT";
  if (reading < 237) return "UP";
  if (reading < 417) return "DOWN";
  if (reading < 623) return "LEFT";
  if (reading < 882) return "SELECT";
  return "none";
}

void setup() {
  lcd.begin(16, 2);
  lcd.print("Press a button");
}

void loop() {
  int reading = analogRead(A0);
  lcd.setCursor(0, 1);
  lcd.print(buttonAt(reading));
  lcd.print(" ");
  lcd.print(reading);
  lcd.print("      ");  // clear what a longer name left
  delay(100);
}

Code walkthrough

The key functions of the sketch, and what each one does.

buttonAt sketch.ino

Takes the A0 reading and returns a button name. It checks the ranges in order: under 72 is RIGHT, under 237 UP, under 417 DOWN, under 623 LEFT, under 882 SELECT, and anything higher is none.

const char *buttonAt(int reading) {
  if (reading < 72) return "RIGHT";
  if (reading < 237) return "UP";
  if (reading < 417) return "DOWN";
  if (reading < 623) return "LEFT";
  if (reading < 882) return "SELECT";
  return "none";
}

setup sketch.ino

Starts the LCD with 16 columns and 2 rows and prints "Press a button".

void setup() {
  lcd.begin(16, 2);
  lcd.print("Press a button");
}

loop sketch.ino

Reads A0, shows the name from buttonAt and the number on row 1, and pads with spaces to wipe any leftover letters. Then it waits 100 ms.

void loop() {
  int reading = analogRead(A0);
  lcd.setCursor(0, 1);
  lcd.print(buttonAt(reading));
  lcd.print(" ");
  lcd.print(reading);
  lcd.print("      ");  // clear what a longer name left
  delay(100);
}

Troubleshooting

The usual mistakes with this circuit, and the fix for each.

  • Old letters stay on the screen This project
    The spaces printed after the name clear them. Keep that line.
  • A button is read wrong This project
    The halfway points in buttonAt come from the typical shield. A different shield may need different numbers.
  • The screen is blank or shows only blocks. LCD keypad shield
    Turn the contrast trimmer on the shield. Use the LiquidCrystal library with the right pin order for your shield, since D4 to D9 are used by it. Check the backlight.
  • Buttons are misread. LCD keypad shield
    All five buttons share A0 as a voltage divider. Read analogRead(A0) and compare to ranges, and calibrate to your values. Pins D4 to D9 and A0 are taken, so plan other uses.
  • Upload fails or nothing runs after wiring pins 0 and 1 to a module. Arduino Uno R3
    Pins 0 and 1 are the USB serial port. Move the module to other pins, or unplug it while uploading. Also check the right board is selected.
  • Pins misbehave or the board resets when you power motors or servos from it. Arduino Uno R3
    Each I/O pin gives about 20 mA, 40 mA max. Power motors and servos from their own supply and join its ground to the Uno's GND.

Change it and keep it

Open it in the editor, change the circuit or the code, and keep your version in a free account.