Contributed by 邦邦, organized by Ai-Thinker
AI-WB2 Adding a Button on IO08 (Long Press, Single Click, Double Click, Release) with MultiButton
Directly porting it avoids reinventing the wheel; it's really nice and can be used in many products. <https://github.com/0x1abin/MultiButton>
Introduction MultiButton is a compact, simple, and easy-to-use event-driven button driver module that supports unlimited button expansion. The callback-based asynchronous handling of button events simplifies your program structure, removes redundant hardcoded button handling, and makes your button business logic clearer.
Create a task directly in the main() function: xTaskCreate(MultiButton_poll_Task, (char*)"MultiButton_poll_Task", 512, NULL, 14, NULL);// The smaller the task priority value, the lower the priority
Define a button struct Button btn1 in the task:
Initialize the IO and the button module:
Create a software timer that scans every 5 ms:
Register events (this example uses the callback approach) (not polling):
Click to expand full code
void MultiButton_poll_Task(void *pvParam)
{
bl_gpio_enable_input(8, 0, 1);//
button_init(&btn1, read_button_GPIO, 1, btn1_id);
button_start(&btn1);
//make the timer invoking the button_ticks() interval 5ms.
ButtonTimers = xTimerCreate("ButtonTimers",5/portTICK_PERIOD_MS,pdTRUE,( void * ) 0,vButtonTimersCallback);//pvTimerID: 软件定时器 ID,数字形式。该 ID 典型的用法是当一个回调函数分配给一个或者多个软件定时器时,在回调函数里面根据 ID 号来处理不同的软件定时器;可以用来标记定时器,表示自己是什么定时器;可以用来保存参数,给回调函数使用
xTimerStart(ButtonTimers,portMAX_DELAY);
button_attach(&btn1, SINGLE_CLICK, BTN1_SINGLE_CLICK_Handler);
button_attach(&btn1, DOUBLE_CLICK, BTN1_DOUBLE_CLICK_Handler);
button_attach(&btn1, LONG_PRESS_HOLD, BTN1_LONG_PRESS_HOLD_Handler);
button_attach(&btn1, PRESS_UP, BTN1_PRESS_UP_Handler);
vTaskDelete(NULL);
while(1)
{
}
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
}Special attention needed:
In the schematic, NC was not soldered at first; I was puzzled for a while before discovering it. bl_gpio_enable_input(8, 0, 1);//
GPIO8 acts as Bootstrap: if it is high at the moment of power-on, the module enters flashing mode; if it is low at the moment of power-on, the module boots normally.
So pull it low internally, and it goes high when the button is pressed. button_init(&btn1, read_button_GPIO, 1, btn1_id);
The button module is initialized as active-high.
The callbacks just print; no real functionality yet.
Click to expand full code
static TimerHandle_t ButtonTimers;
static void vButtonTimersCallback(TimerHandle_t xTimer)
{
button_ticks();
}
void BTN1_SINGLE_CLICK_Handler(void* btn)
{
blog_info_user(MultiButton,"BTN1_SINGLE_CLICK_Handler");
}
void BTN1_DOUBLE_CLICK_Handler(void* btn)
{
blog_info_user(MultiButton,"BTN1_DOUBLE_CLICK_Handler");
}
void BTN1_LONG_PRESS_HOLD_Handler(void* btn)
{
blog_info_user(MultiButton,"BTN1_LONG_PRESS_HOLD_Handler");
}
void BTN1_PRESS_UP_Handler(void* btn)
{
blog_info_user(MultiButton,"BTN1_PRESS_UP_Handler");
}
Original code
Attachments: 
MultiButton.zip(242.5 KB, Downloads: 12)

