MultiButton is a simple and powerful key driver module that is based on an event-driven mechanism and adopts an object-oriented design concept. It helps you easily manage multiple keys and handle key events asynchronously, simplifying your code structure and making key logic clearer and more flexible!
1. Core Advantages of MultiButton
-
• Unlimited Key Expansion: Supports any number of keys without modifying the core code, making it easy to expand.
-
• Event-Driven Mechanism: Based on an event-driven mechanism, it allows you to easily define and handle various key events such as press, release, single click, double click, long press, etc.
-
• Asynchronous Callback Mechanism: The handling functions for key events use asynchronous callbacks to avoid blocking the main program, making your code structure clearer.
-
• Object-Oriented Design: Each key object has its own independent data structure and state management, allowing for easy management.
-
• Simplified Code: Using MultiButton can simplify key handling code, reduce redundancy, and improve code readability and maintainability.
2. Steps to Use MultiButton
-
1. Define Key Structure:
struct Button button1; -
2. Initialize Key Object: Bind the GPIO level reading interface and the valid trigger level for the key.
button_init(&button1, read_button_pin, 0, 0); -
3. Register Key Events: Bind callback functions for each key event.
button_attach(&button1, SINGLE_CLICK, Callback_SINGLE_CLICK_Handler); button_attach(&button1, DOUBLE_CLICK, Callback_DOUBLE_Click_Handler); -
4. Start Key:
button_start(&button1); -
5. Set Timer: Periodically call the
<span>button_ticks()</span>function to update the key state.while(1) { ... if(timer_ticks == 5) { timer_ticks = 0; button_ticks(); } }
3. Data Structure of MultiButton
MultiButton is implemented in C language, and each key object is managed using an independent data structure:
struct Button {
uint16_t ticks;
uint8_t repeat:4;
uint8_t event :4;
uint8_t state :3;
uint8_t debounce_cnt :3;
uint8_t active_level :1;
uint8_t button_level :1;
uint8_t button_id;
uint8_t(*hal_button_Level)(uint8_t button_id_);
BtnCallback cb[number_of_event];
struct Button* next;
};
Each key object is connected through a singly linked list and enters the <span>button_handler(struct Button* handle)</span> state machine for processing, ensuring that the states of each key are independent.
4. Supported Key Events by MultiButton
| Event | Description |
<span>PRESS_DOWN</span> |
Triggered every time the key is pressed down |
<span>PRESS_UP</span> |
Triggered every time the key is released |
<span>PRESS_REPEAT</span> |
Triggered on repeated presses, with <span>repeat</span> counting the number of consecutive presses |
<span>SINGLE_CLICK</span> |
Single click key event |
<span>DOUBLE_CLICK</span> |
Double click key event |
<span>LONG_PRESS_START</span> |
Triggered once when the long press time threshold is reached |
<span>LONG_PRESS_HOLD</span> |
Triggered continuously during the long press |
5. Example Code
#include "button.h"
uint8_t btn1_id = 0;
struct Button btn1;
uint8_t read_button_GPIO(uint8_t button_id)
{
// you can share the GPIO read function with multiple Buttons
switch(button_id)
{
case btn1_id:
return HAL_GPIO_ReadPin(B1_GPIO_Port, B1_Pin);
break;
default:
return 0;
break;
}
}
void BTN1_PRESS_DOWN_Handler(void* btn)
{
// do something...
}
void BTN1_PRESS_UP_Handler(void* btn)
{
// do something...
}
...
int main()
{
button_init(&btn1, read_button_GPIO, 0, btn1_id);
button_attach(&btn1, PRESS_DOWN, BTN1_PRESS_DOWN_Handler);
button_attach(&btn1, PRESS_UP, BTN1_PRESS_UP_Handler);
button_attach(&btn1, PRESS_REPEAT, BTN1_PRESS_REPEAT_Handler);
button_attach(&btn1, SINGLE_CLICK, BTN1_SINGLE_Click_Handler);
button_attach(&btn1, DOUBLE_CLICK, BTN1_DOUBLE_Click_Handler);
button_attach(&btn1, LONG_PRESS_START, BTN1_LONG_PRESS_START_Handler);
button_attach(&btn1, LONG_PRESS_HOLD, BTN1_LONG_PRESS_HOLD_Handler);
button_start(&btn1);
// make the timer invoking the button_ticks() interval 5ms.
// This function is implemented by yourself.
__timer_start(button_ticks, 0, 5);
while(1)
{}
}
6. Conclusion
MultiButton is a simple and powerful key driver module that can help you easily manage multiple keys and handle key events asynchronously. Using MultiButton can simplify key handling code, improve code readability and maintainability, and make your key logic clearer and more flexible!
Project Address: https://github.com/0x1abin/MultiButton