Keypad Algorithm



Auto-repeat (typematic)

Composite Key

Shift keys

Click Duration

Short Click
Long Click


Single Click
Double Clicks
Triple Clicks


1-to-1 GPIO Mapping (for keys <= 4)
Key Scanning (for keys > 4)


From key detection to key representation

  • Set — bitmap
  • Code — ID
  • Virtual key

Time Constants


typical: 20ms ~ 50ms
max: 100ms

Short Click:

< 500ms (the time from press to release)

Long Press:

> 500ms (the press time)

Interval between clicks:

time between two clicks: < 700ms

A simple 4-stage encoder


  • Click (short, single), long press, and auto-repeat are supported
  • Composite Key is not supported,
    • although it is easy to be added on.
  • Prefers the key detection of 1-to-1 GPIO mapping
    • although to adopt matrix scanning is possible.
  • Python-like pseudo code is used
  • Easy to be implemented with C-like bit-wise operations


S_Initial, S_Debounce, S_PressLong, S_Typematic = range(4)

Key Vectors


Generated by Key_real()
Key_real() — to get real press from GPIOs

press — debounced press




click — press (debounced) and free

clear after client's reading via Key_clicked()

click = set() # click.clear()

every debounce cycle (20~50 ms)
real = Key_real()
if stage == S_Initial:
    press = set() # press.clear()
    pressAcc = real
    if len(pressAcc) != 0:
        state = S_Debounce
else: # stage >= S_Debounce
    pressAcc &= real
    press |= pressAcc
    free = ~pressAcc
    if len(pressAcc) == 0: # NOTE: go back to S_Initial only when all keys are released
        state = S_Initial
    if stage != S_Typematic:
        click |= press & free

long — long press

clear after client's reading via Key_long()

long = set() # long.clear()

every long press check cycle (10~100 debounce cycles)
if stage == S_Debounce:
    longAcc = pressAcc.copy()
    if longAcc != 0:
        stage = S_PressLong

repeat — auto repeat (typematic) after a long press

clear after client's reading via Key_repeated()

repeat = set() # repeat.clear()

every repeat cycle (2~ debounce cycles)
if stage == S_PressLong:
    repeatAcc = pressAcc & longAcc
    if repeatAcc != 0:
        stage = S_Typematic
elif stage == S_Typematic:
    repeatAcc &= pressAcc & longAcc
    repeat |= repeatAcc

Prototype of public functions (in C style)

void Key_reset()
void Key_update()
Key Key_clicked()
Key Key_long()
Key Key_repeated()

Key matrix scanning

Prototype of public functions (in C style):

void init()
MS getKeyDownTime()
Key getKey()
void flush()
bool hit()

Suggested Readings


Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License