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

Missing interrupt sometimes

Hello all,

I am using the nrf51822 chip as well as an accelerometer LIS3DH. The device does advertising and turns on a LED when it is active.

The accelerometer is configured to detect when the device has not been moved for 2 minutes. When this happens, the nRF51822 stops advertising and switches off the LED until the accelerometer detectes movement again. This works with an interruption (same interruption for putting to sleep as well as to awake).

I have found that sometimes the interrupt handler does not trigger (I checked with an oscylloscope that the accelerometer does trigger the interrupt, so the problem is in the processor). When this happens, I have to wait a couple of minutes and then the processor awakes normally.

I attach here the relevant part of the code:

static void accel_interrupt_handler1(uint8_t pin_no, uint8_t button_action)
{
stopped_person=button_action;
}

The stopped_person variable is dealt with in another part of the code.

The initialization of the interrupt is:

static void interrupts_init(void)
{	
	//Interrupts
	static app_button_cfg_t buttons[] =
    {
				{ACCEL_INT1, APP_BUTTON_ACTIVE_HIGH, NRF_GPIO_PIN_NOPULL, accel_interrupt_handler1},			
    };	
		
    APP_BUTTON_INIT(buttons, sizeof(buttons) / sizeof(buttons[0]), BUTTON_DETECTION_DELAY, true); 			
}

It is important to note that this works most of times. Could anyone tell me why I am missing some interrupts?

Thank you very much!

  • Hi dblasco, Why are you using button library for initializing the interrupt? most likely your problem is because of using button library and have detection delay. Can you set detection delay to 0 and see what happens? I still do not like using button handler instead use something like below

    static void gpio_init(void)
    {
        ret_code_t err_code;
    
        if (!nrf_drv_gpiote_is_init())
        {
            err_code = nrf_drv_gpiote_init();
            APP_ERROR_CHECK(err_code);
        }
    
        nrf_drv_gpiote_in_config_t in_config = GPIOTE_CONFIG_IN_SENSE_LOTOHI(false);
        in_config.pull = NRF_GPIO_PIN_PULLDOWN;
    
        err_code = nrf_drv_gpiote_in_init(SENSOR_INT_PIN, &in_config, sensor_int_handler);
        APP_ERROR_CHECK(err_code);
    
        nrf_drv_gpiote_in_event_enable(SENSOR_INT_PIN, true);
    }
    

    This above code is for SDK10 and i have not ported it to SDK11 but i am assuming it should not change (too much)

    I have tried using LIS2DH and it works perfectly fine for me. You said that you have verified that the accelerometer does fire interrupt when it is moving. This means that the configuration of that sensor probably is correct. How are you sleeping in the application? are you using sd_app_Evt_Wait or __WFE or __WFI?

    I would like to see how you are sleeping (does your application sleep on condition?)

  • Hi Aryan,

    thank you for your response. I will try using the code you provided. I will tell the results. May I ask why the button handler is not ok? Even changing the delay debounce to 0?

    Yes, I think there is no problem with the accelerometer.

    I am sleeping by means of sd_app_evt_wait().

    The application is always sleeping, and it awakes when any handler comes up (advertising, timer, ...)

  • button handler is designed keeping button mechanics in mind. I think it should work if you make debounce delay to 0, but even then why do you want to have so much overhead for your interrupt? Everytime there is an interrupt, the button handler library is run just to pass the interrupt to your handler.

  • After some days trying this, I think the problem has been solved by using the gpiote library.

    Thank you!

Related