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);
}

Parents
  • Hi,

    I do not immediately see any issue with your setup, and I would not expect you to lose interrupts. How have you verified this? Could you for instance toggle a GPIO in the event handler (in_pin_handler()) and use a logic analyzer to observe the toggled pin(s) in relationship with the input pins, to see verify if that is really the case?

  • Hi Einar,

    Thanks for the feedback. I have setup an output pin and toggled this in the in_pin_handler() event handler along with storing the state of the button as in the code above in value[] byte. I was observing the state of the output pin on an oscilloscope as i was pressing a momentary pushbutton connected to the input. With this setup i could frequently see that during the button press the interrupt would not capture the event (whether high to low (push down) or low to high (release button). 

    I am doing this in conjunction with sending the value of "value[]" over BLE. Do you think that BLE will conflict with the button interrupt priority?

  • 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? 

Reply
  • 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? 

Children
Related