This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

GPIOTE Interrupt doesn't catch button press

Hi all,

I am currently developing on the RIGADO BMD-300 (nRF52832) eval board. I have the following code setup to interrupt on a button press (aim is to have 9 buttons). I am storing the current state of the button in a single byte (m_custom_value). The idea is that all buttons are pulled-up so that start high. As the IN Sense is set to Toggle, i was assuming that when the button is pressed, i would get an interrupt and when the button is released i would get another interrupt. Ultimately, i would expect the button state to stay low (0) if i hold down the button and then change to high when i release the button. 

This seams to work, but not very well. I am not interrupting on every press and release. Can someone please tell me if there is a more robust way of doing this instead of polling the specific inputs and using lots of processing time?

Regards,

Zoran

void in_pin_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action)
{

    if (pin == GL1)
    {
        value[2] = value[2] ^ 0x01;
    }
    else if (pin == GL2)
    {
        value[2] = value[2] ^ 0x02;
    }
}

static void gpio_init(void)
{
    ret_code_t err_code;

    value[2] = 0xFF;

    if (!nrf_drv_gpiote_is_init())
    {
        err_code = nrf_drv_gpiote_init();
        APP_ERROR_CHECK(err_code);
    }

    nrf_drv_gpiote_out_config_t out_config = GPIOTE_CONFIG_OUT_SIMPLE(false);
    err_code = nrf_drv_gpiote_out_init(12, &out_config);
    APP_ERROR_CHECK(err_code);

    //Setup GL1 Input
    nrf_drv_gpiote_in_config_t in_config_GL1 = GPIOTE_CONFIG_IN_SENSE_TOGGLE(true);
    in_config_GL1.pull = NRF_GPIO_PIN_PULLUP;

    err_code = nrf_drv_gpiote_in_init(GL1, &in_config_GL1, in_pin_handler);
    APP_ERROR_CHECK(err_code);

    nrf_drv_gpiote_in_event_enable(GL1, true);

    //Setup GL2 Input
    nrf_drv_gpiote_in_config_t in_config_GL2 = GPIOTE_CONFIG_IN_SENSE_TOGGLE(true);
    in_config_GL2.pull = NRF_GPIO_PIN_PULLUP;

    err_code = nrf_drv_gpiote_in_init(GL2, &in_config_GL2, in_pin_handler);
    APP_ERROR_CHECK(err_code);

    nrf_drv_gpiote_in_event_enable(GL2, true);
}

  • That explains it. You need to low pass filter the button (hardware debouncing) if you want a single interrupt for each button transition. If not you need to handle multiple rapid interrupts (due to switching noise), and debounce in software.

    I would say that the best approach is to filter the button signal as we do in the DK, as this limits the number of interrupts you have to handle in a short time. You could do software debouncing in addition to be sure, but you might not need it. I you want software debouncing you can for instance use the Button handling library.

  • Hi Einar,

    Thank you for this feedback. As my BLE application is based on the ble_app_template example and it uses the BSP BLE Button Module, do i need to be aware of any conflicts with the Button handler, for example with timers? 

    Also, is this a good example to follow for this? https://github.com/NordicPlayground/nrf51-app-button-example/blob/master/main.c 

    I have also seen others on here suggesting to make a custom board header file and using the BSP functionality to handle buttons. Are there any benefits to doing this over using the button handling library?

  • The button handling library (app_button)  uses the app timer library, which is a library that is used to share RTC1 amongst an arbitrary number of timers, so there will not be any conflicts in that regard.

    I personally find the BSP a bit too complex for simple applications. It makes sense in the SDK where we need to support a large variety of boards, but less for other applications. So I would probably use the button handling library directly instead of via the BSP, but that is just my preference.

    If you want to use the button library directly you can for instance refer to how it is used in the BSP (bsp.c), or perhaps better one of the other applications that use it directly, for instance ble_app_blinky.

  • Hi Einar,

    Do you recommend that i remove the BSP implementation in the ble_app_template example and implement the few BLE button funtions via the button handling library myself, and then expand this to include my other buttons?

  • I have extended the ble_app_template to include a custom service that  sends notifications to a central device. As mentioned earlier, the peripheral will need to monitor the state of 9 push buttons and 1 analog input. I am not sure how to implement the following BLE button functions directly through the button library. These should include wake up, sleep, disconnect, wakeup bond delete and whitelist off as is currently working in this ble_app_template example. Any chance you could point me in the right direction? 

Related