Built-in project · Arduino Uno R3

Keypad lock on an Arduino Uno

A 4x4 keypad, a relay and an RGB LED on an Uno: type 1234 then # and the relay clicks the door lamp on. The whole build, an Arduino Uno and 8 more parts, runs here in your browser on the firmware below; open it in the editor to change the wiring or the code and run it again.

AdvancedRuns in your browser. Free, and no account needed.

Step by step, with the wiring and the common mistakes: Arduino 4x4 Keypad Code Lock with a Relay

Keypad lock · Arduino Uno R3live0.000 s 0.00x
Click to open it in the editor
The circuit itself, running here on the simulator. Press what can be pressed; click anything else to open it in the editor.

The code

The firmware exactly as the editor opens it. Change a line there and press Run: it compiles in the browser.

sketch.ino · Arduino Uno R3
// Keypad lock: type the code, the relay clicks, the door opens.
//
//   pins 9, 8, 7, 6   keypad rows R1 to R4
//   pins 5, 4, 3, 2   keypad columns C1 to C4
//   pin 10, 11, 12    the RGB LED's red, green and blue legs, 220 ohm each
//   pin 13            the relay module's IN (VCC to 5 V, GND to GND)
//
// The code is 1234 and # sends it. Get it right and the LED goes green and
// the relay pulls in for three seconds, which on a real door is the strike
// plate letting go. Get it wrong and the LED flashes red. * clears what you
// have typed, and every key you press blinks blue so you know it landed.
//
// # Scanning a keypad
//
// A keypad has no chip in it. Under each key is a contact that shorts one of
// four row wires to one of four column wires, so the sketch has to ask: drive
// one row low, read the four columns with their pull-ups on, and a column that
// reads low is a key held in that row. mokxi_keypad.h does that scan and
// hands back one character per press.
//
// # The relay
//
// The board pin cannot switch a door strike, a lamp or a motor on its own, and
// it should not try. The relay module takes a logic level on IN and closes a
// contact that has nothing to do with the board's 5 V. COM is wired to the
// supply and NO to the door lamp, so the lamp lights only while the relay is
// pulled in.

#include "mokxi_keypad.h"

const uint8_t ROWS[4] = {9, 8, 7, 6};
const uint8_t COLS[4] = {5, 4, 3, 2};

const int RED = 10;
const int GREEN = 11;
const int BLUE = 12;
const int RELAY = 13;

const char CODE[] = "1234";
const int CODE_LEN = 4;
const int OPEN_MS = 3000;

Keypad pad(ROWS, COLS);

char typed[8];
int count = 0;

static void colour(int r, int g, int b) {
  digitalWrite(RED, r);
  digitalWrite(GREEN, g);
  digitalWrite(BLUE, b);
}

static void clearTyped() {
  count = 0;
  typed[0] = 0;
}

static bool matches() {
  if (count != CODE_LEN) return false;
  for (int i = 0; i < CODE_LEN; i++) {
    if (typed[i] != CODE[i]) return false;
  }
  return true;
}

static void open() {
  Serial.println("code accepted: door open");
  colour(LOW, HIGH, LOW);
  digitalWrite(RELAY, HIGH);
  delay(OPEN_MS);
  digitalWrite(RELAY, LOW);
  colour(HIGH, LOW, LOW);
  Serial.println("locked again");
}

static void refuse() {
  Serial.println("wrong code");
  for (int i = 0; i < 3; i++) {
    colour(LOW, LOW, LOW);
    delay(120);
    colour(HIGH, LOW, LOW);
    delay(120);
  }
}

void setup() {
  pinMode(RELAY, OUTPUT);
  pinMode(RED, OUTPUT);
  pinMode(GREEN, OUTPUT);
  pinMode(BLUE, OUTPUT);
  digitalWrite(RELAY, LOW);
  colour(HIGH, LOW, LOW);
  pad.begin();
  Serial.begin(115200);
  Serial.println("Mokxi Uno: keypad lock. Type 1234 then #.");
  clearTyped();
}

void loop() {
  char c = pad.pressed();
  if (c == 0) {
    delay(5);
    return;
  }

  // A blue wink on every key, so a press that lands is a press you can see.
  colour(LOW, LOW, HIGH);
  delay(60);
  colour(HIGH, LOW, LOW);

  if (c == '#') {
    if (matches()) {
      open();
    } else {
      refuse();
    }
    clearTyped();
    return;
  }
  if (c == '*') {
    Serial.println("cleared");
    clearTyped();
    return;
  }
  if (count < 7) {
    typed[count++] = c;
    typed[count] = 0;
  }
  Serial.print("typed ");
  Serial.println(typed);
}

Parts list

10 parts, plus the jumper wires. Every one is in the editor's parts bin.

How it is wired

20 connections, pin by pin, read from the circuit itself. Each line is one set of pins joined together, by a jumper wire or a breadboard strip.

  • Ground: Arduino Uno R3 pin GND; Relay module pin GND
  • Arduino Uno R3 pin 13; Relay module pin IN
  • Arduino Uno R3 pin 12; Resistor, 220 Ω (3) pin 2
  • Arduino Uno R3 pin 11; Resistor, 220 Ω (2) pin 2
  • Arduino Uno R3 pin 10; Resistor, 220 Ω (1) pin 1
  • Arduino Uno R3 pin 9; Keypad, 4x4 pin R1
  • Arduino Uno R3 pin 8; Keypad, 4x4 pin R2
  • Arduino Uno R3 pin 7; Keypad, 4x4 pin R3
  • Arduino Uno R3 pin 6; Keypad, 4x4 pin R4
  • Arduino Uno R3 pin 5; Keypad, 4x4 pin C1
  • Arduino Uno R3 pin 4; Keypad, 4x4 pin C2
  • Arduino Uno R3 pin 3; Keypad, 4x4 pin C3
  • Arduino Uno R3 pin 2; Keypad, 4x4 pin C4
  • Arduino Uno R3 pin 5V; Relay module pin VCC; Relay module pin NO
  • Ground: Arduino Uno R3 pin GND; RGB LED pin C; LED, yellow pin C
  • RGB LED pin R; Resistor, 220 Ω (1) pin 2
  • RGB LED pin G; Resistor, 220 Ω (2) pin 1
  • RGB LED pin B; Resistor, 220 Ω (3) pin 1
  • Relay module pin COM; Resistor, 220 Ω (4) pin 2
  • Resistor, 220 Ω (4) pin 1; LED, yellow pin A

Change it and keep it

Open it in the editor, change the circuit or the code, and keep your version in a free account.