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

BLUETOOTH CONNECTION ISSUE

Hi,

  • we developed a  2D-3D mouse .It contains a 2D sensor and a 3D sensor  and 4 touchpads for left click,right click and 3D motion enabling.
  • The SDK we are using for developing our application is   "nRF5_SDK_16.0.0_98a08e2"  and examples "ble_app_hids_mouse" .
  • We are using timer interrupt(app_timer) for reading and updating 2D ,3D sensor data and also to updating battery level  to host pc and the gpio interrupt is using for updating the  mouse clicks to host pc.
  • In our code we are enabling  all these interrupt after the bluetooth connection was established between our mouse and host pc .ie On "BLE_GAP_EVT_CONNECTEDevent  in main.c file  under "ble_evt_handler" function .Please look the below screen shot for better under standings.

  • Then we try to connect to our device  to host pc the connection was not establishing  in pc and its shows  "Try connecting your device again " .please look the below screen shot.

  • We find out the reason for this issue after some research and also with the support of nordic . ie,There are several other BLE events that are waiting to happen right after establishing a connection (BLE_GAP_EVT_CONNECTED event), as Service discovery, MTU update, data length update, PHY update, etc. if we are running so many things directly from inside the handling of the BLE_GAP_EVT_CONNECTED event we risk delaying and blocking other pending BLE softdevice events, and as a consequence perhaps even drop the connection if things take too much time. 
  • So our solution to counter this issue was instead of enabling all the interrupt inside the BLE_GAP_EVT_CONNECTED event we just enabled a single shot timer with delay 1 sec here  and inside this timer handler we enabled all these interrupt.
  • After this change in code we continuously  tested  our device on several PC .The result was uneven in different PC.ie, In some PC connectivity issue is showing and in some PC Its not showing .
  • For detailed analysis we take the sniffer traces  of both PC which showing the connectivity issue and also the PC which not showing connectivity issue . Sniffer traces are attaching below.

PC_WITH_CONNECTION_ISSUE.pcapng

PC_WITHOUT_CONNECTION_ISSUE.pcapng

  • After the analysis of sniffer trace of both pc we comes to a conclusion. The PC with connection issue is taking more time to complete the  BLE softdevice events(Service discovery, MTU update, data length update, PHY update, etc).The PC without connection issue is taking less time to complete the  BLE softdevice events(Service discovery, MTU update, data length update, PHY update, etc).

  • Why this time difference is showing in different PC ?
  • when we increased the single shot timer interval to 5 sec connection issue was not showing in any PC but we can't allow this much delay to enable the all features in our device after the BLE connection was established.
  • Please help us to find a proper solution to counter this issue.  

NOTE :- Refer the sniffer trace from "Number"  4200 in  PC_WITH_CONNECTION_ISSUE. Refer the sniffer trace from "Number" 8656 in PC_WITHOUT_CONNECTION_ISSUE.

Parents
  • Hi Edvin,

    Edvin said:
    I have checked the sniffer trace. I can't see any obvious reasons for why the PC disconnects.

     I already told you that after we changed the timer interrupt delay to 5sec connection issue was not showing . Both the traces i posted to you have this change that is why you can't  see any issue but did you notice the time difference  to complete the  BLE softdevice events(Service discovery, MTU update, data length update, PHY update, etc) in both trace.

    If you want a sniffer trace with PC is disconnecting . Please refer the below trace (from number 2800).In this trace two times our device shows the connection problem.

    CONNECTION_PROBLEM.pcapng 

     

    Edvin said:
    You say that the issue goes away if you delay the peripheral initialization with 5 seconds instead of 1 second, is that correct?

     yes.

    Edvin said:
    what IRQ is your app_timer running?

     Inside the "ble_evt_handler" . Now peripherals_enable() is used to start the timer . Please refer the below code  for better clarification.

    /**@brief Function for enabling all peripherals.
     *
     * @details This function will be called after 1s in the device connected to the host pc.
     *
     * @param[in]   p_context   Pointer used for passing some arbitrary information (context) from the
     *                          app_start_timer() call to the timeout handler.
     * void peripherals_enable_timeout_handler(void * p_event_data, uint16_t event_size)  
     **/
     
     
    static void peripherals_enable_timeout_handler(void * p_context)  
    {
         
         ret_code_t err_code;
         
         nrf_gpio_pin_set(BSP_LED_2);       /* Green led will off */
         
         err_code = app_spi_enable();       /* Enabling  2D movement */
         APP_ERROR_CHECK(err_code); 
    
         motion_3d_module_enable();         /* Enabling  3D movement */ 
    
         saadc_timer_enable();              /* SAADC timer will enable so the saadc conversion will start */
         
         if (nrf_gpio_pin_read(PIN_BASE_SENSE) == false)   /* Docked Event*/
         {
               DOCKED   = true;
               touchpad_disable();  /* Disable touchpad   */
         }
         else                                              /* Un_docked Event */
         {  
               DOCKED   = false;
               touchpad_enable();  /* Enable touchpad     */
         }
    
    
    }
    
    
    
    
    /**@brief Function for the Timer initialization.
     *
     * @details Initializes the timer module.
     */
    static void peripherals_enable_timer_init(void)
    {
            ret_code_t err_code;
    
            // Create battery timer.
            err_code = app_timer_create(&peripherals_enable_timer_id,
                                        APP_TIMER_MODE_SINGLE_SHOT,
                                        peripherals_enable_timeout_handler);
            APP_ERROR_CHECK(err_code);
    }
    
    /** Function for enabling the peripherals_enable timer**/
    static void  peripherals_enable(void)
    {
        ret_code_t err_code;
        err_code = app_timer_start(peripherals_enable_timer_id, PERIPHERALS_ENABLE_DELAY_INTERVAL, NULL);
        APP_ERROR_CHECK(err_code);   
     
    }
    
    
    
    
    /** Function for disabling the peripherals_enable timer **/
    static void  peripherals_enable_stop(void)
    {
        uint32_t err_code;  
        err_code = app_timer_stop(peripherals_enable_timer_id);
        APP_ERROR_CHECK(err_code); 
     
    }

     

    Edvin said:
    What is APP_TIMER_CONFIG_IRQ_PRIORITY in your sdk_config.h?

     APP_TIMER_CONFIG_IRQ_PRIORITY = 6

    Edvin said:
    Just for testing, can you try something like this:

      We did the test but same issue was showing . The connection was not establishing with PC.

    Edvin said:
    So does any of the peripherals you initialize use the priority below 5?

     No. The peripherals are only using gpio and timer interrupts and both of its priority level is 6. 

