A phenomenon in which NUS's Central stops midway while performing a BLE scan.

hello.

I have two NUS Centrals running at the same time. BLE Scan continues to run during standby.

static void scan_start(void)
{
    ret_code_t ret;

    printf("> Scanstart ");
    ret = nrf_ble_scan_start(&m_scan);
    APP_ERROR_CHECK(ret);

    Bsp_led_indication_Scanning_clr();
    ret = bsp_indication_set(BSP_INDICATE_SCANNING); // connection LED
    APP_ERROR_CHECK(ret);

}
The problem is that when the peripheral PCB is turned on while the two Centrals are performing BLE Scan,
One connection is made to the Central, and the other one stops while scanning.

There is no problem with other operations, only the BLE Scan stops.
Why is this like this?

Also, is there a way to check whether BLE SCAN is operating and restart it if BLE SCAN is stopped?
Parents
  • Hi

    From the bottom screenshot you provided it seems like both central tries to connect to the peripheral at the same time, as ble_scan_connect Connecting is printed on both sides. If so it makes sense that both devices stops scanning and tries to connect, however only one of them will be able to and then it depends how the central handles a connection procedure that doesn't end up connecting.

    In the default NUS example project in the nRF5 SDK, the scan_evt_handler handles scan events, where scanning is stopped when it gets a connection event, but it also has a timeout event that's triggered and restarts scanning if it times out, but you seem to be using a custom ble_scan_connect() function from what I can tell, so maybe it doesn't handle a timeout?

    Best regards,

    Simon

Reply
  • Hi

    From the bottom screenshot you provided it seems like both central tries to connect to the peripheral at the same time, as ble_scan_connect Connecting is printed on both sides. If so it makes sense that both devices stops scanning and tries to connect, however only one of them will be able to and then it depends how the central handles a connection procedure that doesn't end up connecting.

    In the default NUS example project in the nRF5 SDK, the scan_evt_handler handles scan events, where scanning is stopped when it gets a connection event, but it also has a timeout event that's triggered and restarts scanning if it times out, but you seem to be using a custom ble_scan_connect() function from what I can tell, so maybe it doesn't handle a timeout?

    Best regards,

    Simon

Children
  • hi, 

    I analyzed the part you provided.

    As you said, the function static void scan_evt_handler(scan_evt_t const * p_scan_evt) has TIMEOUT.

    However, as you can see from the debugging message above, TIMEOUT was not executed.

    So, I looked at the basic NUS example again and there is no difference.

             case NRF_BLE_SCAN_EVT_SCAN_TIMEOUT:
             {
                 printf("Scan timed out\n\r");
                 scan_start();
             } break;
    static void scan_evt_handler(scan_evt_t const * p_scan_evt)
    {
        int8_t rssi;
        ret_code_t err_code;
        //ble_gap_evt_adv_report_t const *p_adv_report      = &p_scan_evt->params.p_whitelist_adv_report;
    
        switch(p_scan_evt->scan_evt_id)
        {
             case NRF_BLE_SCAN_EVT_CONNECTING_ERROR:
             {
                  err_code = p_scan_evt->params.connecting_err.err_code;
                  APP_ERROR_CHECK(err_code);
                  printf("case NRF_BLE_SCAN_EVT_CONNECTING_ERROR\n\r");
    
             } break;
    
             case NRF_BLE_SCAN_EVT_CONNECTED:
             {
                 rssi = p_scan_evt->params.p_whitelist_adv_report->rssi;
    
                ble_gap_evt_connected_t const * p_connected =
                                   p_scan_evt->params.connected.p_connected;
                 // Scan is automatically stopped by the connection.
                 
               
                printf("\n\r> Connecting %02x %02x %02x %02x %02x %02x  %ddBm\n\r",
                    p_connected->peer_addr.addr[0],
                    p_connected->peer_addr.addr[1],
                    p_connected->peer_addr.addr[2],
                    p_connected->peer_addr.addr[3],
                    p_connected->peer_addr.addr[4],
                    p_connected->peer_addr.addr[5],
                     rssi
                );
               
                 
               
                 /*
                 NRF_LOG_INFO("Connecting to target %02x%02x%02x%02x%02x%02x",
                          p_connected->peer_addr.addr[0],
                          p_connected->peer_addr.addr[1],
                          p_connected->peer_addr.addr[2],
                          p_connected->peer_addr.addr[3],
                          p_connected->peer_addr.addr[4],
                          p_connected->peer_addr.addr[5]
                          );
               
                */
     
    
             } break;
    
             case NRF_BLE_SCAN_EVT_SCAN_TIMEOUT:
             {
                 printf("Scan timed out\n\r");
                 scan_start();
             } break;
    
             default:
                 break;
        }
    }
    And I looked at the nrf_ble_scan_connect_with_target() function where the actual connection is made.
    nrf_ble_scan_stop(), which again stops scanning; There is a function.

    Likewise, there seems to be no problematic differences from the basic NUS source.
    static void nrf_ble_scan_connect_with_target(nrf_ble_scan_t           const * const p_scan_ctx,
                                                 ble_gap_evt_adv_report_t const * const p_adv_report)
    {
        ret_code_t err_code;
        scan_evt_t scan_evt;
    
         int8_t rssi;
    
        // For readability.
        ble_gap_addr_t const        * p_addr        = &p_adv_report->peer_addr;
        ble_gap_scan_params_t const * p_scan_params = &p_scan_ctx->scan_params;
        ble_gap_conn_params_t const * p_conn_params = &p_scan_ctx->conn_params;
        uint8_t                       con_cfg_tag   = p_scan_ctx->conn_cfg_tag;
    
    
        rssi = p_adv_report->rssi;
        printf("> ble_scan RSSI Filter: %ddBm", rssi);
        if( rssi < gRSSI_Filter_mode )
        {
            printf(" ble_scan_connect_with_target - RSSI Filter fail\n\r");
            return;
        }
       
    
        // Return if the automatic connection is disabled.
        if (!p_scan_ctx->connect_if_match)
        {
            return;
        }
    
        // Stop scanning.
        nrf_ble_scan_stop();
    
        memset(&scan_evt, 0, sizeof(scan_evt));
    
        // Establish connection.
        err_code = sd_ble_gap_connect(p_addr,
                                      p_scan_params,
                                      p_conn_params,
                                      con_cfg_tag);
    
        printf("> ble_scan_connect Connecting\n\r");
    
        scan_evt.scan_evt_id                    = NRF_BLE_SCAN_EVT_CONNECTING_ERROR;
        scan_evt.params.connecting_err.err_code = err_code;
    
        printf("> ble_scan Connection status: %d\n\r", err_code);
    
        // If an error occurred, send an event to the event handler.
        if ((err_code != NRF_SUCCESS) && (p_scan_ctx->evt_handler != NULL))
        {
            p_scan_ctx->evt_handler(&scan_evt);
        }
    
    }
    The conclusive problem is that case NRF_BLE_SCAN_EVT_SCAN_TIMEOUT: does not occur.
    Why is that so? I can't find the difference.
Related