按键

[English]

按键组件实现了 GPIO 和 ADC 两种按键,并允许同时创建两种不同的按键。下图显示了两种按键的硬件设计:

../_images/button_hardware.png
  • GPIO 按键优点有:每一个按键占用独立的 IO,之间互不影响,稳定性高;缺点有:按键数量多时占用太多 IO 资源。

  • ADC 按键优点有:可多个按键共用一个 ADC 通道,占用 IO 资源少;缺点有:不能同时按下多按键,当按键因氧化等因素导致闭合电阻增大时,容易误触,稳定性不高。

注解

  • GPIO 按键需注意上下拉问题,组件内部会启用芯片内部的上下拉电阻,但是在仅支持输入的 IO 内部没有电阻, 需要外部连接

  • ADC 按键需注意电压不能超过 ADC 量程。

按键事件

每个按键拥有下表的 8 个事件:

事件

触发条件

BUTTON_PRESS_DOWN

按下

BUTTON_PRESS_UP

弹起

BUTTON_PRESS_REPEAT

按下弹起次数 >= 2次

BUTTON_SINGLE_CLICK

按下弹起 1 次

BUTTON_DOUBLE_CLICK

按下弹起 2 次

BUTTON_LONG_PRESS_START

按下时间达到阈值的瞬间

BUTTON_LONG_PRESS_HOLD

长按期间一直触发

BUTTON_PRESS_REPEAT_DONE

多次按下弹起结束

每个按键可以有 回调轮询 两种使用方式:

  • 回调:一个按键的每个事件都可以为其注册一个回调函数,产生事件时回调函数将会被调用。这种方式的效率和实时性高,不会丢失事件。

  • 轮询:在程序中周期性调用 iot_button_get_event() 查询按键当前的事件。这种方式使用简单,适合任务简单的场合

当然你也可以将以上两种方式组合使用。

注意

回调函数中不能有 TaskDelay 等阻塞的操作

配置项

  • BUTTON_PERIOD_TIME_MS : 扫描周期

  • BUTTON_DEBOUNCE_TICKS : 消抖次数

  • BUTTON_SHORT_PRESS_TIME_MS : 连续短按有效时间

  • BUTTON_LONG_PRESS_TIME_MS : 长按有效时间

  • ADC_BUTTON_MAX_CHANNEL : ADC 按钮的最大通道数

  • ADC_BUTTON_MAX_BUTTON_PER_CHANNEL : ADC 一个通道最多的按钮数

  • ADC_BUTTON_SAMPLE_TIMES : 每次扫描的样本数

  • BUTTON_SERIAL_TIME_MS : 长按期间触发的 CALLBACK 间隔时间

应用示例

创建按键

// create gpio button
button_config_t gpio_btn_cfg = {
    .type = BUTTON_TYPE_GPIO,
    .long_press_ticks = CONFIG_BUTTON_LONG_PRESS_TIME_MS,
    .short_press_ticks = CONFIG_BUTTON_SHORT_PRESS_TIME_MS,
    .gpio_button_config = {
        .gpio_num = 0,
        .active_level = 0,
    },
};
button_handle_t gpio_btn = iot_button_create(&gpio_btn_cfg);
if(NULL == gpio_btn) {
    ESP_LOGE(TAG, "Button create failed");
}

// create adc button
button_config_t adc_btn_cfg = {
    .type = BUTTON_TYPE_ADC,
    .long_press_ticks = CONFIG_BUTTON_LONG_PRESS_TIME_MS,
    .short_press_ticks = CONFIG_BUTTON_SHORT_PRESS_TIME_MS,
    .adc_button_config = {
        .adc_channel = 0,
        .button_index = 0,
        .min = 100,
        .max = 400,
    },
};
button_handle_t adc_btn = iot_button_create(&adc_btn_cfg);
if(NULL == adc_btn) {
    ESP_LOGE(TAG, "Button create failed");
}

注解

ADC 按钮使用的是 ADC1 ,当项目中还有其他地方使用到了 ADC1 时,请传入 adc_handle 和 adc_channel 来配置 ADC 按钮。

注册回调函数

static void button_single_click_cb(void *arg,void *usr_data)
{
    ESP_LOGI(TAG, "BUTTON_SINGLE_CLICK");
}

iot_button_register_cb(gpio_btn, BUTTON_SINGLE_CLICK, button_single_click_cb,NULL);

