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

Unable to convert to Long Range after looking at umpteen examples :-(

Using SDK 15.2, PCA10056 Dev Kit. Segger Embedded Studio. s140_nrf52_6.1.0_softdevice.hex


Our Code (non Long Range) works perfectly! We are using it in a test for a customer. The code is based on the UART example.
However, we want more range, and want to test Long Range.

Note: I am NOT experienced in this field, but managed to get the existing code working after 8 weeks of work.
We do not have this amount of time to spend now...


For weeks I have looked at at least 5 different examples, but nothing I have tried works with my code.
Part of the problem is that there seems to be many approaches to configuring for long range, and most examples are not complete.

The last example I tried to follow, is this one:
Ref 1: devzone.nordicsemi.com/.../sdk15-long-advertising-and-long-range-connect

It is supposed to show the difference between the standard UART example and the conversion to Long Range.
If I follow that example, the Peripheral returns Error = 7 (Invalid Parameter) in call to:

- ble_advertising_start(&m_advertising, BLE_ADV_MODE_FAST);
- sd_ble_gap_adv_set_configure()


What confuses, is that many examples e.g. sets
adv_params.properties.type = BLE_GAP_ADV_TYPE_EXTENDED_CONNECTABLE_NONSCANNABLE_UNDIRECTED;

but there is no sign of such code in Ref 1 above...


Please, please help converting this example to use Long Range!
Please do not just refer to general descriptions, as I have tried to follow them for weeks with no success....


Code for Advertising and Scanning from Peripheral and Central follow below:


----------------- ble_app_uart START ----------------------------------


#define APP_ADV_INTERVAL 300
#define APP_ADV_DURATION 0


BLE_ADVERTISING_DEF(m_advertising);

.....


static void on_adv_evt(ble_adv_evt_t ble_adv_evt)
{
uint32_t err_code;

switch (ble_adv_evt)
{
case BLE_ADV_EVT_FAST:
break;
case BLE_ADV_EVT_IDLE:
break;
default:
break;
}
}

....


static void advertising_init(void)
{
uint32_t err_code;
ble_advertising_init_t init;

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

init.advdata.name_type = BLE_ADVDATA_FULL_NAME;
//init.advdata.include_appearance = false;
init.advdata.include_appearance = true; // Changed to True from ble_app_hrs example

// ONLY General Discovery Mode
init.advdata.flags = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;

init.srdata.uuids_complete.uuid_cnt = sizeof(m_adv_uuids) / sizeof(m_adv_uuids[0]);
init.srdata.uuids_complete.p_uuids = m_adv_uuids;

init.config.ble_adv_fast_enabled = true;

init.config.ble_adv_fast_interval = APP_ADV_INTERVAL;

init.config.ble_adv_fast_timeout = APP_ADV_DURATION;

init.evt_handler = on_adv_evt;

err_code = ble_advertising_init(&m_advertising, &init);
APP_ERROR_CHECK(err_code);

ble_advertising_conn_cfg_tag_set(&m_advertising, APP_BLE_CONN_CFG_TAG);
}

static void advertising_start() {

ret_code_t err_code;

err_code = ble_advertising_start(&m_advertising, BLE_ADV_MODE_FAST);
APP_ERROR_CHECK(err_code);

}


----------------- ble_app_uart END ----------------------------------

----------------- ble_app_uart_c START ----------------------------------

#define APP_BLE_CONN_CFG_TAG 1
#define SCAN_SCAN_DURATION_PAIR 3000


.....

static void scan_evt_handler(scan_evt_t cons t * p_scan_evt)
{
ret_code_t err_code;

//p_scan_evt->params.p_whitelist_adv_report->peer_addr

switch(p_scan_evt->scan_evt_id)
{

case NRF_BLE_SCAN_EVT_WHITELIST_REQUEST:
{
NRF_LOG_INFO("NRF_BLE_SCAN_EVT_WHITELIST_REQUEST");
NRF_LOG_FLUSH();

on_whitelist_req();
m_whitelist_disabled = false;
} break;


case NRF_BLE_SCAN_EVT_CONNECTING_ERROR:
{
err_code = p_scan_evt->params.connecting_err.err_code;

NRF_LOG_INFO("scan_evt_handler()>>NRF_BLE_SCAN_EVT_CONNECTING_ERROR: %d ", err_code);
NRF_LOG_FLUSH();

} break;


case NRF_BLE_SCAN_EVT_CONNECTED:
{
NRF_LOG_INFO("NRF_BLE_SCAN_EVT_CONNECTED");
NRF_LOG_FLUSH();

ble_gap_evt_connected_t const * p_connected =
p_scan_evt->params.connected.p_connected;
// Scan is automatically stopped by the connection.
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:
{
NRF_LOG_INFO("NRF_BLE_SCAN_EVT_SCAN_TIMEOUT");
NRF_LOG_FLUSH();
//scan_start(); /// GOS Should Not Scan here again !
} break;

case NRF_BLE_SCAN_EVT_FILTER_MATCH:
NRF_LOG_INFO("NRF_BLE_SCAN_EVT_FILTER_MATCH");
NRF_LOG_FLUSH();
break;

case NRF_BLE_SCAN_EVT_WHITELIST_ADV_REPORT:
NRF_LOG_INFO("NRF_BLE_SCAN_EVT_WHITELIST_ADV_REPORT");
NRF_LOG_FLUSH();
break;

case NRF_BLE_SCAN_EVT_NOT_FOUND:
break;

default:
break;
}
}
....


static void scan_init()
{
ret_code_t err_code;
nrf_ble_scan_init_t init_scan;

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

m_scan_param.timeout = SCAN_SCAN_DURATION_PAIR;

init_scan.p_scan_param = &m_scan_param;

init_scan.connect_if_match = true;
init_scan.conn_cfg_tag = APP_BLE_CONN_CFG_TAG;

err_code = nrf_ble_scan_init(&m_scan, &init_scan, scan_evt_handler);

APP_ERROR_CHECK(err_code);


err_code = nrf_ble_scan_filter_set(&m_scan, SCAN_UUID_FILTER, &m_nus_uuid);
APP_ERROR_CHECK(err_code);

err_code = nrf_ble_scan_filters_enable(&m_scan, NRF_BLE_SCAN_UUID_FILTER, false);
APP_ERROR_CHECK(err_code);


}


static void scan_start(void)
{

if (nrf_fstorage_is_busy(NULL)) // Added from ble_app_hrs_c
{
m_memory_access_in_progress = true;
return;
}


NRF_LOG_INFO("Start Scanning");
NRF_LOG_FLUSH();

ret_code_t ret;

ret = nrf_ble_scan_start(&m_scan);

APP_ERROR_CHECK(ret);

}

----------------- ble_app_uart_c END ----------------------------------

Parents Reply Children
  • Hello Vidar,

    Your Code compiles and runs with LR (Long Range) for me as well. However, with your LR advertising_init() function in my Peripheral, I still got Error 7 from ble_advertising_start().

    The problem turned out to be this code in the LR advertising_init():

    init.advdata.flags = BLE_GAP_ADV_FLAGS_LE_ONLY_LIMITED_DISC_MODE;

    I changed it to the flag that I used in my original (non LR) advertising_init():

    init.advdata.flags = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;

    and voila, the Error 7 went away: AND the LONG RANGE CODE CONNECTS & WORKS!

    Range does indeed seems to be approx 3 times what I had before, even though the Path Loss today probably is high due to very high humidity (drizzle).

    Goes to show how critical some of this code may be, and thus hard to understand & get working at least for a Novice like me...

    THANKS A LOT FOR YOUR HELP!

    ------

    By the way: How do I post Tips to other users?

    I have found easier ways to measure current on the nRF52840 Dev Kit without soldering on the Board.

    I have also found an easier way to Power & Program the nRF52840 Dongle with only one permanent modification.

    (Repeated Soldering on the boards are bound to destroy them as paths will come loose. It is also very time consuming and slows down prototyping)

    I would like to post the tips on how to do this when time permits. But how / where?

  • Hello,

    Thanks for confirming that it worked. Limited discovery mode limits the maximum advertising duration to 180 seconds (BT spec. requirement) and the softdevice enforces this. So if you require a longer or no timeout at all for advertising you need to use the general discovery mode. 

    Appreciate that you want to share your findings with other users. Unfortunately, the blog post section on this forum is currently limited to nordic employees. You can always create a new forum thread. It should get good visibility for those who are searching for similar subjects.

  •   Hi,

          How to do  these library  nRF5_SDK_15.2.0_mod.zip  make compatible with nrf5_SDK_17.2.0. 

  • Hi,

    You can see modifications I made for these 2 example in the 'diff' file below. It should not be much different in SDK 17.0.2

    diff --git a/examples/ble_central/ble_app_uart_c/main.c b/examples/ble_central/ble_app_uart_c/main.c
    index 5c6ffd5..c53297b 100644
    --- a/examples/ble_central/ble_app_uart_c/main.c
    +++ b/examples/ble_central/ble_app_uart_c/main.c
    @@ -116,6 +116,10 @@ static void scan_start(void)
     
         ret = bsp_indication_set(BSP_INDICATE_SCANNING);
         APP_ERROR_CHECK(ret);
    +
    +    //Optional: Change output power
    +    ret = sd_ble_gap_tx_power_set(BLE_GAP_TX_POWER_ROLE_SCAN_INIT, 0, 8);
    +    APP_ERROR_CHECK(ret);
     }
     
     
    @@ -164,13 +168,25 @@ static void scan_evt_handler(scan_evt_t const * p_scan_evt)
      */
     static void scan_init(void)
     {
    -    ret_code_t          err_code;
    -    nrf_ble_scan_init_t init_scan;
    +    ret_code_t            err_code;
    +    nrf_ble_scan_init_t   init_scan;
    +    ble_gap_scan_params_t scan_params;
    +
    +    memset(&scan_params, 0, sizeof(ble_gap_scan_params_t));
    +
    +    scan_params.active        = 1;
    +    scan_params.interval      = NRF_BLE_SCAN_SCAN_INTERVAL;
    +    scan_params.window        = NRF_BLE_SCAN_SCAN_WINDOW;
    +    scan_params.timeout       = NRF_BLE_SCAN_SCAN_DURATION;
    +    scan_params.filter_policy = BLE_GAP_SCAN_FP_ACCEPT_ALL;
    +    scan_params.scan_phys     = BLE_GAP_PHY_CODED;
    +    scan_params.extended      = true;
     
         memset(&init_scan, 0, sizeof(init_scan));
     
         init_scan.connect_if_match = true;
         init_scan.conn_cfg_tag     = APP_BLE_CONN_CFG_TAG;
    +    init_scan.p_scan_param     = &scan_params;
     
         err_code = nrf_ble_scan_init(&m_scan, &init_scan, scan_evt_handler);
         APP_ERROR_CHECK(err_code);
    diff --git a/examples/ble_central/ble_app_uart_c/pca10056/s140/config/sdk_config.h b/examples/ble_central/ble_app_uart_c/pca10056/s140/config/sdk_config.h
    index bb9c621..8ff8018 100644
    --- a/examples/ble_central/ble_app_uart_c/pca10056/s140/config/sdk_config.h
    +++ b/examples/ble_central/ble_app_uart_c/pca10056/s140/config/sdk_config.h
    @@ -127,7 +127,7 @@
     #endif
     // <o> NRF_BLE_SCAN_BUFFER - Data length for an advertising set. 
     #ifndef NRF_BLE_SCAN_BUFFER
    -#define NRF_BLE_SCAN_BUFFER 31
    +#define NRF_BLE_SCAN_BUFFER 255
     #endif
     
     // <o> NRF_BLE_SCAN_NAME_MAX_LEN - Maximum size for the name to search in the advertisement report. 
    @@ -184,7 +184,7 @@
     // <255=> BLE_GAP_PHY_NOT_SET 
     
     #ifndef NRF_BLE_SCAN_SCAN_PHY
    -#define NRF_BLE_SCAN_SCAN_PHY 1
    +#define NRF_BLE_SCAN_SCAN_PHY 4
     #endif
     
     // <e> NRF_BLE_SCAN_FILTER_ENABLE - Enabling filters for the Scanning Module.
    @@ -12394,7 +12394,7 @@
     // <i> Requested BLE GAP data length to be negotiated.
     
     #ifndef NRF_SDH_BLE_GAP_DATA_LENGTH
    -#define NRF_SDH_BLE_GAP_DATA_LENGTH 251
    +#define NRF_SDH_BLE_GAP_DATA_LENGTH 27
     #endif
     
     // <o> NRF_SDH_BLE_PERIPHERAL_LINK_COUNT - Maximum number of peripheral links. 
    @@ -12423,7 +12423,7 @@
     
     // <o> NRF_SDH_BLE_GATT_MAX_MTU_SIZE - Static maximum MTU size. 
     #ifndef NRF_SDH_BLE_GATT_MAX_MTU_SIZE
    -#define NRF_SDH_BLE_GATT_MAX_MTU_SIZE 247
    +#define NRF_SDH_BLE_GATT_MAX_MTU_SIZE 23
     #endif
     
     // <o> NRF_SDH_BLE_GATTS_ATTR_TAB_SIZE - Attribute Table size in bytes. The size must be a multiple of 4. 
    diff --git a/examples/ble_peripheral/ble_app_uart/main.c b/examples/ble_peripheral/ble_app_uart/main.c
    index 4d40d21..a42a8c7 100644
    --- a/examples/ble_peripheral/ble_app_uart/main.c
    +++ b/examples/ble_peripheral/ble_app_uart/main.c
    @@ -616,12 +616,15 @@ static void advertising_init(void)
         init.advdata.include_appearance = false;
         init.advdata.flags              = BLE_GAP_ADV_FLAGS_LE_ONLY_LIMITED_DISC_MODE;
     
    -    init.srdata.uuids_complete.uuid_cnt = sizeof(m_adv_uuids) / sizeof(m_adv_uuids[0]);
    -    init.srdata.uuids_complete.p_uuids  = m_adv_uuids;
    -
    -    init.config.ble_adv_fast_enabled  = true;
    -    init.config.ble_adv_fast_interval = APP_ADV_INTERVAL;
    -    init.config.ble_adv_fast_timeout  = APP_ADV_DURATION;
    +    init.advdata.uuids_complete.uuid_cnt = sizeof(m_adv_uuids) / sizeof(m_adv_uuids[0]);
    +    init.advdata.uuids_complete.p_uuids  = m_adv_uuids;
    +
    +    init.config.ble_adv_fast_enabled      = true;
    +    init.config.ble_adv_fast_interval     = APP_ADV_INTERVAL;
    +    init.config.ble_adv_fast_timeout      = APP_ADV_DURATION;
    +    init.config.ble_adv_primary_phy       = BLE_GAP_PHY_CODED;
    +    init.config.ble_adv_secondary_phy     = BLE_GAP_PHY_CODED;
    +    init.config.ble_adv_extended_enabled  = true;
         init.evt_handler = on_adv_evt;
     
         err_code = ble_advertising_init(&m_advertising, &init);
    @@ -687,6 +690,10 @@ static void advertising_start(void)
     {
         uint32_t err_code = ble_advertising_start(&m_advertising, BLE_ADV_MODE_FAST);
         APP_ERROR_CHECK(err_code);
    +
    +    //Optional: Change output power
    +    err_code = sd_ble_gap_tx_power_set(BLE_GAP_TX_POWER_ROLE_ADV, m_advertising.adv_handle, 8);
    +    APP_ERROR_CHECK(err_code);
     }
     
     
    

Related