Keypad Tutorial for Arduino and ESP8266

Keypad Tutorial for Arduino, ESP8266 and ESP32

In this tutorial you learn how to use the keypad with your Arduino, ESP8266 and also ESP32 microcontroller.

The Keypad is one of the most used input devices for Arduino applications.

In this tutorial we build a lock which opens when we type in the correct password.

Keypad Thumbnail

There are two different version of the keypad with the only difference in the number of buttons:

  • The version with 3 columns and 4 rows which includes the numbers 0 to 9 with the asterisk (*) and hashtag (#) button
  • I have the bigger version with 4 instead of 3 columns. The bigger version includes all buttons of the smaller version but has also buttons for the letters: A, B, C, D

Functionality of the Keypad Matrix

The keypad is internally build like a matrix with rows and columns. The you can identify a cell in an Excel sheet with the row and column number, the Arduino is able to identify the pressed button on the keypad. The following picture shows that the first 4 connectors identify the row number (R1, R2, R3, R4) and the last 3 to 4 connectors identify the column number (C1, C2, C3, C4), depending on the version of the keypad.

Keypad Pins

In the table on the right sight of the picture you see that if a button is pressed, the keypad field has a unique identifier, the row and column number. Therefore the microcontroller is able to identify the keypad field through a 4 step mechanism that is described with the following picture:

Keypad 4 step mechanism
  1. In the idle state, every row pin is set to LOW and every column pin is set HIGH
  2. If one button is pressed, the column of this button is connected to LOW and therefore the column pin is pulled from HIGH to LOW. → The column is found.
  3. Now every row is pulled HIGH individually, stating by R1. All columns are LOW.
  4. If the row, where the button is pressed is pulled HIGH, the column changes from LOW to HIGH. → The row is found.

Basic Example of Keypad

Now, after we know how the keypad works, we make a basic example. In this example we want to display the number which is pressed in the serial monitor. If this example is to easy for you, at the end of this article there is also a more advanced example where we build a password lock.

The following table gives you an overview of all components and parts that I used for this tutorial. If you want to support my work, you can by something from the following links and I will earn a commission This does not affect the price you pay for the products.

If you are interested in components and parts that I used in other tutorials, visit the components and parts page.

Wiring between microcontroller and keypad

The following picture shows the wiring between the following microcontroller and the keypad:

  • Arduino Uno
  • ESP266 NodeMCU
  • ESP32 NodeMCU

If you are interested how you can reduce the number of used digital I/O pins, click here and lean how to use a digital multiplexer.

Keypad Arduino

Keypad ESP8266

Keypad ESP8266

Under construction

For this example we use the Keypad library of Mark Stanley and Alexander Brevig which make the use of the keypad very easy. This library support the 3x4 and 4x4 keypad. If you do now know how to install a library, click here for a step by step tutorial.

After we wire everything up, let’s dive into the program code:

Keypad tutorial Arduino Code

#include "Keypad.h"
const byte ROWS = 4; //four rows
const byte COLS = 4; //four columns

char keys[ROWS][COLS] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}
};
byte rowPins[ROWS] = {9, 8, 7, 6}; 
byte colPins[COLS] = {5, 4, 3, 2}; 

Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);

void setup() {
  Serial.begin(9600);
}

void loop() {
  char key = keypad.getKey();

  if (key){
    Serial.println(key);
  }
}

In the first line we include the previous or already installed library Keypad. Then we define the number of rows and columns your keypad has. In my case I have to 4x4 keypad.
To be able to identify the keypad right we create a matrix with the keypad. If your keypad has a different layout, then you can change the layout with this matrix. Make sure that the number of rows and columns is right.
The last part in the section where we define the variables are the pins we use for the keypad. You can use every digital I/O pin on your microcontroller. In my case I used the pins 2 to 9 of the Arduino Uno.

Next the library Keypad has to know what keypad is connected to the microcontroller. Therefore we create an object called keypad from the library and pass the previous defined variables to this object.

For the setup function we define the baud rate to 9600. Make sure that the baud rate of your serial monitor in the Arduino IDE is also set to 9600.

In the loop function we first read the character which we get from the keypad and store this character in the key variable. If the key variable is not empty, we print the character to the serial output.

The following picture shows the numbers in the serial monitor.

Keypad Serial Output

Example of a Password Lock

Now the more advanced example where we build a lock which opens when we type in the correct password. In this example I use the keypad and an LCD display along with a microcontroller. You can use any microcontroller you want. In my case, I use the Arduino Uno.

The following picture shows the connection between the devices for the Arduino Uno and the ESP8266 as example. You see that we only connected the LCD display and that the magic happens inside the program code which I explain step by step in the following section. At the end of this section you can download the complete Arduino code as zip file.