查询按键事件

button_event_t event;
event = iot_button_get_event(button_handle);

API Reference

Header File

Functions

button_handle_t iot_button_create(const button_config_t *config)

Create a button.

Return

A handle to the created button, or NULL in case of error.

Parameters
  • config: pointer of button configuration, must corresponding the button type

esp_err_t iot_button_delete(button_handle_t btn_handle)

Delete a button.

Return

  • ESP_OK Success

  • ESP_FAIL Failure

Parameters
  • btn_handle: A button handle to delete

esp_err_t iot_button_register_cb(button_handle_t btn_handle, button_event_t event, button_cb_t cb, void *usr_data)

Register the button event callback function.

Return

  • ESP_OK on success

  • ESP_ERR_INVALID_ARG Arguments is invalid.

  • ESP_ERR_INVALID_STATE The Callback is already registered. No free Space for another Callback.

Parameters
  • btn_handle: A button handle to register

  • event: Button event

  • cb: Callback function.

  • usr_data: user data

esp_err_t iot_button_unregister_cb(button_handle_t btn_handle, button_event_t event)

Unregister the button event callback function.

Return

  • ESP_OK on success

  • ESP_ERR_INVALID_ARG Arguments is invalid.

  • ESP_ERR_INVALID_STATE The Callback is already registered. No free Space for another Callback.

Parameters
  • btn_handle: A button handle to unregister

  • event: Button event

size_t iot_button_count_cb(button_handle_t btn_handle)

how many Callbacks are still registered.

Return

0 if no callbacks registered, or 1 .. (BUTTON_EVENT_MAX-1) for the number of Registered Buttons.

Parameters
  • btn_handle: A button handle to unregister

button_event_t iot_button_get_event(button_handle_t btn_handle)

Get button event.

Return

Current button event. See button_event_t

Parameters
  • btn_handle: Button handle

uint8_t iot_button_get_repeat(button_handle_t btn_handle)

Get button repeat times.

Return

button pressed times. For example, double-click return 2, triple-click return 3, etc.

Parameters
  • btn_handle: Button handle

uint16_t iot_button_get_ticks_time(button_handle_t btn_handle)

Get button ticks time.

Return

Actual time from press down to up (ms).

Parameters
  • btn_handle: Button handle

uint16_t iot_button_get_long_press_hold_cnt(button_handle_t btn_handle)

Get button long press hold count.

Return

Count of trigger cb(BUTTON_LONG_PRESS_HOLD)

Parameters
  • btn_handle: Button handle

Structures

struct button_custom_config_t

custom button configuration

Public Members

uint8_t active_level

active level when press down

esp_err_t (*button_custom_init)(void *param)

user defined button init

uint8_t (*button_custom_get_key_value)(void *param)

user defined button get key value

esp_err_t (*button_custom_deinit)(void *param)

user defined button deinit

void *priv

private data used for custom button, MUST be allocated dynamically and will be auto freed in iot_button_delete

struct button_config_t

Button configuration.

Public Members

button_type_t type

button type, The corresponding button configuration must be filled

uint16_t long_press_time

Trigger time(ms) for long press, if 0 default to BUTTON_LONG_PRESS_TIME_MS

uint16_t short_press_time

Trigger time(ms) for short press, if 0 default to BUTTON_SHORT_PRESS_TIME_MS

button_gpio_config_t gpio_button_config

gpio button configuration

button_adc_config_t adc_button_config

adc button configuration

button_custom_config_t custom_button_config

custom button configuration

union button_config_t::[anonymous] [anonymous]

button configuration

Type Definitions

typedef void (*button_cb_t)(void *button_handle, void *usr_data)
typedef void *button_handle_t

Enumerations

enum button_event_t

Button events.

Values:

BUTTON_PRESS_DOWN = 0
BUTTON_PRESS_UP
BUTTON_PRESS_REPEAT
BUTTON_PRESS_REPEAT_DONE
BUTTON_SINGLE_CLICK
BUTTON_DOUBLE_CLICK
BUTTON_LONG_PRESS_START
BUTTON_LONG_PRESS_HOLD
BUTTON_EVENT_MAX
BUTTON_NONE_PRESS
enum button_type_t

Supported button type.

Values:

BUTTON_TYPE_GPIO
BUTTON_TYPE_ADC
BUTTON_TYPE_CUSTOM