Reply
  • Hi Edvin,

    Edvin said:
    I have checked the sniffer trace. I can't see any obvious reasons for why the PC disconnects.

     I already told you that after we changed the timer interrupt delay to 5sec connection issue was not showing . Both the traces i posted to you have this change that is why you can't  see any issue but did you notice the time difference  to complete the  BLE softdevice events(Service discovery, MTU update, data length update, PHY update, etc) in both trace.

    If you want a sniffer trace with PC is disconnecting . Please refer the below trace (from number 2800).In this trace two times our device shows the connection problem.

    CONNECTION_PROBLEM.pcapng 

     

    Edvin said:
    You say that the issue goes away if you delay the peripheral initialization with 5 seconds instead of 1 second, is that correct?

     yes.

    Edvin said:
    what IRQ is your app_timer running?

     Inside the "ble_evt_handler" . Now peripherals_enable() is used to start the timer . Please refer the below code  for better clarification.

    /**@brief Function for enabling all peripherals.
     *
     * @details This function will be called after 1s in the device connected to the host pc.
     *
     * @param[in]   p_context   Pointer used for passing some arbitrary information (context) from the
     *                          app_start_timer() call to the timeout handler.
     * void peripherals_enable_timeout_handler(void * p_event_data, uint16_t event_size)  
     **/
     
     
    static void peripherals_enable_timeout_handler(void * p_context)  
    {
         
         ret_code_t err_code;
         
         nrf_gpio_pin_set(BSP_LED_2);       /* Green led will off */
         
         err_code = app_spi_enable();       /* Enabling  2D movement */
         APP_ERROR_CHECK(err_code); 
    
         motion_3d_module_enable();         /* Enabling  3D movement */ 
    
         saadc_timer_enable();              /* SAADC timer will enable so the saadc conversion will start */
         
         if (nrf_gpio_pin_read(PIN_BASE_SENSE) == false)   /* Docked Event*/
         {
               DOCKED   = true;
               touchpad_disable();  /* Disable touchpad   */
         }
         else                                              /* Un_docked Event */
         {  
               DOCKED   = false;
               touchpad_enable();  /* Enable touchpad     */
         }
    
    
    }
    
    
    
    
    /**@brief Function for the Timer initialization.
     *
     * @details Initializes the timer module.
     */
    static void peripherals_enable_timer_init(void)
    {
            ret_code_t err_code;
    
            // Create battery timer.
            err_code = app_timer_create(&peripherals_enable_timer_id,
                                        APP_TIMER_MODE_SINGLE_SHOT,
                                        peripherals_enable_timeout_handler);
            APP_ERROR_CHECK(err_code);
    }
    
    /** Function for enabling the peripherals_enable timer**/
    static void  peripherals_enable(void)
    {
        ret_code_t err_code;
        err_code = app_timer_start(peripherals_enable_timer_id, PERIPHERALS_ENABLE_DELAY_INTERVAL, NULL);
        APP_ERROR_CHECK(err_code);   
     
    }
    
    
    
    
    /** Function for disabling the peripherals_enable timer **/
    static void  peripherals_enable_stop(void)
    {
        uint32_t err_code;  
        err_code = app_timer_stop(peripherals_enable_timer_id);
        APP_ERROR_CHECK(err_code); 
     
    }

     

    Edvin said:
    What is APP_TIMER_CONFIG_IRQ_PRIORITY in your sdk_config.h?

     APP_TIMER_CONFIG_IRQ_PRIORITY = 6

    Edvin said:
    Just for testing, can you try something like this:

      We did the test but same issue was showing . The connection was not establishing with PC.

    Edvin said:
    So does any of the peripherals you initialize use the priority below 5?

     No. The peripherals are only using gpio and timer interrupts and both of its priority level is 6. 

Children
No Data
Related