STANNUM
Open the simulator

Tutorials / Input

4×4 matrix keypad

Sixteen keys on eight wires: the code scans rows and columns, and the simulation closes the right crossing.

Parts in the example:
  • Keypad 4×4
  • LED
  • Active buzzer
The Keypad 4×4 block as it appears on the canvas.

What it is

A membrane keypad has no electronics: each key connects one row wire to one column wire. To read it the firmware scans — drives one line, reads the others, moves on — and the crossing that reads LOW is the key. The Keypad library does this for you and adds debouncing.

In the simulator

The block is the keypad; press and hold a key with the mouse. The simulation joins the row and the column of every pressed key at the pin level, so whichever way the code scans — the library drives the columns and reads the rows, hand-written code often does the opposite — the reading is right.

Pins

PinWhat it is
L1row 1 — to a GPIO
L2row 2 — to a GPIO
L3row 3 — to a GPIO
L4row 4 — to a GPIO
C1column 1 — to a GPIO
C2column 2 — to a GPIO
C3column 3 — to a GPIO
C4column 4 — to a GPIO

Wiring

The circuit below is the example Password lock — 4×4 keypad from the lab — open it with Project → Open example… and it comes ready to run.

The wired circuit, as the lab draws it.
Keypad 4×4 pinGoes to
L1D13 on the board (GPIO 13)
L2D12 on the board (GPIO 12)
L3D14 on the board (GPIO 14)
L4D27 on the board (GPIO 27)
C1D26 on the board (GPIO 26)
C2D25 on the board (GPIO 25)
C3TX2 on the board (GPIO 17)
C4RX2 on the board (GPIO 16)

Code

sketch.cpp
#include <Arduino.h>
#include <Keypad.h>

char teclas[4][4] = {
  {'1','2','3','A'}, {'4','5','6','B'}, {'7','8','9','C'}, {'*','0','#','D'}};
byte pinosLinha[4]  = {13, 12, 14, 27};
byte pinosColuna[4] = {26, 25, 17, 16};
Keypad teclado(makeKeymap(teclas), pinosLinha, pinosColuna, 4, 4);

const String SENHA = "1234";
const int LED = 4, BUZZER = 5;
String digitado = "";

void setup() {
  Serial.begin(115200);
  pinMode(LED, OUTPUT);
  pinMode(BUZZER, OUTPUT);
  Serial.println("type the password then #  (* clears)");
}

void loop() {
  char k = teclado.getKey();
  if (!k) return;

  if (k == '*') {
    digitado = "";
    Serial.println("cleared");
  } else if (k == '#') {
    if (digitado == SENHA) {
      Serial.println(">>> OPEN <<<");
      digitalWrite(LED, HIGH);
      delay(3000);
      digitalWrite(LED, LOW);
    } else {
      Serial.println("wrong password!");
      digitalWrite(BUZZER, HIGH);
      delay(400);
      digitalWrite(BUZZER, LOW);
    }
    digitado = "";
  } else {
    digitado += k;
    Serial.printf("* (%d digits)\n", digitado.length());
  }
}

The key map, the two arrays of pins and the Keypad object. getKey() returns the key pressed since the last call, or nothing. The example collects digits, compares with the password on #, clears on *, and answers with the LED or the buzzer.

Run it

Press Build and run. The first build of a project takes a while; after that, only what changed is rebuilt.

The simulation running: the canvas reacts and the serial monitor shows what the code prints.

Press 1, 2, 3, 4 and then #: the serial monitor says “OPEN” and the green LED lights for three seconds. A wrong code sounds the buzzer. Each digit prints a “*” with the count.

How the simulation models it

Try this

  1. Change the password and make it 6 digits.
  2. Lock out for 10 seconds after three wrong attempts.

See also