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?

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

  • The button handling library will give you events when buttons are pressed and released. This has not direct implication on BLE or anything else, but then you should do whatever you what to do in the event handler. You should find examples of most of the things you mention by looking through the BLE examples.

  • Thank you Einar. Much appreciated for your support.

  • Hi Einar,

    As I mentioned in my other post, I was able to implement a solution based on the bsp library. I thought I would give this approach a try as I wanted to try to work with a custom board header file for my application. I am not sure if there is some limitation with this approach but I cannot seem to detect button presses when I increase the frequency of the timer/notifications to 50Hz. I can’t even trigger the original BLE button 1 disconnect function  at this rate. Any idea what might be causing this or how to resolve it?

  • Hi,

    From our earlier discussion I remember that you found that there is a large number of interrupts per button event (due to bounce). It is expected that these are lost if these are not services immediately due to a higher priority interrupt (SoftDevice), as the CPU cannot queue up multiple interrupts for the same source (interrupt number). So to handle this you should limit the number of interrupt by low-pass filtering the button presses (using a capacitor).

Reply
  • Hi,

    From our earlier discussion I remember that you found that there is a large number of interrupts per button event (due to bounce). It is expected that these are lost if these are not services immediately due to a higher priority interrupt (SoftDevice), as the CPU cannot queue up multiple interrupts for the same source (interrupt number). So to handle this you should limit the number of interrupt by low-pass filtering the button presses (using a capacitor).

Children
Related