#include "Keypad.h"
#include "Wire.h"
#include "LiquidCrystal_I2C.h"

const byte ROWS = 4; //four rows
const byte COLS = 4; //four columns

char keys[ROWS][COLS] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}
};

byte rowPins[ROWS] = {9, 8, 7, 6}; 
byte colPins[COLS] = {5, 4, 3, 2}; 

Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
LiquidCrystal_I2C lcd(0x27, 20, 4); 

The first part of the code is nearly the same, only we include the library of the LCD display LiquidCrystal_I2C.h and create an object of this library called lcd. I use a 20x4 LCD display on I2C address 0x27 for this example. If you use a different one, you have to change the parameters of the lcd object.

You can also visit my LCD display tutorial, where you learn everything you have to know about different LCD displays and how to use them.

const int len_key = 5;
char master_key[len_key] = {'1','2','3','4','1'};
char attempt_key[len_key];
int z=0;

For this example we define some new variables:

  • len_key is a constant which define the length of the password.
  • master_key is the array where we store the correct password.
  • attempt_key is the array where we store the characters the user inputs via the keypad.
  • z is the variable to point at the right place inside the master_key and attempt_key arrays, starting by 0. For example: char master_key[z=2] = 3.
void setup() {
  Serial.begin(9600);
  lcd.init();
  lcd.backlight();
  lcd.setCursor(0,0);
  lcd.print("Insert Password");
}

In the setup function we add new lines for the LCD display to turn the back light of the screen on and print “Insert Password” in the first line.

void loop() {
  char key = keypad.getKey();
  lcd.setCursor(z-1,1);
  lcd.print("*");
  if (key){
    switch(key){
      case '*':
        z=0;
        break;
      case '#':
        delay(100); // added debounce
        checkKEY();
        break;
      default:
         attempt_key[z]=key;
         z++;
      }
    
  }
}

The loop function starts with reading the character of the keypad. This is done by the getKey function of the previous created key object.

Because I want to see as user of the password lock how many characters I already typed in, we print an asterisk character for each character that was typed in by the user. Therefore we set the cursor for the LCD screen to z-1 and not z in the second row of the screen and print the asterisk character.

After the user entered a key, we come to a switch case logic in the program script because we want to execute different tasks, depending on the key the user entered:

  • If the input is “*” → we want to reset the input and start from the beginning to give the user the possibility to delete the previous inserts. Maybe the user mistype a character.
  • If the input is “#” → we want to check if the total key is valid with a checkKey function, that I explain in the next section.
  • Otherwise we add the character to the attempt_key array and increase the “pointer” of the attempt_key array to write the next input in the next place of the array.
void checkKEY()
{
   int correct=0;
   int i;
   for (i=0; i < len_key; i++) {
    if (attempt_key[i]==master_key[i]) {
      correct++;
      }
    }
   if (correct==len_key && z==len_key){
    lcd.setCursor(0,1);
    lcd.print("Correct Key");
    delay(3000);
    z=0;
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("Insert Password");
   }
   else
   {
    lcd.setCursor(0,1);
    lcd.print("Incorrect Key");
    delay(3000);
    z=0;
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("Insert Password");
   }
   for (int zz=0; zz<len_key; zz++) {
    attempt_key[zz]=0;
   }
}

In this checkKEY function we check if the current key in the attempt_key array is the same we saved in the master_key array.

First we create a new variable correct to count how many characters are the same between the attempt_key and master_key array. Therefore we check element by element of the array and if it is a match we increase the correct variable. Also we check if the length of the input key has the same length as the len_key. Otherwise a key like: [1,2,3,4,1,8] would be correct because the first elements compared character by character are valid.

After all elements are compared and the correct variable has the same length as the master_key, it is clear that the entered key was correct.
We print on the screen that the key was correct and wait for 3 seconds before we clear the screen and restart the request for a password.

If the key was incorrect we print this on the screen and also wait for 3 seconds before we clear the screen and restart the request for a password.

In any case we clear the previous key inputs and set the pointer of the attempt_key array to the first element 0.

 

If you want to download the whole Arduino script for this advanced keypad example as zip file, then click the download button below.

The following video shows the functionality of the keypad log.

  1. First I insert a wrong password.
  2. Then I type in the correct password.
  3. At the end I type in the wrong password but the first characters are the correct one. The password is too long.

Conclusion

I hope you liked this tutorial where you learned how to use the keypad as input device and build a lock which opens when we type in the correct password. If you want to reduce the number of used digital I/O pins, I recommend to read the article about the digital multiplexer.

What is your next project and will you use the keypad? Let me know in the comment section.
If you have any questions regarding this tutorial, use the comment section below to ask your questions. I answer them as soon as possible.

Leave A Comment