This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts
This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

app_button library event fired on release

Hey, I recently got the nrf52 DK and tried to make use of the app_button library to have easy to use debouncing. As far as I understood the library, the event should be fired when the button is pressed. The thing is, when the button is released, the event is also fired. Is that working as intended? I tried to work around this with the app_button_is_pushed query, but this will also be true even after I released the button. I guess I'm doing something wrong here. Here is my code.

#include <stdbool.h>
#include <stdint.h>
#include "nrf.h"
#include "nrf_gpiote.h"
#include "nrf_gpio.h"
#include "boards.h"
#include "nrf_drv_ppi.h"
#include "nrf_drv_timer.h"
#include "nrf_drv_gpiote.h"
#include "app_button.h"
#include "app_timer.h"
#include "app_error.h"
#include "app_scheduler.h"
#include "nrf_delay.h"


#define NUM_OF_BUTTONS 1

#define APP_TIMER_PRESCALER 0
#define APP_TIMER_OP_QUEUE_SIZE 2

static void button_event_handler(uint8_t pin_no, uint8_t button_action)
{
	
	if(app_button_is_pushed(BUTTON_1) == true)
	{
			bsp_board_led_on(1);
			nrf_delay_ms(500);
			bsp_board_led_off(1);
	}
  //code run on button state change

	
}

//Configure a button with pullup and detection on low state
static const app_button_cfg_t app_buttons[NUM_OF_BUTTONS] = 
{
    {BUTTON_1, false, BUTTON_PULL, button_event_handler}
};

static void lfclk_config(void)
{
    NRF_CLOCK->LFCLKSRC             = (CLOCK_LFCLKSRC_SRC_Xtal << CLOCK_LFCLKSRC_SRC_Pos);
    NRF_CLOCK->EVENTS_LFCLKSTARTED  = 0;
    NRF_CLOCK->TASKS_LFCLKSTART     = 1;
    while (NRF_CLOCK->EVENTS_LFCLKSTARTED == 0)
    {
        //Do nothing.
    }
    NRF_CLOCK->EVENTS_LFCLKSTARTED = 0;
}


int main(void)
{

		lfclk_config();
    uint32_t err_code;

    //app_button uses app_timer, if this is not initialize, then initialize it here
    APP_TIMER_INIT(APP_TIMER_PRESCALER, APP_TIMER_OP_QUEUE_SIZE, false);

	
	
    //init app_button module, 50ms detection delay (button debouncing)
    err_code = app_button_init((app_button_cfg_t *)app_buttons,
                                   NUM_OF_BUTTONS,
                                   APP_TIMER_TICKS(50, APP_TIMER_PRESCALER));
    APP_ERROR_CHECK(err_code);

    err_code = app_button_enable();
    APP_ERROR_CHECK(err_code);

		bsp_board_leds_init();

    // Enter main loop.
    while(true)
    {

    }
}

Someone knows if I did something wrong or how I can edit the code so the led only blinks if I press the button and not when I release it? Thanks in advance.

  • Hi,

    You can detect if the button is pushed or released. The button event handler will be fired on both events.

    The button_action variable in

    button_event_handler(uint8_t pin_no, uint8_t button_action)
    

    will be either APP_BUTTON_PUSH or APP_BUTTON_RELEASE. APP_BUTTON_PUSH will indicate either high or low depending on the active state:

    typedef struct
    {
        uint8_t              pin_no;           /**< Pin to be used as a button. */
        uint8_t              active_state;     /**< APP_BUTTON_ACTIVE_HIGH or APP_BUTTON_ACTIVE_LOW. */
        nrf_gpio_pin_pull_t  pull_cfg;         /**< Pull-up or -down configuration. */
        app_button_handler_t button_handler;   /**< Handler to be called when button is pushed. */
    } app_button_cfg_t;
    

    Just add a switch case in the button event handler to check if the button_action is APP_BUTTON_PUSH or APP_BUTTON_RELEASE.

    Ole

  • Thank you very much. Didn't see that. Can be closed.

  • Thanks, I found this useful too.

Related