Keyboard Scanning

[中文]

The Keyboard Scanning Component implements fast and efficient keyboard scanning, supporting key debouncing, key release and press event reporting, as well as combination keys.

This component uses matrix key row-column scanning and, through special circuit design, achieves full-key rollover circuit detection.

../_images/keyboard_hardware.png
  • In this circuit, rows output high-level signals sequentially, detecting whether columns have high-level signals. If they do, it indicates the key is pressed.

Note

  • Since the logic of this component does not involve swapping row-column scanning, it is not suitable for traditional row-column scanning circuits and is only applicable to full-key rollover circuits for keyboards.

Component Events

  • KBD_EVENT_PRESSED: Reports data when there is a change in key states.

    • key_pressed_num: Number of keys pressed.

    • key_release_num: Number of keys released.

    • key_change_num: Number of keys with changed states compared to the previous state. >0 indicates an increase in pressed keys, <0 indicates a decrease.

    • key_data: Information of the currently pressed keys, with positions (x, y). Indexed in the order they were pressed, with smaller indexes being pressed earlier.

    • key_release_data: Information of keys released compared to the previous state, with positions (x, y).

  • KBD_EVENT_COMBINATION: Combination key event. Triggered when a combination key is pressed.

    • key_num: Number of keys in the combination.

    • key_data: Position information of the combination keys. For setting a combination key (1,1) and (2,2), (1,1) must be pressed first followed by (2,2) to trigger the combination key event. Combination keys only trigger with increasing combinations.

Application Example

Initializing Keyboard Scanning

keyboard_btn_config_t cfg = {
    .output_gpios = (int[])
    {
        40, 39, 38, 45, 48, 47
    },
    .output_gpio_num = 6,
    .input_gpios = (int[])
    {
        21, 14, 13, 12, 11, 10, 9, 4, 5, 6, 7, 15, 16, 17, 18
    },
    .input_gpio_num = 15,
    .active_level = 1,
    .debounce_ticks = 2,
    .ticks_interval = 500,      // us
    .enable_power_save = false, // enable power save
};
keyboard_btn_handle_t kbd_handle = NULL;
keyboard_button_create(&cfg, &kbd_handle);

Registering Callback Functions

  • Registration of KBD_EVENT_PRESSED event is as follows:

keyboard_btn_cb_config_t cb_cfg = {
    .event = KBD_EVENT_PRESSED,
    .callback = keyboard_cb,
};
keyboard_button_register_cb(kbd_handle, cb_cfg, NULL);
  • Registration of KBD_EVENT_COMBINATION event requires passing combination key information through the combination member:

keyboard_btn_cb_config_t cb_cfg = {
    .event = KBD_EVENT_COMBINATION,
    .callback = keyboard_combination_cb1,
    .event_data.combination.key_num = 2,
    .event_data.combination.key_data = (keyboard_btn_data_t[]) {
        {5, 1},
        {1, 1},
    },
};

keyboard_button_register_cb(kbd_handle, cb_cfg, NULL);

Note

Additionally, multiple callbacks can be registered for each event. When registering multiple callbacks, it’s recommended to save keyboard_btn_cb_handle_t *rtn_cb_hdl for later unbinding of specific callbacks.

Key Scanning Efficiency

  • Testing with ESP32S3 chip scanning a 5*16 matrix keyboard, the maximum scanning rate can reach 20K.

Low Power Support

  • Set enable_power_save to true during initialization to activate the low-power mode. In this mode, key scanning is suspended when no key changes occur, allowing the CPU to enter a sleep state. The CPU wakes up when a key is pressed.

Note

This feature only ensures that it does not occupy the CPU; it does not guarantee that the CPU will necessarily enter low-power mode. Currently, only Light Sleep mode is supported.

API Reference

Header File

Functions

esp_err_t keyboard_button_create(keyboard_btn_config_t *kbd_cfg, keyboard_btn_handle_t *kbd_handle)

Create a keyboard instance.

Parameters
  • kbd_cfg – keyboard configuration

  • kbd_handle – keyboard handle

Returns

  • ESP_OK on success

  • ESP_ERR_INVALID_ARG Arguments is invalid.

  • ESP_ERR_NO_MEM No more memory allocation.

esp_err_t keyboard_button_delete(keyboard_btn_handle_t kbd_handle)

Delete the keyboard instance.

Parameters

kbd_handle – keyboard handle

Returns

  • ESP_OK on success

  • ESP_ERR_INVALID_ARG Arguments is invalid.

esp_err_t keyboard_button_register_cb(keyboard_btn_handle_t kbd_handle, keyboard_btn_cb_config_t cb_cfg, keyboard_btn_cb_handle_t *rtn_cb_hdl)

