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.
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
-
uint32_t key_num
-
struct keyboard_btn_event_data_t::combination_t combination
Structures
-
struct keyboard_btn_data_t
keyboard button data
-
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
-
int key_change_num
-
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
-
keyboard_btn_event_t event
-
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
-
const int *output_gpios
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)