Keypad
Arduino boards can take alphanumeric character inputs from human interaction devices such as a keypad. A circuit can be designed to act as an electronic access control device to open a door or other physical barrier using a code input using a keypad.
Keypads are available in multiple sizes, with keys laid out as rows and columns. Each key on the keypad can be individually identified when pressed and the program can determine what number or a letter of the alphabet each key should be considered as.
For this project we will use a 4x4 keypad.
Components
Component | Purpose |
---|---|
Arduino Nano | The microcontroller |
4x4 keypad | Keypad for input |
Circuit Diagram

Connections
4x4 keypad pins
Nano Pin | Keypad Pin |
---|---|
D9 | R1 |
D8 | R2 |
D7 | R3 |
D6 | R4 |
D2 | C1 |
D3 | C2 |
D4 | C3 |
D5 | C4 |
Code
/*
Project: Physical Computing
Circuit: Keypad
Boards Supported: UNO R3/R4, Nano, ESP32
Function: The projects reads characters input from a keypad.
Author: STEMVentor Educonsulting
This code is copyrighted. Please do not reuse or share for any purpose other than for learning with subscribed STEMVentor programs. This code is for educational purposes only and is not for production use.
*/
// LIBRARIES
// Install library "Keypad" by Mark Stanley and Alexander Brevig.
#include <Keypad.h>
// PIN DEFINITIONS
// This pin definition is as required by the keypad library.
// For Arduino Nano
// In the generic keypad module used, the upper four pins are column pins in reverse order
// and the lower four pins are row pins in correct order.
// If row and column pins are not clearly printed on the keypad you will have to try various combinations.
uint8_t row_pins[keypad_rows] = { 6, 7, 8, 9 }; // R1, R2, R3, R4
uint8_t col_pins[keypad_cols] = { 5, 4, 3, 2 }; // C1, C2, C3, C4
// For ESP32
// byte row_pins[ROW_NUM] = {13, 12, 14, 27};
// byte col_pins[COLUMN_NUM] = {32, 33, 35, 26};
// CONSTANT DEFINITIONS
#define KEYPAD_ROWS 4
#define KEYPAD_COLS 4
// GLOBAL VARIABLES
// The values returned by a 4x4 matrix keypad are mapped to the key layout as below.
// A keypad with a printed membrane will indicate the character each key should be mapped to.
// For a generic keypad without membrane the keys will be numbered S1-S16 (or equivalent)
// and can be mapped as required with the mapping below.
char keys[KEYPAD_ROWS][KEYPAD_COLS] = {
{ '1', '2', '3', 'A' },
{ '4', '5', '6', 'B' },
{ '7', '8', '9', 'C' },
{ '*', '0', '#', 'D' }
};
// Used for reading entered key.
String received_key;
/* INITIALIZE OBJECTS
* Libraries usually follow an object-oriented approach that requires
* an instance of the class to call its methods.
*/
Keypad keypad = Keypad(makeKeymap(keys), row_pins, col_pins, KEYPAD_ROWS, KEYPAD_COLS);
/* LOCAL FUNCTIONS */
// Read a single key press value.
char readKey(){
char key_value = keypad.getKey(); //to read the key/character entered
while(key_value == NO_KEY) {
key_value = keypad.getKey(); //keep on reading till a new character is entered
}
return key_value;
// For some reason the key needs to be stored into another variable else it does not print.
// received_key = key;
// Serial.println("Key pressed: " + received_key);
// return received_key;
}
// String together multiple key press values until a # is pressed (exclude the #).
// Pass the minimum and maximum sequence lengths as parameters. (0,0) => no limits.
String readKeySequence(uint8_t min_length, uint8_t max_length){
String key_sequence = "";
char key_pressed = "";
Serial.println("Press a sequence of keys on the keypad, end with a #:");
do {
key_pressed = readKey();
// Check if # is pressed before the minimum key sequence length has been input.
if(key_pressed == "#" && key_sequence.length() < min_length){
Serial.print(" Key Sequence must be " + String(min_length) + " values minimum. ");
// Discard the #
key_pressed = "";
} else if(key_pressed != "#"){
// Serial.print(key_pressed);
key_sequence = key_sequence + key_pressed;
}
// Check if the maximum key sequence length has been input (end by making the key press a #)
if(key_sequence.length() >= max_length){
Serial.print(" Maximum Key Sequence of " + String(max_length) + " values has been input.");
key_pressed = "#";
}
} while(key_pressed != "#");
// Serial.println();
// Serial.println(key_sequence);
return(key_sequence);
}
/* SETUP CODE: runs once when the board starts up or resets */
void keypadSetup()
{
// Start the serial communication with baud rate suitable for your components.
Serial.begin(9600);
Serial.println("The keypad is ready!");
}
/* MAIN LOOP: runs repeatedly at a very high frequency (1000s of times a second) */
void loop() {
String key_sequence_entered = readKeySequence(4,6);
Serial.println("Key sequence entered: " + key_sequence_entered)
}