Preview build — page text is a draft awaiting human review. Code badges come from real compiles. The flasher is real but not yet hardware-tested; the Playground is still a preview.

4×4 keypad with Arduino Uno — wiring and Keypad library code

Connect a 4×4 membrane keypad to an Arduino Uno on D2–D9 and read keys, collect a code and clear it with the Keypad library.

Arduino C++Verified — core avr 1.8.8, Keypad 3.1.1, 3 Nov 2026Compile-only

Community draft — report a mistake

The 4×4 membrane keypad gives you 16 keys from 8 wires, the usual input for door locks and voting machines.

It needs no power and no extra parts on the Uno: four row pins and four column pins. The sketch prints each key and collects a code that you confirm with # and clear with *.

Wiring

Arduino Uno R3Only the pins used are shown · 5 V logic4×4 matrix membrane keypadD2D3D4D5D6D7D8D9R1R2R3R4C1C2C3C4
Every connection
Arduino Uno R34×4 matrix membrane keypadWireNotes
D2R1red
D3R2orange
D4R3yellow
D5R4green
D6C1blue
D7C2purple
D8C3white
D9C4brown

No supply — passive switch matrix part, 5 V board. The keypad has no electronics, so it works at 3.3 V or 5 V. It does need eight GPIOs; on ESP32 avoid the strapping pins (0, 2, 5, 12, 15) and the input-only pins (34–39) for the row outputs.

Board quirks

  • A keypad is a passive switch matrix: no power pin and no resistors — the library scans rows and uses the Uno’s internal pull-ups on the columns.
  • D2–D9 leave D0/D1 (USB serial) and D13 (on-board LED) free.
  • Pin 1 of the ribbon is usually R1 at the left when the keys face you; if keys come out wrong, reverse the row or column arrays.

Code

keypad-uno.inoArduino C++Open in PlaygroundOpen in PlaygroundFlash
// 4×4 membrane keypad on an Arduino Uno R3 with the Keypad library.
// Rows R1-R4 → D2, D3, D4, D5; columns C1-C4 → D6, D7, D8, D9. No resistors needed.
#include <Keypad.h>

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

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

void setup() {
  Serial.begin(9600);
  Serial.println(F("Type digits, # to enter, * to clear"));
}

void loop() {
  char key = keypad.getKey();
  if (!key) return;
  if (key == '#') {
    Serial.print(F("Entered: "));
    Serial.println(entry);
    entry = "";
  } else if (key == '*') {
    entry = "";
    Serial.println(F("Cleared"));
  } else {
    entry += key;
    Serial.print(F("Key: "));
    Serial.println(key);
  }
}

Library: Keypad (Mark Stanley, Alexander Brevig) — compiled with Keypad 3.1.1.

Expected serial output

Serial Monitor · 9600Output
Type digits, # to enter, * to clear
Key: 1
Key: 9
Key: 8
Entered: 198

Common errors

Wrong keys come out

Rows and columns are mixed up. Swap the row and column pin arrays, or reverse one of them.

Some keys never register

A loose ribbon or one wire on the wrong pin — test each row with a multimeter.

↑↓ to move · Enter to open