{"id":73,"date":"2026-02-25T18:42:43","date_gmt":"2026-02-25T17:42:43","guid":{"rendered":"https:\/\/elrebo.de\/?p=73"},"modified":"2026-05-24T17:09:50","modified_gmt":"2026-05-24T15:09:50","slug":"generic_button","status":"publish","type":"post","link":"https:\/\/www.elrebo.de\/index.php\/2026\/02\/25\/generic_button\/","title":{"rendered":"generic_button"},"content":{"rendered":"\n<p id=\"block-414798d8-8aad-40c3-9c67-fe10a7d97400\">An ESP-IDF component for <a href=\"https:\/\/elrebo.de\/index.php\/2026\/02\/20\/physical-computing\/\">Physical Computing<\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"block-b7af8fe6-ee05-4737-b8a7-bd14cb052bab\">Purpose<\/h2>\n\n\n\n<p id=\"block-edac24cc-24a7-4687-b040-30f006a17a40\">Generic Button functionality for ESP32 systems.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"block-6e8ded18-4a39-4795-b42d-58151ceec5b0\">How it is done<\/h2>\n\n\n\n<p id=\"block-fb52741a-2856-4f1e-9c98-51bc1968d9a7\">For every button you want to use, you have to<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>create an instance of class GenericButton <\/li>\n<\/ul>\n\n\n\n<p>For every button event you want to detect, you have to<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>prepare a callback function to handle the event<\/li>\n\n\n\n<li>register the event and the callback function for the button<\/li>\n<\/ul>\n\n\n\n<p id=\"block-fb52741a-2856-4f1e-9c98-51bc1968d9a7\">When one of the registered events occurs, the corresponding callback function is triggered.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Where to find it<\/h2>\n\n\n\n<p id=\"block-c6668f66-9f3b-478b-be26-25514e5c4c51\"><code>generic_button<\/code> is published on the ESP Registry at <a href=\"https:\/\/components.espressif.com\/components\/elrebo-de\/generic_button\">https:\/\/components.espressif.com\/components\/elrebo-de\/generic_button<\/a>.<\/p>\n\n\n\n<p id=\"block-59b5f8f9-187f-4ca0-a6fc-8e3b1cb6081a\">The source code can be found at <a href=\"https:\/\/github.com\/elrebo-de\/generic_button\">https:\/\/github.com\/elrebo-de\/generic_button<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"block-332a00f2-d662-4719-9763-0238503494eb\">How to use it<\/h2>\n\n\n\n<p id=\"block-0baaf1e0-c189-43d9-9dcd-f9d53d74c9f1\">As an ESP-IDF component <code>generic_button<\/code> must be included into idf_component.yml as a dependency. As usual this can be done by executing this command:<\/p>\n\n\n\n<p id=\"block-a12d2abd-f019-4d1b-8f93-b7255840b2b0\"><code>idf.py add-dependency \"elrebo-de\/generic_button^1.1.0\"<\/code><\/p>\n\n\n\n<p id=\"block-b75afaa5-4920-4296-8fe6-0d33ce677167\">Now you can include <code>generic_button.hpp<\/code> and use the GenericButton class in your program.<\/p>\n\n\n\n<p id=\"block-b75afaa5-4920-4296-8fe6-0d33ce677167\">There are two constructors available for the class, depending on the button type:<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Button type GPIO<\/h3>\n\n\n\n<p id=\"block-7bce5294-9d86-49a3-b85e-2b3da24ebca5\">There are two parameters in the constructor of class GenericButton for GPIO buttons:<\/p>\n\n\n\n<ul id=\"block-0a19c02c-7cd6-4950-bcee-ac26320b2c0a\" class=\"wp-block-list\">\n<li>tag &#8211; the tag used for logging from this instance of GenericButton class<\/li>\n\n\n\n<li>btn_gpio_cfg &#8211; the structure defining the configuration of the GPIO button<\/li>\n<\/ul>\n\n\n\n<p>The structure btn_gpio_cfg is of type button_gpio_config_t and defines these items:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>button_gpio_config_t btn_gpio_cfg = {\n    .gpio_num = 9,\n    .active_level = 0,\n    .enable_power_save = false,\n    .disable_pull = false,\n};<\/code><\/pre>\n\n\n\n<p>Here the onBoard button of a <code>ESP32-C6-DevKitM-1 V1.0<\/code> board is defined:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>button_gpio_config_t btn_gpio_cfg = {\n        .gpio_num = 9,\n        .active_level = 0,\n        .enable_power_save = false,\n        .disable_pull = false,\n    };\n    GenericButton onBoardButton(\n\t   std::string(\"onBoardButton\"),\n\t   btn_gpio_cfg\n\t);<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Button type ADC<\/h3>\n\n\n\n<p id=\"block-7bce5294-9d86-49a3-b85e-2b3da24ebca5\">There are two parameters in the constructor of class GenericButton for ADC buttons:<\/p>\n\n\n\n<ul id=\"block-0a19c02c-7cd6-4950-bcee-ac26320b2c0a\" class=\"wp-block-list\">\n<li>tag &#8211; the tag used for logging from this instance of GenericButton class<\/li>\n\n\n\n<li>btn_adc_cfg &#8211; the structure defining the configuration of the ADC button<\/li>\n<\/ul>\n\n\n\n<p>The structure btn_adc_cfg is of type button_adc_config_t and defines these items:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>    \/\/ adcButton0\n    button_adc_config_t btn_adc_cfg_0 = {\n        \/**&lt; handle of adc unit, \n           if NULL will create new one internal, \n           else will use the handle *\/\n        .adc_handle = adc_handle,  \n\n        \/**&lt; ADC unit *\/         \n        .unit_id = ADC_UNIT_1,               \n\n        \/**&lt; Channel of ADC *\/\n        .adc_channel = ADC1_GPIO0_CHANNEL,  \n\n        \/**&lt; button index on the channel *\/ \n        .button_index = 0, \n\n        \/**&lt; min voltage in mv corresponding to the button *\/                  \n        .min = 0,   \n\n        \/**&lt; max voltage in mv corresponding to the button *\/                         \n        .max = 154,                          \n    };<\/code><\/pre>\n\n\n\n<p>Here the second button_index in a resistor ladder of six buttons is defined:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>    \/\/ adcButton1\n    button_adc_config_t btn_adc_cfg_1 = {\n        .adc_handle = adc_handle,\n        .unit_id = ADC_UNIT_1, \n        .adc_channel = ADC1_GPIO0_CHANNEL,\n        .button_index = 1,\n        .min = 155,\n        .max = 477,\n    };\n    GenericButton onBoardButton(\n\t   std::string(\"adcButton1\"),\n\t   btn_adc_cfg_1\n\t);<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Event Callback Functions<\/h3>\n\n\n\n<p>For every event you want to detect, you have to define a callback function. This function is called, when the event occurs.<\/p>\n\n\n\n<p>Here is an example for the BUTTON_SINGLE_CLICK event:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ Callback function for BUTTON_SINGLE_CLICK event from onBoardButton\nextern \"C\" void callback_onBoardButton_BUTTON_SINGLE_CLICK(void *arg, void *data)\n{\n    ESP_LOGI(\"onBoardButton Callback\", \"for Event BUTTON_SINGLE_CLICK called!\");\n\n    iot_button_print_event((button_handle_t)arg);\n\n    \/\/ ToDo: add code here to execute in case of a single click\n}<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Register Callback Function for Event<\/h3>\n\n\n\n<p>To register this callback function with your button you have to call <code>RegisterCallbackForEvent<\/code>with your GenericButton instance (here <code>onBoardButton<\/code>):<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>onBoardButton.RegisterCallbackForEvent(BUTTON_SINGLE_CLICK, callback_onBoardButton_BUTTON_SINGLE_CLICK);<\/code><\/pre>\n\n\n\n<p>For ADC buttons you can hand in the button configuration with parameter <code>data<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>adcButton1.RegisterCallbackForEvent(BUTTON_SINGLE_CLICK, callback_onBoardButton_BUTTON_SINGLE_CLICK, (void *)&amp;btn_adc_cfg_1);<\/code><\/pre>\n\n\n\n<p>Now you are able to identify in the callback function which ADC button has triggered the event.<\/p>\n\n\n\n<p>Please have a look at the two examples <code>onBoardButton<\/code> and <code>adcButtons<\/code>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>An ESP-IDF component for Physical Computing Purpose Generic Button functionality for ESP32 systems. How it is done For every button you want to use, you have to For every button event you want to detect, you have to When one of the registered events occurs, the corresponding callback function is triggered. Where to find it [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":106,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-73","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oss"],"_links":{"self":[{"href":"https:\/\/www.elrebo.de\/index.php\/wp-json\/wp\/v2\/posts\/73","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.elrebo.de\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.elrebo.de\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.elrebo.de\/index.php\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.elrebo.de\/index.php\/wp-json\/wp\/v2\/comments?post=73"}],"version-history":[{"count":6,"href":"https:\/\/www.elrebo.de\/index.php\/wp-json\/wp\/v2\/posts\/73\/revisions"}],"predecessor-version":[{"id":574,"href":"https:\/\/www.elrebo.de\/index.php\/wp-json\/wp\/v2\/posts\/73\/revisions\/574"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.elrebo.de\/index.php\/wp-json\/wp\/v2\/media\/106"}],"wp:attachment":[{"href":"https:\/\/www.elrebo.de\/index.php\/wp-json\/wp\/v2\/media?parent=73"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.elrebo.de\/index.php\/wp-json\/wp\/v2\/categories?post=73"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.elrebo.de\/index.php\/wp-json\/wp\/v2\/tags?post=73"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}