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

    This sounds like it might be a misunderstanding. When you connect to one central with the peripheral, that peripheral will naturally stop advertising. So if it is the only advertising device your other central is scanning for it might seem like it stops scanning, or have you debugged and specifically see that the radio or scan function stops once the peripheral is connected to the other central?

    To make sure it isn't the case that you're only seeing the one peripheral stops advertising you can have two devices advertising that the central will detect. Either another DK running the BLE NUS peripheral sample, or a phone with the nRF Connect app advertising with the Nordic UART Service.

    Best regards,

    Simon

  • hi,  

    This sounds like it might be a misunderstanding. When you connect to one central with the peripheral, that peripheral will naturally stop advertising. So if it is the only advertising device your other central is scanning for it might seem like it stops scanning, or have you debugged and specifically see that the radio or scan function stops once the peripheral is connected to the other central?

    I am connecting two peripheral devices to the PC and checking the debugging messages.

    And when you turn on pheipheal, the above phenomenon occurs.

    As you can see in the captured image below, Central in the left terminal program and Central in the right terminal program

    are running simultaneously.

    static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context) -> BLE_GAP_EVT_ADV_REPORT

    When the two centrals are scanning as shown in the captured image above, when the peripheral is turned on, it looks like the image below.

    ( Name filter )

    The left central stopped scanning and the right central connected normally.

    What makes me think that the left central has stopped scanning is that debugging messages for scans no longer appear.

    Additionally, even if the peripheral device is turned on, it does not connect.

    Isn't it possible that the scan stops during the connection process and there is no time-out function for failure?

  • 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

  • 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.
  • Hi

    I'm struggling a bit to understand you here. Does the basic NUS sample also result in the same behavior that if two centrals with the NUS sample tries to connect to the same peripheral, one will connect while the other will just be stuck trying to connect forever and not restart scanning? And how long are you waiting without seeing any response from the central device that didn't connect?

    What are the conn_params; set to in your application? There should be a connection timeout I think that eventually times out if the peripheral doesn't respond, and then the scanner will restart when it gets out of the connection function.

    Best regards,

    Simon

Related