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

can nrf_connect for andrio scan for long range ble advertise

I want to use long range ble for advertising with nrf52833. I have a PCA10100 SDK board, and I'm running a program with type of BLE_GAP_ADV_TYPE_EXTENDED_NONCONNECTABLE_SCANNABLE_UNDIRECTED. Then I use nrf_connect for andrio in a mobile phone to scan for it. I have seen the device information of the phone and found that it surported long range(PHY Coded). but I can't scan my PCA10100 SDK. What reason is it?

Parents
  • Hello,

        The first image is Device Information of nrf_connect,It show long range is surported. The second and third image is the energy profiler of nrf52833 when it is advertising. 

  • I believe that there is a bug in nRF Connect for Android that causes it to say that all Bluetooth 5 features (Long range included) is supported as long as the phone supports Bluetooth 5. Since all Bluetooth 5 features, such as long range and high speed (2M) are optional, it is not given that all of them are supported.

    Can you share the snippets used to start advertising? And also please confirm that your call to sd_ble_gap_adv_start() (probably through ble_advertising_start() or advertising_start()) returns NRF_SUCCESS.

    Have you tried scanning for it using another nRF?

    Best regards,

    Edvin

  • static void advertising_init(void)
    {
    /* ret_code_t err_code;
    ble_advdata_t advdata;
    ble_advdata_t srdata;

    ble_uuid_t adv_uuids[] = {{LBS_UUID_SERVICE, m_lbs.uuid_type}};

    // Build and set advertising data.
    memset(&advdata, 0, sizeof(advdata));

    advdata.name_type = BLE_ADVDATA_FULL_NAME;
    advdata.include_appearance = true;
    advdata.flags = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;


    memset(&srdata, 0, sizeof(srdata));
    srdata.uuids_complete.uuid_cnt = sizeof(adv_uuids) / sizeof(adv_uuids[0]);
    srdata.uuids_complete.p_uuids = adv_uuids;

    err_code = ble_advdata_encode(&advdata, m_adv_data.adv_data.p_data, &m_adv_data.adv_data.len);
    APP_ERROR_CHECK(err_code);

    err_code = ble_advdata_encode(&srdata, m_adv_data.scan_rsp_data.p_data, &m_adv_data.scan_rsp_data.len);
    APP_ERROR_CHECK(err_code);

    ble_gap_adv_params_t adv_params;

    // Set advertising parameters.
    memset(&adv_params, 0, sizeof(adv_params));

    adv_params.primary_phy = BLE_GAP_PHY_CODED;//BLE_GAP_PHY_1MBPS;
    adv_params.duration = APP_ADV_DURATION;
    adv_params.properties.type = BLE_GAP_ADV_TYPE_EXTENDED_CONNECTABLE_NONSCANNABLE_UNDIRECTED;//BLE_GAP_ADV_TYPE_CONNECTABLE_SCANNABLE_UNDIRECTED;
    adv_params.p_peer_addr = NULL;
    adv_params.filter_policy = BLE_GAP_ADV_FP_ANY;
    adv_params.interval = APP_ADV_INTERVAL;

    err_code = sd_ble_gap_adv_set_configure(&m_adv_handle, &m_adv_data, &adv_params);
    APP_ERROR_CHECK(err_code);*/
    ret_code_t err_code;
    ble_advdata_t advdata;
    ble_advdata_t srdata;
    int8_t my_tx_power=8;

    ble_uuid_t adv_uuids[] = {{LBS_UUID_SERVICE, m_lbs.uuid_type}};

    // Build and set advertising data.
    memset(&advdata, 0, sizeof(advdata));

    advdata.name_type = BLE_ADVDATA_FULL_NAME;
    advdata.include_appearance = true;
    advdata.flags = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;
    advdata. p_tx_power_level = &my_tx_power;


    memset(&srdata, 0, sizeof(srdata));
    srdata.uuids_complete.uuid_cnt = sizeof(adv_uuids) / sizeof(adv_uuids[0]);
    srdata.uuids_complete.p_uuids = adv_uuids;

    //err_code = ble_advdata_encode(&srdata, m_adv_data.scan_rsp_data.p_data, &m_adv_data.scan_rsp_data.len);
    //APP_ERROR_CHECK(err_code);

    //ble_gap_adv_params_t adv_params;

    // Set advertising parameters.
    ble_gap_adv_params_t adv_params;
    /* memset(&adv_params, 0, sizeof(adv_params));


    adv_params.primary_phy = BLE_GAP_PHY_CODED;//BLE_GAP_PHY_1MBPS
    adv_params.secondary_phy = BLE_GAP_PHY_CODED;

    adv_params.properties.type = BLE_GAP_ADV_TYPE_EXTENDED_CONNECTABLE_NONSCANNABLE_UNDIRECTED;//BLE_GAP_ADV_TYPE_EXTENDED_NONCONNECTABLE_SCANNABLE_UNDIRECTED;//BLE_GAP_ADV_TYPE_EXTENDED_CONNECTABLE_NONSCANNABLE_UNDIRECTED;//;
    adv_params.p_peer_addr = NULL;
    adv_params.filter_policy = BLE_GAP_ADV_FP_ANY;
    adv_params.interval = 800;
    adv_params.duration = 0; // Never time out.

    err_code = sd_ble_gap_adv_set_configure(&m_adv_handle, &m_adv_data, &adv_params);
    APP_ERROR_CHECK(err_code); */
    memset(&adv_params, 0, sizeof(adv_params));

    //adv_params.primary_phy = BLE_GAP_PHY_1MBPS;//BLE_GAP_PHY_CODED;//BLE_GAP_PHY_1MBPS;
    //adv_params.secondary_phy = BLE_GAP_PHY_CODED,

    //.p_peer_addr = NULL,
    //.filter_policy = BLE_GAP_ADV_FP_ANY,
    //.interval = ADV_INTERVAL,
    //.duration = 0,

    adv_params.primary_phy = BLE_GAP_PHY_CODED;//BLE_GAP_PHY_1MBPS;//BLE_GAP_PHY_CODED;
    //adv_params.secondary_phy = BLE_GAP_PHY_CODED;//BLE_GAP_PHY_1MBPS;//BLE_GAP_PHY_CODED;

    adv_params.duration = APP_ADV_DURATION;//APP_ADV_DURATION;//0

    //adv_params.properties.type = BLE_GAP_ADV_TYPE_CONNECTABLE_SCANNABLE_UNDIRECTED;//BLE_GAP_ADV_TYPE_EXTENDED_CONNECTABLE_NONSCANNABLE_UNDIRECTED;//BLE_GAP_ADV_TYPE_CONNECTABLE_SCANNABLE_UNDIRECTED;
    adv_params.properties.type = BLE_GAP_ADV_TYPE_EXTENDED_CONNECTABLE_NONSCANNABLE_UNDIRECTED;//BLE_GAP_ADV_TYPE_EXTENDED_CONNECTABLE_NONSCANNABLE_UNDIRECTED;//BLE_GAP_ADV_TYPE_EXTENDED_NONCONNECTABLE_SCANNABLE_UNDIRECTED;

    adv_params.p_peer_addr = NULL;
    adv_params.filter_policy = BLE_GAP_ADV_FP_ANY;
    adv_params.interval = APP_ADV_INTERVAL;

    err_code = ble_advdata_encode(&advdata, m_adv_data.adv_data.p_data, &m_adv_data.adv_data.len);
    APP_ERROR_CHECK(err_code);
    //err_code = ble_advdata_encode(&srdata, m_adv_data.scan_rsp_data.p_data, &m_adv_data.scan_rsp_data.len);
    //APP_ERROR_CHECK(err_code);
    err_code = sd_ble_gap_adv_set_configure(&m_adv_handle, &m_adv_data, &adv_params);
    APP_ERROR_CHECK(err_code);
    }


    /**@brief Function for handling Queued Write Module errors.
    *
    * @details A pointer to this function will be passed to each service which may need to inform the
    * application about an error.
    *
    * @param[in] nrf_error Error code containing information about what went wrong.
    */
    static void nrf_qwr_error_handler(uint32_t nrf_error)
    {
    APP_ERROR_HANDLER(nrf_error);
    }


    /**@brief Function for handling write events to the LED characteristic.
    *
    * @param[in] p_lbs Instance of LED Button Service to which the write applies.
    * @param[in] led_state Written/desired state of the LED.
    */
    static void led_write_handler(uint16_t conn_handle, ble_lbs_t * p_lbs, uint8_t led_state)
    {
    if (led_state)
    {
    bsp_board_led_on(LEDBUTTON_LED);
    NRF_LOG_INFO("Received LED ON!");
    }
    else
    {
    bsp_board_led_off(LEDBUTTON_LED);
    NRF_LOG_INFO("Received LED OFF!");
    }
    }


    /**@brief Function for initializing services that will be used by the application.
    */
    static void services_init(void)
    {
    ret_code_t err_code;
    ble_lbs_init_t init = {0};
    nrf_ble_qwr_init_t qwr_init = {0};

    // Initialize Queued Write Module.
    qwr_init.error_handler = nrf_qwr_error_handler;

    err_code = nrf_ble_qwr_init(&m_qwr, &qwr_init);
    APP_ERROR_CHECK(err_code);

    // Initialize LBS.
    init.led_write_handler = led_write_handler;

    err_code = ble_lbs_init(&m_lbs, &init);
    APP_ERROR_CHECK(err_code);
    }


    /**@brief Function for handling the Connection Parameters Module.
    *
    * @details This function will be called for all events in the Connection Parameters Module that
    * are passed to the application.
    *
    * @note All this function does is to disconnect. This could have been done by simply
    * setting the disconnect_on_fail config parameter, but instead we use the event
    * handler mechanism to demonstrate its use.
    *
    * @param[in] p_evt Event received from the Connection Parameters Module.
    */
    static void on_conn_params_evt(ble_conn_params_evt_t * p_evt)
    {
    ret_code_t err_code;

    if (p_evt->evt_type == BLE_CONN_PARAMS_EVT_FAILED)
    {
    err_code = sd_ble_gap_disconnect(m_conn_handle, BLE_HCI_CONN_INTERVAL_UNACCEPTABLE);
    APP_ERROR_CHECK(err_code);
    }
    }


    /**@brief Function for handling a Connection Parameters error.
    *
    * @param[in] nrf_error Error code containing information about what went wrong.
    */
    static void conn_params_error_handler(uint32_t nrf_error)
    {
    APP_ERROR_HANDLER(nrf_error);
    }


    /**@brief Function for initializing the Connection Parameters module.
    */
    static void conn_params_init(void)
    {
    ret_code_t err_code;
    ble_conn_params_init_t cp_init;

    memset(&cp_init, 0, sizeof(cp_init));

    cp_init.p_conn_params = NULL;
    cp_init.first_conn_params_update_delay = FIRST_CONN_PARAMS_UPDATE_DELAY;
    cp_init.next_conn_params_update_delay = NEXT_CONN_PARAMS_UPDATE_DELAY;
    cp_init.max_conn_params_update_count = MAX_CONN_PARAMS_UPDATE_COUNT;
    cp_init.start_on_notify_cccd_handle = BLE_GATT_HANDLE_INVALID;
    cp_init.disconnect_on_fail = false;
    cp_init.evt_handler = on_conn_params_evt;
    cp_init.error_handler = conn_params_error_handler;

    err_code = ble_conn_params_init(&cp_init);
    APP_ERROR_CHECK(err_code);
    }


    /**@brief Function for starting advertising.
    */
    static void advertising_start(void)
    {
    ret_code_t err_code;

    err_code = sd_ble_gap_adv_start(m_adv_handle, APP_BLE_CONN_CFG_TAG);
    APP_ERROR_CHECK(err_code);

    bsp_board_led_on(ADVERTISING_LED);
    }

