Learn to code

ARDUINO & CODES

Previous Post
Reliable detecting a switch with Arduino
Next Post
Reading analog values with Arduino

Reading a 4 x 4 keypad with Arduino

in Arduino Digital / Analog

In this tutorial, we will read the values of a keypad without using libraries. This tutorial is for those who want to understand how the keypad works. Firstly, we will learn how the keypad works. In other words, how a keypad detects key presses. An easy example is given by printing the key on the Serial Monitor. We are going to use a 3×4 matrix membrane keypad. 

Parts you will need

Arduino Uno Rev3 Arduino Uno Rev3 × 1
Keypad Keypad × 1
Dupont Wires Dupont Wires × 7

Arduinoplatform is a participant in several affiliate programs. This means that I will earn a commision if you buy a product from the affiliated websites through clicking on the links provided above.

How does the keypad work?

The buttons of each keypad are arranged in rows and columns. The keypad that we are using has 4 rows and 3 columns. Beneath each key is a switch. Each switch is connected with the other switches in the row.  Each row and columns should be connected to the Arduino. In total, we have 7 pins that we are going to connect.

The way that Arduino detects which button is pressed on the keypad is by detecting the row and columns pin that is detected to the button.

  1. If no buttons are pressed all of the column pins are HIGH and all of the rows are LOW.
  2. When a button is pressed, the column pin of the button is pulled LOW.
  3. The Arduino knows which column the button is in however it still needs to know the row. It does this by switching all the rows to HIGH, and at the same time reading the column pins to detect which column is HIGH.
  4. When the column pin is HIGH, the Arduino has found the row that is connected to the button.

BreadBoard Layout

This sketch will only work correctly if the wiring agrees with the code. Check carefully, as incorrect wiring can short out the pins, and that could damage your controller chip.

  1. Place the keypad next to the Arduino
  2. Look closely to the diagram, the wires should be connected according to the schematic. Otherwise, the keypad will not work
  3. Connect the Arduino Board with your computer.
  4. Open the Arduino IDE.
  5. Open a new sketch and copy-paste the code sketch code below
  6. Click the Verify button on the top left side of the screen to be sure that there are no problems
  7. Click the Upload button (next to the Verify button).
  8. Open the serial monitor window, you should see the number that you press on the Serial Monitor.

The Code

/*
  Keypad sketch
  prints the key pressed on a keypad to the serial port
*/
const int numRows = 4; // number of rows in the keypad
const int numCols = 3; // number of columns
const int debounceTime = 20; // number of milliseconds for switch to be stable
// keymap defines the character returned when the corresponding key is pressed
const char keymap[numRows][numCols] = {
  { '1', '2', '3' } ,
  { '4', '5', '6' } ,
  { '7', '8', '9' } ,
  { '*', '0', '#' }
};
// this array determines the pins used for rows and columns
const int rowPins[numRows] = { 7, 2, 3, 6 }; // Rows 0 through 3
const int colPins[numCols] = { 5, 8, 4 }; // Columns 0 through 2
void setup()
{
  Serial.begin(9600);
  for (int row = 0; row < numRows; row++)
  {
    pinMode(rowPins[row], INPUT); // Set row pins as input
    digitalWrite(rowPins[row], HIGH); // turn on Pull-ups
  }
  for (int column = 0; column < numCols; column++)
  {
    pinMode(colPins[column], OUTPUT); // Set column pins as outputs for writing
    digitalWrite(colPins[column], HIGH); // Make all columns inactive
  }
}
void loop()
{
  char key = getKey();
  if ( key != 0) { // if the character is not 0 then it's a valid key press
    Serial.print("Got key ");
    Serial.println(key);
  }
}
// returns with the key pressed, or 0 if no key is pressed
char getKey()
{
  char key = 0; // 0 indicates no key pressed
  for (int column = 0; column < numCols; column++)
  {
    digitalWrite(colPins[column], LOW); // Activate the current column.
    for (int row = 0; row < numRows; row++) // Scan all rows for a key press.
    {
      if (digitalRead(rowPins[row]) == LOW) // Is a key pressed?
      {
        delay(debounceTime); // debounce
        while (digitalRead(rowPins[row]) == LOW)
          ; // wait for key to be released
        key = keymap[row][column]; // Remember which key was pressed.
      }
    }
    digitalWrite(colPins[column], HIGH); // De-activate the current column.
  }
  return key; // returns the key pressed or 0 if none

Code Explanation

This code is a bit complicated if you are not familiar with Arduino. Each of the four rows on the keypad is connected to an input pin and each column is connected to an output pin. Since we will use the rows and columns of the keypad a lot we are declaring them as a constant variable at the beginning of the sketch. Furthermore, we declare a constant variable for debounce to be able to detect if the switch which is activated by the button is stable.

const int numRows = 4; // number of rows in the keypad
const int numCols = 3; // number of columns
const int debounceTime = 20; // number of milliseconds for switch to be stable

Secondly, we want to tell the Arduino if button “1” is pressed it will display “1” on the Serial Monitor. Therefore we need to declare variables that hold these values. This is done by creating a char variable named keymap that holds the values of the rows and columns of the keypad.

const char keymap[numRows][numCols] = {
  { '1', '2', '3' } ,
  { '4', '5', '6' } ,
  { '7', '8', '9' } ,
  { '*', '0', '#' }
};

We are starting serial communication between the Arduino and the computer

Serial.begin(9600);

 

The next part is to set all columns and rows HIGH to be able to know if the button is pressed.

for (int row = 0; row < numRows; row++)
  {
    pinMode(rowPins[row], INPUT); // Set row pins as input
    digitalWrite(rowPins[row], HIGH); // turn on Pull-ups
  }
  for (int column = 0; column < numCols; column++)
  {
    pinMode(colPins[column], OUTPUT); // Set column pins as outputs for writing
    digitalWrite(colPins[column], HIGH); // Make all columns inactive
  }

 

In the void loop() part of the sketch, the getkey function is used. getkey sets the pin for every column LOW and then checks to see if any of the row pins are LOW. All rows are HIGH unless a switch is closed, the button is pressed. A small delay is used to ensure that the switch is not bouncing. The code waits for the switch, the button is released and then returns the character, number associated with the switch associated in the keymap array. If nothing is pressed it will return 0.

void loop()
{
  char key = getKey();
  if ( key != 0) { // if the character is not 0 then it's a valid key press
    Serial.print("Got key ");
    Serial.println(key);
  }
}
// returns with the key pressed, or 0 if no key is pressed
char getKey()
{
  char key = 0; // 0 indicates no key pressed
  for (int column = 0; column < numCols; column++)
  {
    digitalWrite(colPins[column], LOW); // Activate the current column.
    for (int row = 0; row < numRows; row++) // Scan all rows for a key press.
    {
      if (digitalRead(rowPins[row]) == LOW) // Is a key pressed?
      {
        delay(debounceTime); // debounce
        while (digitalRead(rowPins[row]) == LOW)
          ; // wait for key to be released
        key = keymap[row][column]; // Remember which key was pressed.
      }
    }
    digitalWrite(colPins[column], HIGH); // De-activate the current column.
  }
  return key; // returns the key pressed or 0 if none

 

Leave a Reply

Your email address will not be published. Required fields are marked *

Fill out this field
Fill out this field
Please enter a valid email address.
You need to agree with the terms to proceed

Menu