Register the button callback function.

Parameters
  • kbd_handle – keyboard handle

  • cb_cfg – callback configuration

  • rtn_cb_hdl – callback handle for unregister

Returns

  • ESP_OK on success

  • ESP_ERR_INVALID_ARG Arguments is invalid.

  • ESP_ERR_NO_MEM No more memory allocation for the event

esp_err_t keyboard_button_unregister_cb(keyboard_btn_handle_t kbd_handle, keyboard_btn_event_t event, keyboard_btn_cb_handle_t rtn_cb_hdl)

Unregister the button callback function.

Note

If only the event is provided, all callbacks associated with this event will be canceled. If rtn_cb_hdl is provided, only the specified callback will be unregistered.

Parameters
  • kbd_handle – keyboard handle

  • event – event type

  • rtn_cb_hdl – callback handle for unregister

Returns

  • ESP_OK on success

  • ESP_ERR_INVALID_ARG Arguments is invalid.

  • ESP_ERR_NO_MEM No more memory allocation for the event

esp_err_t keyboard_button_get_index_by_gpio(keyboard_btn_handle_t kbd_handle, uint32_t gpio_num, kbd_gpio_mode_t gpio_mode, uint32_t *index)

Get index by gpio number.

Parameters
  • kbd_handle – keyboard handle

  • gpio_num – gpio number

  • gpio_mode – gpio mode, input or output

  • index – return index

Returns

  • ESP_OK on success

  • ESP_ERR_INVALID_ARG Arguments is invalid.

  • ESP_ERR_NOT_FOUND The gpio number is not found.

esp_err_t keyboard_button_get_gpio_by_index(keyboard_btn_handle_t kbd_handle, uint32_t index, kbd_gpio_mode_t gpio_mode, uint32_t *gpio_num)

Get gpio number by index.

Parameters
  • kbd_handle – keyboard handle

  • index – index

  • gpio_mode – gpio mode, input or output

  • gpio_num – return gpio number

Returns

  • ESP_OK on success

  • ESP_ERR_INVALID_ARG Arguments is invalid.

  • ESP_ERR_NOT_FOUND The index is not found.

Unions

union keyboard_btn_event_data_t
#include <keyboard_button.h>

keyboard button event data

Public Members

struct keyboard_btn_event_data_t::combination_t combination

combination event

struct combination_t
#include <keyboard_button.h>

combination event data eg: Set key_data = {(1,1), (2,2)} means that the button sequence is (1,1) -> (2,2)

Public Members

uint32_t key_num

Number of keys

keyboard_btn_data_t *key_data

Array, contains key codes by index. The button sequence is also provided through this

Structures

struct keyboard_btn_data_t

keyboard button data

Public Members

uint8_t output_index

key position’s output gpio number

uint8_t input_index

key position’s input gpio number

struct keyboard_btn_report_t

keyboard button report data

Public Members

int key_change_num

Number of key changes

uint32_t key_pressed_num

Number of keys pressed

uint32_t key_release_num

Number of keys released

keyboard_btn_data_t *key_data

Array, contains key codes

keyboard_btn_data_t *key_release_data

Array, contains key codes

struct keyboard_btn_cb_config_t

keyboard button callback config

Public Members

keyboard_btn_event_t event

Event type

keyboard_btn_event_data_t event_data

Event data

keyboard_btn_callback_t callback

Callback function

void *user_data

Callback user data

struct keyboard_btn_config_t

keyboard button config

Public Members

const int *output_gpios

Array, contains output GPIO numbers used by rom/col line

const int *input_gpios

Array, contains input GPIO numbers used by rom/col line

uint32_t output_gpio_num

output_gpios array size

uint32_t input_gpio_num

input_gpios array size

uint32_t active_level

active level for the input gpios

uint32_t debounce_ticks

debounce time in ticks

uint32_t ticks_interval

interval time in us

bool enable_power_save

enable power save mode

UBaseType_t priority

FreeRTOS task priority

BaseType_t core_id

ESP32 core ID

Type Definitions

typedef struct keyboard_btn_t *keyboard_btn_handle_t

keyboard handle type

typedef void *keyboard_btn_cb_handle_t

keyboard callback handle for unregister

typedef void (*keyboard_btn_callback_t)(keyboard_btn_handle_t kbd_handle, keyboard_btn_report_t kbd_report, void *user_data)

Enumerations

enum keyboard_btn_event_t

Keyboard button event.

Values:

enumerator KBD_EVENT_PRESSED

Report all currently pressed keys when a key is either pressed or released.

enumerator KBD_EVENT_COMBINATION

When the component buttons are pressed in sequence, report.

enumerator KBD_EVENT_MAX