0
0
Power-electronicsHow-ToBeginner · 4 min read

How to Read Keypad Input in Embedded C: Simple Guide

To read keypad input in embedded C, configure the keypad rows as outputs and columns as inputs with pull-up resistors. Then, scan each row by setting it low and check which column reads low to detect the pressed key.
📐

Syntax

Reading a keypad involves setting rows as outputs and columns as inputs, then scanning rows one by one to detect pressed keys.

  • SetRowLow(row): Drive one row line low.
  • ReadColumn(col): Read the state of a column input.
  • ScanKeypad(): Loop through rows and columns to find pressed key.
c
void SetRowLow(int row);
int ReadColumn(int col);
char ScanKeypad(void);
💻

Example

This example shows how to scan a 4x4 keypad connected to microcontroller pins. It sets each row low in turn and reads columns to find which key is pressed.

c
#include <stdint.h>
#include <stdbool.h>

// Simulated hardware registers for rows and columns
uint8_t ROW_PORT = 0xFF; // All rows high initially
uint8_t COL_PIN = 0x0F;  // Columns inputs with pull-ups (bits 0-3)

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

// Set one row low (0) and others high (1)
void SetRowLow(int row) {
    ROW_PORT = 0xFF; // all high
    ROW_PORT &= ~(1 << row); // set selected row low
}

// Read column inputs, return bitmask of columns (0 means pressed)
uint8_t ReadColumns(void) {
    // In real hardware, read input pins here
    // For simulation, return COL_PIN
    return COL_PIN;
}

// Scan keypad and return pressed key or 0 if none
char ScanKeypad(void) {
    for (int row = 0; row < 4; row++) {
        SetRowLow(row);
        uint8_t cols = ReadColumns();
        for (int col = 0; col < 4; col++) {
            if ((cols & (1 << col)) == 0) { // active low means pressed
                return keys[row][col];
            }
        }
    }
    return 0; // no key pressed
}

// Example main function
#include <stdio.h>
int main() {
    // Simulate pressing key '5' (row 1, col 1)
    COL_PIN = 0x0D; // bit 1 low (0b1101)
    char key = ScanKeypad();
    if (key) {
        printf("Key pressed: %c\n", key);
    } else {
        printf("No key pressed\n");
    }
    return 0;
}
Output
Key pressed: 5
⚠️

Common Pitfalls

Common mistakes when reading keypad input include:

  • Not configuring rows as outputs and columns as inputs properly.
  • Forgetting to enable pull-up resistors on column inputs, causing floating inputs.
  • Not scanning rows one at a time, which can cause multiple keys to appear pressed.
  • Ignoring debounce, which can cause multiple detections for one press.
c
/* Wrong: Setting all rows low at once - causes ghosting */
void WrongScan(void) {
    ROW_PORT = 0x00; // all rows low
    uint8_t cols = ReadColumns();
    // This can cause multiple false key detections
}

/* Right: Scan one row at a time */
void RightScan(void) {
    for (int row = 0; row < 4; row++) {
        SetRowLow(row);
        uint8_t cols = ReadColumns();
        // Check columns here
    }
}
📊

Quick Reference

Tips for reading keypad input:

  • Configure rows as outputs and columns as inputs with pull-ups.
  • Scan rows one by one by setting them low.
  • Read columns to detect which key is pressed (active low).
  • Implement debounce to avoid false multiple detections.

Key Takeaways

Set keypad rows as outputs and columns as inputs with pull-up resistors.
Scan each row by driving it low and read columns to detect pressed keys.
Avoid setting all rows low at once to prevent ghosting errors.
Use debounce logic to ensure stable key detection.
Map detected row and column to the correct key character.