Platform-portable button detection library with multi-click and long-press support.
More...
Platform-portable button detection library with multi-click and long-press support.
Overview
OneButton is a button event detection library originally inspired by Arduino OneButton, ported to bare-metal embedded systems (STM32, ESP32).
Features:
- Single-click detection
- Double-click detection
- Long-press detection with start/stop events
- Hardware debouncing
- Configurable timing parameters
- Non-blocking, poll-based operation
- Multi-button support
Platform Selection
Select your target platform by defining ONE of the following:
- STM_PLATFORM - For STM32 microcontrollers with HAL
- ESP_PLATFORM - For ESP32 microcontrollers with ESP-IDF
Example:
#define STM_PLATFORM
#define ESP_PLATFORM
- Warning
- Define ONLY ONE platform macro at a time
Platform-Specific Configuration
STM32 Platform (HAL-based)
Macros:
- OB_READ_PIN() → HAL_GPIO_ReadPin(Btn->GpioPort, Btn->GpioPin)
- OB_GET_TICK() → HAL_GetTick() (1ms SysTick)
- OB_BUTTON_PRESSED → GPIO_PIN_RESET (0 - active low)
- OB_BUTTON_NOT_PRESSED → GPIO_PIN_SET (1 - pull-up)
Initialization:
OneButtonInit(&myButton, GPIOA, GPIO_PIN_0);
GPIO Configuration Requirements:
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = GPIO_PIN_0;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
ESP32 Platform (ESP-IDF)
Required Headers:
- xtimers.h - Custom timer wrapper
- ot_app.h - Application header
Macros:
- OB_READ_PIN() → gpio_get_level(Btn->GpioPin)
- OB_GET_TICK() → xTim_getTick() (custom millisecond timer)
- OB_BUTTON_PRESSED → 0 (active low)
- OB_BUTTON_NOT_PRESSED → 1 (pull-up)
Initialization:
OneButtonInit(&myButton, GPIO_NUM_9);
GPIO Configuration Requirements:
gpio_config_t io_conf = {
.pin_bit_mask = (1ULL << GPIO_NUM_9),
.mode = GPIO_MODE_INPUT,
.pull_up_en = GPIO_PULLUP_ENABLE,
.pull_down_en = GPIO_PULLDOWN_DISABLE,
.intr_type = GPIO_INTR_DISABLE
};
gpio_config(&io_conf);
Usage Example
void onSingleClick(uint16_t btnNum) {
printf("Button %d: Single click\n", btnNum);
}
void onDoubleClick(uint16_t btnNum) {
printf("Button %d: Double click\n", btnNum);
}
void onLongPressStart(uint16_t btnNum) {
printf("Button %d: Long press started\n", btnNum);
}
void onLongPressStop(uint16_t btnNum) {
printf("Button %d: Long press stopped\n", btnNum);
}
void setup() {
#ifdef STM_PLATFORM
OneButtonInit(&button1, GPIOA, GPIO_PIN_0);
#endif
#ifdef ESP_PLATFORM
OneButtonInit(&button1, GPIO_NUM_9);
#endif
}
void loop() {
}
Porting to New Platforms
To add support for a new platform:
- Add platform definition at top of OneButton.h:
- Add platform-specific macros block:
#ifdef OB_MYPLATFORM
#define OB_READ_PIN() my_gpio_read(Btn->GpioPin)
#define OB_GET_TICK() my_get_millis()
#define OB_BUTTON_PRESSED 0
#define OB_BUTTON_NOT_PRESSED 1
#endif
- Update OneButton_t structure if needed (e.g., add port field)
- Add platform-specific initialization in OneButton.c:
#ifdef OB_MYPLATFORM
}
#endif
- See also
- OneButton.c for implementation details
-
ad_button.h for integration with OpenThread application
- Version
- 1.0
- Date
- Nov 19, 2022
- Author
- Jan Łukaszewicz (plhar.nosp@m.eo@g.nosp@m.mail..nosp@m.com)
- Copyright
- © 2025 MIT LICENCE