0
0
Power-electronicsHow-ToBeginner · 4 min read

How to Interface 4x4 Keypad in Embedded C: Simple Guide

To interface a 4x4 keypad in Embedded C, connect its rows and columns to microcontroller pins, configure rows as outputs and columns as inputs with pull-ups, then scan by setting rows low one by one and reading columns to detect pressed keys. Use a nested loop to check each key and map the row-column pair to the corresponding character.
📐

Syntax

Interfacing a 4x4 keypad involves setting microcontroller pins connected to rows as outputs and columns as inputs. You then scan keys by driving each row low and reading the column inputs to detect which key is pressed.

The main steps are:

  • Initialize row pins as outputs and set them high.
  • Initialize column pins as inputs with pull-up resistors.
  • Scan each row by setting it low and checking columns for a low signal.
  • Map the detected row and column to the corresponding key value.
c
void keypad_init(void) {
    // Set row pins as output and set high
    // Set column pins as input with pull-ups
}

char keypad_get_key(void) {
    for (int row = 0; row < 4; row++) {
        // Set current row low
        // Read columns
        // If column low, return mapped key
        // Set row high again
    }
    return '\0'; // No key pressed
}
💻

Example

This example shows how to scan a 4x4 keypad connected to PORTB pins of an 8-bit microcontroller. Rows are connected to pins RB0-RB3 and columns to RB4-RB7.

c
#include <xc.h>

#define ROWS 4
#define COLS 4

// Key map for 4x4 keypad
const char keys[ROWS][COLS] = {
    {'1', '2', '3', 'A'},
    {'4', '5', '6', 'B'},
    {'7', '8', '9', 'C'},
    {'*', '0', '#', 'D'}
};

// Initialize keypad pins
void keypad_init(void) {
    TRISB = 0xF0; // RB0-RB3 output (rows), RB4-RB7 input (columns)
    PORTB = 0x0F; // Set rows high (RB0-RB3), columns high (RB4-RB7) pull-ups enabled
}

// Scan keypad and return pressed key or '\0' if none
char keypad_get_key(void) {
    for (int row = 0; row < ROWS; row++) {
        PORTB = ~(1 << row) & 0x0F; // Drive one row low, keep columns high
        __delay_ms(5); // Small delay for signal to settle
        unsigned char col_val = PORTB & 0xF0; // Read columns
        for (int col = 0; col < COLS; col++) {
            if (!(col_val & (1 << (col + 4)))) { // Active low
                while (!(PORTB & (1 << (col + 4)))); // Wait for key release
                return keys[row][col];
            }
        }
    }
    return '\0';
}

int main(void) {
    keypad_init();
    char key;
    while (1) {
        key = keypad_get_key();
        if (key != '\0') {
            // Use the key value (e.g., display or process)
        }
    }
    return 0;
}
Output
No direct output; returns pressed key character when a key is pressed.
⚠️

Common Pitfalls

Common mistakes when interfacing a 4x4 keypad include:

  • Not configuring rows as outputs and columns as inputs properly.
  • Failing to enable pull-up resistors on column inputs, causing floating inputs and false readings.
  • Not adding a small delay after setting a row low before reading columns, leading to unstable readings.
  • Not waiting for key release, causing multiple detections of a single press.
c
/* Wrong way: No pull-ups and no delay */
void keypad_init_wrong(void) {
    TRISB = 0xF0; // Rows output, columns input
    PORTB = 0x00; // Rows low, no pull-ups
}

/* Right way: Pull-ups enabled and delay added */
void keypad_init_right(void) {
    TRISB = 0xF0; // Rows output, columns input
    PORTB = 0x0F; // Rows high, pull-ups enabled
}

char keypad_get_key_right(void) {
    for (int row = 0; row < 4; row++) {
        PORTB = ~(1 << row) & 0x0F; // Drive one row low, keep columns high
        __delay_ms(5); // Delay for stable reading
        // Read columns and detect key
        PORTB = 0x0F; // Reset rows high
    }
    return '\0';
}
📊

Quick Reference

Summary tips for 4x4 keypad interfacing:

  • Rows: Output pins, start high, drive low one at a time.
  • Columns: Input pins with pull-up resistors enabled.
  • Scan: Drive each row low, read columns for low signal.
  • Debounce: Add small delay and wait for key release.
  • Map row-column to key character using a 2D array.

Key Takeaways

Configure keypad rows as outputs and columns as inputs with pull-ups.
Scan keys by driving rows low one at a time and reading columns for pressed keys.
Add delays and wait for key release to avoid false or repeated detections.
Use a 2D array to map row-column pairs to keypad characters.
Test hardware connections and pin configurations carefully to avoid floating inputs.