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

Reset on_ble_connect when button event

Hello,

my problem is reproducable with this Setup:

  • nRF5-DK with ble_blinky_example (central)
  • nRF5-DK with ble_blinky_example (peripheral)
  • Press Button1 immediately on the peripheral after connecting (LED2 lights up).
  • watch how the peripheral goes back to Advertising (resets)
  • Press Button1 after the Connection is established a while, everything works fine.

 When the button_event_handler() is empty, the devices stay connected. What causes this and how to avoid it?

Kind regards,

DanKA

  • When i use a single shot timer to wait a couple milliseconds before i call app_button_enable(), there is no reset:

    in on_ble_evt():

            case BLE_GAP_EVT_CONNECTED:
                    NRF_LOG_INFO("Connected\r\n");
                    err_code = app_timer_stop(m_adv_con_led_timer_id);
                    APP_ERROR_CHECK(err_code);
                    //bsp_board_led_on(CONNECTED_LED_PIN);
                    m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
                    err_code = app_timer_start(m_off_timer_id, APP_TIMER_TICKS(400, APP_TIMER_PRESCALER), NULL);
                    APP_ERROR_CHECK(err_code);
                    break; // BLE_GAP_EVT_CONNECTED

    and then the timer_handler

                    uint8_t  err_code = app_button_enable();
                    APP_ERROR_CHECK(err_code);
                    bsp_board_led_on(CONNECTED_LED_PIN);

  • which SDK version are you testing this on? And which softdevice version you have on the board?

  • Hello Aryan, 

    i use SDK 12.3 and Softdevice S130 2.0.1/ Softdevice S132 3.0.0. I attached a video.

    • Peripheral left, central right.
    • First: in connection, everything fine. (Button press is indicated with a led).
    • Second: Switch off and on the peripheral, same with resetting  via IF BOOT/RESET. Press Button1 directly after connecting (LED2 lights up). Board goes back to advertising.
    • Third: Wait after connection. Everything works fine. (Button press is indicated with a led).
  • I think the problem is with the below code

    static void button_event_handler(uint8_t pin_no, uint8_t button_action)
    {
        uint32_t err_code;
    
        switch (pin_no)
        {
            case LEDBUTTON_BUTTON_PIN:
                NRF_LOG_INFO("Send button state change.\r\n");            
                err_code = ble_lbs_on_button_change(&m_lbs, button_action);
                if (err_code != NRF_SUCCESS &&
                    err_code != BLE_ERROR_INVALID_CONN_HANDLE &&
                    err_code != NRF_ERROR_INVALID_STATE)
                {
                    APP_ERROR_CHECK(err_code);
                }
                break;
    
            default:
                APP_ERROR_HANDLER(pin_no);
                break;
        }
    }

     

    You can clearly see here that we are trying to send a notification here without checking if the device is connected or not. In your case, when you press the button before the device is connected, then the ble_lbs_on_button_change would return error and you will hit the APP_ERROR_CHECK which by default will reset your device.

    The best would be to change the function to below

    static void button_event_handler(uint8_t pin_no, uint8_t button_action)
    {
        uint32_t err_code;
    
        switch (pin_no)
        {
            case LEDBUTTON_BUTTON_PIN:
                NRF_LOG_INFO("Send button state change.\r\n");
            if(m_conn_handle != BLE_CONN_HANDLE_INVALID)        
            {
                err_code = ble_lbs_on_button_change(&m_lbs, button_action);
                if (err_code != NRF_SUCCESS &&
                    err_code != BLE_ERROR_INVALID_CONN_HANDLE &&
                    err_code != NRF_ERROR_INVALID_STATE)
                {
                    APP_ERROR_CHECK(err_code);
                }
                break;
    
            default:
                APP_ERROR_HANDLER(pin_no);
                break;
            }
        }
    }

    now we will attempt to send notifications only if there is a connection.

  • I am very sorry to reject the answer that late. The suggested solution does not work - it is still the same behaviour as shown in the Video. I did test it with the timer metioned in the first answer active and thought i would work.

    However, in my application, i want to show that the device is in a Connection so that the customer can start interacting. So, when the LED lights up, i want to be sure that there is a Connection.

    Aryan's answer wants to check that, but as i said: the device resets if there is a button release immediately after Connection. The timer i used is not an elegant solution because just it delays enabling the app_button and the ligthing up the LED.

    Any suggestions are very much appreciated.  

    Reproducable with nRR5-DK, SDK 12.3 and Softdevice S130 2.0.1/ Softdevice S132 3.0.0 using the ble_app_blinky example.

    Kind regards

    DanKa

Related