Reply
  • static void advertising_init(void)
    {
    /* ret_code_t err_code;
    ble_advdata_t advdata;
    ble_advdata_t srdata;

    ble_uuid_t adv_uuids[] = {{LBS_UUID_SERVICE, m_lbs.uuid_type}};

    // Build and set advertising data.
    memset(&advdata, 0, sizeof(advdata));

    advdata.name_type = BLE_ADVDATA_FULL_NAME;
    advdata.include_appearance = true;
    advdata.flags = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;


    memset(&srdata, 0, sizeof(srdata));
    srdata.uuids_complete.uuid_cnt = sizeof(adv_uuids) / sizeof(adv_uuids[0]);
    srdata.uuids_complete.p_uuids = adv_uuids;

    err_code = ble_advdata_encode(&advdata, m_adv_data.adv_data.p_data, &m_adv_data.adv_data.len);
    APP_ERROR_CHECK(err_code);

    err_code = ble_advdata_encode(&srdata, m_adv_data.scan_rsp_data.p_data, &m_adv_data.scan_rsp_data.len);
    APP_ERROR_CHECK(err_code);

    ble_gap_adv_params_t adv_params;

    // Set advertising parameters.
    memset(&adv_params, 0, sizeof(adv_params));

    adv_params.primary_phy = BLE_GAP_PHY_CODED;//BLE_GAP_PHY_1MBPS;
    adv_params.duration = APP_ADV_DURATION;
    adv_params.properties.type = BLE_GAP_ADV_TYPE_EXTENDED_CONNECTABLE_NONSCANNABLE_UNDIRECTED;//BLE_GAP_ADV_TYPE_CONNECTABLE_SCANNABLE_UNDIRECTED;
    adv_params.p_peer_addr = NULL;
    adv_params.filter_policy = BLE_GAP_ADV_FP_ANY;
    adv_params.interval = APP_ADV_INTERVAL;

    err_code = sd_ble_gap_adv_set_configure(&m_adv_handle, &m_adv_data, &adv_params);
    APP_ERROR_CHECK(err_code);*/
    ret_code_t err_code;
    ble_advdata_t advdata;
    ble_advdata_t srdata;
    int8_t my_tx_power=8;

    ble_uuid_t adv_uuids[] = {{LBS_UUID_SERVICE, m_lbs.uuid_type}};

    // Build and set advertising data.
    memset(&advdata, 0, sizeof(advdata));

    advdata.name_type = BLE_ADVDATA_FULL_NAME;
    advdata.include_appearance = true;
    advdata.flags = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;
    advdata. p_tx_power_level = &my_tx_power;


    memset(&srdata, 0, sizeof(srdata));
    srdata.uuids_complete.uuid_cnt = sizeof(adv_uuids) / sizeof(adv_uuids[0]);
    srdata.uuids_complete.p_uuids = adv_uuids;

    //err_code = ble_advdata_encode(&srdata, m_adv_data.scan_rsp_data.p_data, &m_adv_data.scan_rsp_data.len);
    //APP_ERROR_CHECK(err_code);

    //ble_gap_adv_params_t adv_params;

    // Set advertising parameters.
    ble_gap_adv_params_t adv_params;
    /* memset(&adv_params, 0, sizeof(adv_params));


    adv_params.primary_phy = BLE_GAP_PHY_CODED;//BLE_GAP_PHY_1MBPS
    adv_params.secondary_phy = BLE_GAP_PHY_CODED;

    adv_params.properties.type = BLE_GAP_ADV_TYPE_EXTENDED_CONNECTABLE_NONSCANNABLE_UNDIRECTED;//BLE_GAP_ADV_TYPE_EXTENDED_NONCONNECTABLE_SCANNABLE_UNDIRECTED;//BLE_GAP_ADV_TYPE_EXTENDED_CONNECTABLE_NONSCANNABLE_UNDIRECTED;//;
    adv_params.p_peer_addr = NULL;
    adv_params.filter_policy = BLE_GAP_ADV_FP_ANY;
    adv_params.interval = 800;
    adv_params.duration = 0; // Never time out.

    err_code = sd_ble_gap_adv_set_configure(&m_adv_handle, &m_adv_data, &adv_params);
    APP_ERROR_CHECK(err_code); */
    memset(&adv_params, 0, sizeof(adv_params));

    //adv_params.primary_phy = BLE_GAP_PHY_1MBPS;//BLE_GAP_PHY_CODED;//BLE_GAP_PHY_1MBPS;
    //adv_params.secondary_phy = BLE_GAP_PHY_CODED,

    //.p_peer_addr = NULL,
    //.filter_policy = BLE_GAP_ADV_FP_ANY,
    //.interval = ADV_INTERVAL,
    //.duration = 0,

    adv_params.primary_phy = BLE_GAP_PHY_CODED;//BLE_GAP_PHY_1MBPS;//BLE_GAP_PHY_CODED;
    //adv_params.secondary_phy = BLE_GAP_PHY_CODED;//BLE_GAP_PHY_1MBPS;//BLE_GAP_PHY_CODED;

    adv_params.duration = APP_ADV_DURATION;//APP_ADV_DURATION;//0

    //adv_params.properties.type = BLE_GAP_ADV_TYPE_CONNECTABLE_SCANNABLE_UNDIRECTED;//BLE_GAP_ADV_TYPE_EXTENDED_CONNECTABLE_NONSCANNABLE_UNDIRECTED;//BLE_GAP_ADV_TYPE_CONNECTABLE_SCANNABLE_UNDIRECTED;
    adv_params.properties.type = BLE_GAP_ADV_TYPE_EXTENDED_CONNECTABLE_NONSCANNABLE_UNDIRECTED;//BLE_GAP_ADV_TYPE_EXTENDED_CONNECTABLE_NONSCANNABLE_UNDIRECTED;//BLE_GAP_ADV_TYPE_EXTENDED_NONCONNECTABLE_SCANNABLE_UNDIRECTED;

    adv_params.p_peer_addr = NULL;
    adv_params.filter_policy = BLE_GAP_ADV_FP_ANY;
    adv_params.interval = APP_ADV_INTERVAL;

    err_code = ble_advdata_encode(&advdata, m_adv_data.adv_data.p_data, &m_adv_data.adv_data.len);
    APP_ERROR_CHECK(err_code);
    //err_code = ble_advdata_encode(&srdata, m_adv_data.scan_rsp_data.p_data, &m_adv_data.scan_rsp_data.len);
    //APP_ERROR_CHECK(err_code);
    err_code = sd_ble_gap_adv_set_configure(&m_adv_handle, &m_adv_data, &adv_params);
    APP_ERROR_CHECK(err_code);
    }


    /**@brief Function for handling Queued Write Module errors.
    *
    * @details A pointer to this function will be passed to each service which may need to inform the
    * application about an error.
    *
    * @param[in] nrf_error Error code containing information about what went wrong.
    */
    static void nrf_qwr_error_handler(uint32_t nrf_error)
    {
    APP_ERROR_HANDLER(nrf_error);
    }


    /**@brief Function for handling write events to the LED characteristic.
    *
    * @param[in] p_lbs Instance of LED Button Service to which the write applies.
    * @param[in] led_state Written/desired state of the LED.
    */
    static void led_write_handler(uint16_t conn_handle, ble_lbs_t * p_lbs, uint8_t led_state)
    {
    if (led_state)
    {
    bsp_board_led_on(LEDBUTTON_LED);
    NRF_LOG_INFO("Received LED ON!");
    }
    else
    {
    bsp_board_led_off(LEDBUTTON_LED);
    NRF_LOG_INFO("Received LED OFF!");
    }
    }


    /**@brief Function for initializing services that will be used by the application.
    */
    static void services_init(void)
    {
    ret_code_t err_code;
    ble_lbs_init_t init = {0};
    nrf_ble_qwr_init_t qwr_init = {0};

    // Initialize Queued Write Module.
    qwr_init.error_handler = nrf_qwr_error_handler;

    err_code = nrf_ble_qwr_init(&m_qwr, &qwr_init);
    APP_ERROR_CHECK(err_code);

    // Initialize LBS.
    init.led_write_handler = led_write_handler;

    err_code = ble_lbs_init(&m_lbs, &init);
    APP_ERROR_CHECK(err_code);
    }


    /**@brief Function for handling the Connection Parameters Module.
    *
    * @details This function will be called for all events in the Connection Parameters Module that
    * are passed to the application.
    *
    * @note All this function does is to disconnect. This could have been done by simply
    * setting the disconnect_on_fail config parameter, but instead we use the event
    * handler mechanism to demonstrate its use.
    *
    * @param[in] p_evt Event received from the Connection Parameters Module.
    */
    static void on_conn_params_evt(ble_conn_params_evt_t * p_evt)
    {
    ret_code_t err_code;

    if (p_evt->evt_type == BLE_CONN_PARAMS_EVT_FAILED)
    {
    err_code = sd_ble_gap_disconnect(m_conn_handle, BLE_HCI_CONN_INTERVAL_UNACCEPTABLE);
    APP_ERROR_CHECK(err_code);
    }
    }


    /**@brief Function for handling a Connection Parameters error.
    *
    * @param[in] nrf_error Error code containing information about what went wrong.
    */
    static void conn_params_error_handler(uint32_t nrf_error)
    {
    APP_ERROR_HANDLER(nrf_error);
    }


    /**@brief Function for initializing the Connection Parameters module.
    */
    static void conn_params_init(void)
    {
    ret_code_t err_code;
    ble_conn_params_init_t cp_init;

    memset(&cp_init, 0, sizeof(cp_init));

    cp_init.p_conn_params = NULL;
    cp_init.first_conn_params_update_delay = FIRST_CONN_PARAMS_UPDATE_DELAY;
    cp_init.next_conn_params_update_delay = NEXT_CONN_PARAMS_UPDATE_DELAY;
    cp_init.max_conn_params_update_count = MAX_CONN_PARAMS_UPDATE_COUNT;
    cp_init.start_on_notify_cccd_handle = BLE_GATT_HANDLE_INVALID;
    cp_init.disconnect_on_fail = false;
    cp_init.evt_handler = on_conn_params_evt;
    cp_init.error_handler = conn_params_error_handler;

    err_code = ble_conn_params_init(&cp_init);
    APP_ERROR_CHECK(err_code);
    }


    /**@brief Function for starting advertising.
    */
    static void advertising_start(void)
    {
    ret_code_t err_code;

    err_code = sd_ble_gap_adv_start(m_adv_handle, APP_BLE_CONN_CFG_TAG);
    APP_ERROR_CHECK(err_code);

    bsp_board_led_on(ADVERTISING_LED);
    }

Children
  • Edvin said:

    And also please confirm that your call to sd_ble_gap_adv_start() (probably through ble_advertising_start() or advertising_start()) returns NRF_SUCCESS.

    Have you tried scanning for it using another nRF?

  • It return NRF_SUCESS. What do you mean to say "using another nRF", Is it using another phone? or using another program?  

  • you will need to write an application that scans on long range to be running on a separate nRF. I didn't understand the second screenshot from your mobile phone. There it says that none of the Bluetooth 5 features are available.

    I got some clarity in the "bug" in nRF Connect:

    The issue is that some phones support some long range features. In particular they support Long range when a connection is entered. That is, they scan on 1MBPS, then connect to a peripheral, and then you can switch to long range. Some of these phones does not support scanning on CODED_PHY (long range). But the way that nRF Connect for iOS checks this is just by reading a bit that says whether or not long range is supported. That bit doesn't say whether scanning in CODED_PHY is supported. 

    Please search devzone for scanning in long range. I have not done this myself, but there are a few posts discussing it. 

    If you are able to pick up long range advertisements using a custom application on an nRF acting as a scanner, but not on the cellphone, that would suggest that the phone doesn't support scanning on Long Range.

    Best regards,

    Edvin

Related