Button APIs
The Button class provides a simple way to read the state of a button. There are two ways to configure the functionality of the button.
The first uses Button::Config to configure the button to call a function when the button is pressed or released and uses the Interrupt class’ task and ISR for signaling. At any time, a user may also call the is_pressed method to read the current state of the button’s input pin.
The second uses Button::SimpleConfig to simply configure the button as an input with configurable pull-up or pull-down resistors and a configurable active state (high or low). In this configuration, the input is read manually any time the user calls the is_pressed method.
API Reference
Header File
Classes
-
class Button : protected espp::Interrupt
A class to handle a button connected to a GPIO.
This class uses the ESP-IDF GPIO interrupt handler to detect button presses and releases. It then calls the callback function with the event.
Simple Button Example (No Callback / Interrupt)
// create the button espp::Button simple_button({ .name = "Button 12", .gpio_num = GPIO_NUM_12, .active_level = espp::Interrupt::ActiveLevel::LOW, .pullup_enabled = false, .pulldown_enabled = false, .log_level = espp::Logger::Verbosity::WARN, }); for (int i = 0; i < 10; i++) { logger.info("Button 12 state: {}", simple_button.is_pressed()); std::this_thread::sleep_for(1s); }
Button Example (With Callback / Interrupt)
static auto start = std::chrono::high_resolution_clock::now(); std::string button_topic = "button/state"; std::string button_component_name = "button"; // create a button espp::Button button({ .name = "Button 12", .interrupt_config = { .gpio_num = GPIO_NUM_12, .callback = [&](const espp::Interrupt::Event &event) { auto now = std::chrono::high_resolution_clock::now(); auto elapsed = std::chrono::duration<float>(now - start).count(); logger.info("[Callback][{:.3f}] Button {} state changed to: {}", elapsed, event.gpio_num, event.active); // serialize the event std::error_code ec; std::vector<uint8_t> buffer; auto bytes_written = espp::serialize(event, buffer); if (bytes_written > 0) { // publish the event espp::EventManager::get().publish(button_topic, buffer); } else { logger.error("Failed to serialize button state"); } }, .active_level = espp::Interrupt::ActiveLevel::LOW, .interrupt_type = espp::Interrupt::Type::ANY_EDGE, .pullup_enabled = false, .pulldown_enabled = false, }, .task_config = { .name = "Button 12 task", .stack_size_bytes = 8192, .priority = 5, }, .log_level = espp::Logger::Verbosity::WARN, }); logger.info("Initial button state: {}", button.is_pressed()); // register subscriber on the button topic auto &em = espp::EventManager::get(); auto did_sub = em.add_subscriber(button_topic, "example subscriber", [&](const std::vector<uint8_t> &data) { auto now = std::chrono::high_resolution_clock::now(); auto elapsed = std::chrono::duration<float>(now - start).count(); // deserialize the data std::error_code ec; auto state = espp::deserialize<espp::Interrupt::Event>(data, ec); if (!ec) { logger.info("[Subscriber][{:.3f}]: button {} state changed to: {}", elapsed, state.gpio_num, state.active); } else { logger.error("Failed to deserialize button state: {}", ec.message()); } }); logger.info("Subscribed: {}", did_sub); // create another button espp::Button button_2({ .name = "Button 0", .interrupt_config = { .gpio_num = GPIO_NUM_0, .callback = [&](const espp::Interrupt::Event &event) { logger.info("Button {} state changed to: {}", event.gpio_num, event.active); }, .active_level = espp::Interrupt::ActiveLevel::LOW, .interrupt_type = espp::Interrupt::Type::ANY_EDGE, .pullup_enabled = false, .pulldown_enabled = false, .filter_type = espp::Interrupt::FilterType::PIN_GLITCH_FILTER, }, .task_config = { .name = "Button 0 task", .stack_size_bytes = 8192, .priority = 5, }, .log_level = espp::Logger::Verbosity::WARN, }); while (true) { std::this_thread::sleep_for(1s); }
Public Types
-
using ActiveLevel = Interrupt::ActiveLevel
The active level of the button.
-
using callback_t = Interrupt::event_callback_fn
The callback function type for the button.
Public Functions
-
inline explicit Button(const Config &config)
Construct a button.
This constructor is useful for buttons that require a custom task or interrupt configuration and need to register a callback function.
- Parameters
config – The configuration for the button
-
inline explicit Button(const SimpleConfig &config)
Construct a button with a simple configuration.
This constructor is useful for simple buttons that don’t require a custom task or interrupt configuration and do not need to register a callback function.
- Parameters
config – The simple configuration for the button
-
inline bool is_pressed() const
Whether the button is currently pressed.
- Returns
True if the button is pressed, false otherwise
Protected Types
-
enum class Type
The type of interrupt to use for the GPIO.
Values:
Protected Functions
-
inline size_t get_min_queue_size() const
Get the minimum number of free spaces in the queue.
This will return the minimum number of free spaces in the queue Over the lifetime of the object. This can be used to determine if the queue size is too small for the number of interrupts that are being received. It may also help indicate if the interrupt task priority is too low, preventing the queue from being serviced. Finally, it may also help to indicate if additional filtering may be needed on the interrupt line (either using the FilterType or with hardware filtering).
- Returns
The minimum number of free spaces in the queue
-
inline void add_interrupt(const PinConfig &interrupt)
Add an interrupt to the interrupt handler.
- Parameters
interrupt – The interrupt to add
-
inline bool is_active(const PinConfig &interrupt) const
Get the state of the interrupt.
This will check the raw logic level of the GPIO and return whether the interrupt is active or not according to the active level that was set in the configuration.
- Parameters
interrupt – The interrupt to check
- Returns
Whether the interrupt is active
-
inline std::vector<std::pair<int, bool>> get_active_states()
Get the state of all the interrupts.
- Returns
A vector of the states of the interrupts as pairs of the GPIO number and whether the interrupt is active
-
inline const std::string &get_name() const
Get the name of the component
Note
This is the tag of the logger
- Returns
A const reference to the name of the component
-
inline void set_log_tag(const std::string_view &tag)
Set the tag for the logger
- Parameters
tag – The tag to use for the logger
-
inline espp::Logger::Verbosity get_log_level() const
Get the log level for the logger
See also
See also
- Returns
The verbosity level of the logger
-
inline void set_log_level(espp::Logger::Verbosity level)
Set the log level for the logger
See also
See also
- Parameters
level – The verbosity level to use for the logger
-
inline void set_log_verbosity(espp::Logger::Verbosity level)
Set the log verbosity for the logger
See also
See also
See also
Note
This is a convenience method that calls set_log_level
- Parameters
level – The verbosity level to use for the logger
-
inline espp::Logger::Verbosity get_log_verbosity() const
Get the log verbosity for the logger
See also
See also
See also
Note
This is a convenience method that calls get_log_level
- Returns
The verbosity level of the logger
-
inline void set_log_rate_limit(std::chrono::duration<float> rate_limit)
Set the rate limit for the logger
See also
Note
Only calls to the logger that have _rate_limit suffix will be rate limited
- Parameters
rate_limit – The rate limit to use for the logger
-
struct Config
The configuration for the button.
Public Members
-
std::string_view name = {"Button"}
Name of the button.
-
int isr_core_id = -1
The core ID to run the interrupt service routine on.
-
Task::BaseConfig task_config = {}
Configuration for the button task.
-
std::string_view name = {"Button"}
-
struct SimpleConfig
The simple configuration for the button.
This is a simplified configuration for the button that only requires the GPIO number and the active level of the button. This is useful for simple buttons that don’t require a custom task or interrupt configuration and do not need to register a callback function.
Public Members
-
std::string_view name = {"Button"}
Name of the button.
-
gpio_num_t gpio_num
The GPIO number for the button.
-
ActiveLevel active_level = ActiveLevel::LOW
The active level of the button.
-
bool pullup_enabled = true
Whether to enable the internal pullup resistor for the button
-
bool pulldown_enabled = false
Whether to enable the internal pulldown resistor for the button
-
std::string_view name = {"Button"}
-
using ActiveLevel = Interrupt::ActiveLevel