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 ----------------------------------

  • Hi,

    Attached .zip includes the ble_app_uart and ble_app_uart_c example modified to establish the connection in long range mode. Also replaced s140 v.6.1.0 with s140 6.1.1 as it includes some improvements that may reduce packet loss for "coded phy" connections (https://www.nordicsemi.com/eng/nordic/Products/nRF52840-DK/S140-SD-v6/60625). 

    nRF5_SDK_15.2.0_mod.zip

    Regards,

    Vidar

  • Thanks a lot Vidar!

    I'll look at it as soon as possible and report back here !

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

  • Above, I forgot to say that I am using "SEC_JUST_WORKS" in my Service.

    idle_state_handle() also contains the call:

    ret_code_t err_code = nrf_ble_lesc_request_handler();

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

Related