Reading 4x4 Keypad With Arduino UNO

by Trevor Lee in Circuits > Arduino

1553 Views, 0 Favorites, 0 Comments

Reading 4x4 Keypad With Arduino UNO

4x4-matrix-keypad.gif

Conceptually, reading key press from a Keypad is just like reading button click. Nevertheless, with only 8 pins, it makes reading 16 keys (buttons) interesting.

In this post, I hope to show you that it is still easy to read Keypad key presses, with only 8 pins connected to an Arduino UNO.

As shown, the 16 keys are just like 16 buttons. However you do not have 16 pins to read states of the 16 buttons. Instead, 4 "row pins" are connected to one legs of the 16 buttons; and 4 "column pins" are connected to the other legs of the 16 buttons.

A Way to Read 16 Buttons, With 8 Pins

Consider that if we connect one leg of a button to an Arduino UNO "pull up" input pin:

  • If the other leg of the button is connected 5V (i.e. 1), the "pull up" input will always give you 1, whether the button is pressed or not.
  • However, if the other leg of the button is connected to GND (i.e. 0), the "pull up" input give you 0 if the button is pressed; 1 if the button is released.

Hence, a stretegy to read key press is:

  • Set the "row pins" to output mode, so that we can control each one to be 0 or 1.
  • Set the "column pins" to "pull up" input mode.
  • Read the keys of a row one at a time. When reading a row, say 0, set R0 to 0; but set the other "row pins" to 1.
  • In this configuration, the "column pins" reflect which key of row 0 is pressed.
  • Iteate the same steps for row 1 to read key press of row 1.
  • Iteate the same steps for row 2 to read key press of row 2.
  • Iteate the same steps for row 3 to read key press of row 3.
  • After all 4 iterations in very quick succession, we can figure out which of the 16 keys is pressed.


The Connection

keypad_connect.png
  • Connect R0 pin of Keypad to pin 12 or Arduino UNO.
  • Connect R1 pin of Keypad to pin 11 or Arduino UNO.
  • Connect R2 pin of Keypad to pin 10 or Arduino UNO.
  • Connect R3 pin of Keypad to pin 9 or Arduino UNO.
  • Connect C0 pin of Keypad to pin 8 or Arduino UNO.
  • Connect C1 pin of Keypad to pin 7 or Arduino UNO.
  • Connect C2 pin of Keypad to pin 6 or Arduino UNO.
  • Connect C3 pin of Keypad to pin 5 or Arduino UNO.

The Sketch

#define PIN_R0 12
#define PIN_R1 11
#define PIN_R2 10
#define PIN_R3 9
#define PIN_C0 8
#define PIN_C1 7
#define PIN_C2 6
#define PIN_C3 5
const char keys[4][4] = {
{ '1', '2', '3', 'A'},
{ '4', '5', '6', 'B' },
{ '7', '8', '9', 'C' },
{ '*', '0', '#', 'D'}
};
// setup for reading key on a specify row r -- set PIN_Rr to 0, all other PIN_Rx to 1
void setupForReadingRow(int r) {
digitalWrite(PIN_R0, r != 0);
digitalWrite(PIN_R1, r != 1);
digitalWrite(PIN_R2, r != 2);
digitalWrite(PIN_R3, r != 3);
}
// read which column with key press; -1 if none
int readColumnOfKeyPress() {
int c0 = digitalRead(PIN_C0);
int c1 = digitalRead(PIN_C1);
int c2 = digitalRead(PIN_C2);
int c3 = digitalRead(PIN_C3);
int c = -1;
if (c0 == 0) {
c = 0;
} else if (c1 == 0) {
c = 1;
} else if (c2 == 0) {
c = 2;
} else if (c3 == 0) {
c = 3;
}
return c;
}
void setup() {
pinMode(PIN_R0, OUTPUT);
pinMode(PIN_R1, OUTPUT);
pinMode(PIN_R2, OUTPUT);
pinMode(PIN_R3, OUTPUT);
pinMode(PIN_C0, INPUT_PULLUP);
pinMode(PIN_C1, INPUT_PULLUP);
pinMode(PIN_C2, INPUT_PULLUP);
pinMode(PIN_C3, INPUT_PULLUP);
Serial.begin(115200);
}
void promptForKeyPressOnRow(int r) {
Serial.println(String("press a key on row ") + String(r) + String(":"));
setupForReadingRow(r);
while (true) {
int c = readColumnOfKeyPress();
if (c != -1) {
char key = keys[r][c];
Serial.println(String("- you pressed [") + String(key) + String("]"));
break;
}
}
}
void loop() {
promptForKeyPressOnRow(0);
promptForKeyPressOnRow(1);
promptForKeyPressOnRow(2);
promptForKeyPressOnRow(3);
}

The sketch will read key press of the rows one by one.

The subroutine setupForReadingRow is the step above to set the row from which key press is read.

void setupForReadingRow(int r) {
...
}

The subroutine readColumnOfKeyPress is the step to read which column key is pressed.

int readColumnOfKeyPress() {
...
}

Combining the above two subroutines, the subroutine promptForKeyPressOnRow prompts user to press a key on a specifc row.

void promptForKeyPressOnRow(int r) {
...
}

Finally, in the loop block, the subroutine promptForKeyPressOnRow is called once for each row.

void loop() {
promptForKeyPressOnRow(0);
promptForKeyPressOnRow(1);
promptForKeyPressOnRow(2);
promptForKeyPressOnRow(3);
}


The End Result

serial-out.png

Combining this, and that of my previous post -- Blink Test with Colored Image, with Arduino Nano -- I hope to come up with a more interesting experiment with the Keypad. Until then, enjoy!

Peace be with you! Jesus loves you! May God bless you!