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.
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.
- 1 × Arduino Uno R3In Starter Kit, Claw Machine Kit, Vending Machine Kit.
- 1 × LCD keypad shield
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 pin | Connects to |
|---|---|
| LCD keypad shield pin D9 | Arduino Uno R3 pin 9 |
| LCD keypad shield pin D8 | Arduino Uno R3 pin 8 |
| LCD keypad shield pin D7 | Arduino Uno R3 pin 7 |
| LCD keypad shield pin D6 | Arduino Uno R3 pin 6 |
| LCD keypad shield pin D5 | Arduino Uno R3 pin 5 |
| LCD keypad shield pin D4 | Arduino Uno R3 pin 4 |
| LCD keypad shield pin 5V | Arduino Uno R3 pin 5V |
| LCD keypad shield pin GND | Arduino Uno R3 pin GND |
| LCD keypad shield pin A0 | Arduino 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.
// 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 inbuttonAtcome 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.