Mastering Arduino in Ten Days: Matrix Keypad Display

Background Knowledge

The 4×4 matrix keypad is a commonly used input device in embedded systems, consisting of 16 keys arranged in 4 rows and 4 columns (a total of 16 keys). Compared to individual keys, it significantly saves IO port resources (only 8 IO ports are needed to control 16 keys, while individual keys require 16). It is widely used in human-computer interaction scenarios with controllers such as Arduino, 51 microcontrollers, and STM32 (e.g., password input, function selection, parameter settings, etc.).

1. Hardware Structure

  • Key Layout: The 16 keys are located at the intersection of 4 rows (Row) and 4 columns (Column), with each key corresponding to a unique “row-column” coordinate (e.g., Row 0 Column 0, Row 1 Column 3, etc.).

  • IO Port Connection: 4 row pins (Row Pins) and 4 column pins (Column Pins) are connected to the IO ports of the controller. The keys essentially act as mechanical switches between the “row” and “column” (closed when pressed, open when released).

2. Scanning Principle

The controller identifies the pressed keys through a “row scanning + column detection” method, with the core logic as follows:

  • Row Drive: Set a specific row pin to low (pull down) while setting other row pins to high (pull up);

  • Column Detection: While pulling down a specific row, read the level status of all column pins;

  • Key Recognition: If a column pin detects a low level, it indicates that the key at the intersection of the “currently pulled down row” and the “detected low column” has been pressed;

  • Loop Scanning: Repeat the above steps to quickly scan the 4 rows, achieving the effect of “real-time detection of all keys” (scanning frequency is usually ≥10Hz to avoid missing key presses).

The functions of the 8 pins of the matrix keypad are as follows: (with the keypad facing up, from left to right, they represent pins 1 to 8)

Mastering Arduino in Ten Days: Matrix Keypad Display

Thus, the current actual key value can be determined by the coordinates represented by the electrical signals when the keys are pressed.

1. Electronic Components Used in the Experiment

1 Arduino board, 1 USB data download cable, several Dupont wires

Mastering Arduino in Ten Days: Matrix Keypad Display

1 LCD1602 IIC LCD display (with integrated driver circuit)

Mastering Arduino in Ten Days: Matrix Keypad Display

1 4×4 matrix keypad (with a total of 8 pins, from left to right, pins 1 to 8, pins 1 to 4 control the rows of the keypad, and pins 5 to 8 control the columns)

Mastering Arduino in Ten Days: Matrix Keypad Display

2. Experimental Steps

The wiring method is shown in the figure below

Mastering Arduino in Ten Days: Matrix Keypad Display

Wiring for LCD1602:

  • GND → Arduino GND

  • VCC → Arduino 5V

  • SDA → A4

  • SCL → A5

Wiring for the matrix keypad: (from left to right, pins 1 to 8)

  • Pin 1 → Arduino Pin 11

  • Pin 2 → Arduino Pin 10

  • Pin 3 → Arduino Pin 9

  • Pin 4 → Arduino Pin 8

  • Pin 5 → Arduino Pin 7

  • Pin 6 → Arduino Pin 6

  • Pin 7 → Arduino Pin 5

  • Pin 8 → Arduino Pin 4

3. Program Code

The experiment code requires the inclusion of the LiquidCrystal_I2C.h third-party library to drive the LCD1602 display; the Keypad.h library is included to control the matrix keypad. Search for and install these two libraries in the IDE, ensuring that any dependent libraries are also installed.

Mastering Arduino in Ten Days: Matrix Keypad Display

Program Code:

#include <LiquidCrystal_I2C.h>  // Import LCD1602 I2C driver library
#include <Wire.h>               // Import I2C communication library (required for LCD1602 I2C mode)
#include <Keypad.h>             // Import matrix keypad library
// -------------------------- Hardware Parameter Configuration --------------------------
const uint8_t LCD_ADDR = 0x27;  // I2C device address for LCD1602 (common values are 0x27 or 0x3F)
const uint8_t LCD_COLS = 16;    // Number of columns for LCD1602 (16 columns)
const uint8_t LCD_ROWS = 2;     // Number of rows for LCD1602 (2 rows)
// Matrix keypad configuration (4 rows and 4 columns)
const byte KEYPAD_ROWS = 4;  // Number of rows in the keypad
const byte KEYPAD_COLS = 4;  // Number of columns in the keypad
// Key mapping table (corresponding to actual key positions)
char keyMap[KEYPAD_ROWS][KEYPAD_COLS] = {  { '1', '2', '3', 'A' },  { '4', '5', '6', 'B' },  { '7', '8', '9', 'C' },  { '*', '0', '#', 'D' }};
// Row pins for the keypad (connected to Arduino digital pins)
byte rowPins[KEYPAD_ROWS] = { 11, 10, 9, 8 };
// Column pins for the keypad (connected to Arduino digital pins)
byte colPins[KEYPAD_COLS] = { 7, 6, 5, 4 };
// -------------------------- Global Objects and Variables --------------------------
LiquidCrystal_I2C lcd(LCD_ADDR, LCD_COLS, LCD_ROWS);  // Instantiate LCD1602 object
Keypad customKeypad = Keypad(                         // Instantiate matrix keypad object
  makeKeymap(keyMap),                                 // Key mapping table
  rowPins,                                            // Row pin array
  colPins,                                            // Column pin array
  KEYPAD_ROWS,                                        // Number of rows
  KEYPAD_COLS                                         // Number of columns);
uint8_t inputCount = 0;  // Record the number of key inputs (used to control LCD display position)
// -------------------------- Initialization Function --------------------------
void setup() {  lcd.init();               // Initialize LCD1602  lcd.backlight();          // Turn on LCD backlight  lcd.setCursor(0, 0);      // Set initial cursor position (column 0, row 0)  lcd.print("loading...");  // Welcome message on startup  delay(1500);              // Display prompt for 1.5 seconds  lcd.clear();              // Clear screen to prepare for input}
// -------------------------- Main Loop Function --------------------------
void loop() {  char pressedKey = customKeypad.getKey();  // Get key input (returns 0 if no key is pressed)  // Detect valid key input  if (pressedKey != 0) {    // Calculate cursor position based on input count    // Row 0: Input count 0-15 (corresponding to columns 0-15)    // Row 1: Input count 16-31 (corresponding to columns 0-15)    uint8_t col = inputCount % LCD_COLS;  // Calculate column position (modulo 16)    uint8_t row = inputCount / LCD_COLS;  // Calculate row position (integer division by 16)    lcd.setCursor(col, row);  // Set cursor to current input position    lcd.print(pressedKey);    // Display key character at current position    inputCount++;  // Increment input count    // When 32 characters are input (2 rows × 16 columns), clear screen and reset    if (inputCount >= LCD_COLS * LCD_ROWS) {      delay(500);      // Delay 500ms to allow the last character to display completely      lcd.clear();     // Clear screen      inputCount = 0;  // Reset input count    }  }}

4. Experimental Results

After successfully uploading the program, the LCD1602 screen will light up and display a loading state. After 1.5 seconds, key input can be performed. When a single line exceeds 16 characters, it will automatically wrap to the next line, and when exceeding two lines, the screen will automatically clear.

Wiring Physical Diagram:

Mastering Arduino in Ten Days: Matrix Keypad Display

Experimental Video:

The code in this article has been uploaded to Gitee, see the link: https://gitee.com/webxiaohua/arduino-learn/tree/master/28_ju_zhen_jian_pan

Leave a Comment