Multiple advertisement (beacon + connectable advertisement) on NRF52

Hello,

I am working on building a BLE peripheral using the nRF52 DK board. I want to create both connectable advertisement and unconnectable advertisement (beacon type) on it.

I have searched on this forum for a solution and only found the possibility of using the Time slot API and the multiactivity example.

However, I am facing difficulties in finding a proper and recent example of using the time slot API specifically for advertisement. The multiactivity example seems to have disappeared in the latest SDK, and I couldn't find it in SDK 17.1.0 S132. I have been using the code from this project   https://github.com/xueliu/nRF52/tree/master/nRF52_SDK_0.9.2_dbc28c9/examples/ble_peripheral/experimental_ble_app_multiactivity_beacon/hrs_advertiser  as a reference.

Currently, I can activate the beacon and the normal connectable advertisement separately, but I cannot activate them both at the same time. Also I can activate the beacon only  once: if start, stop it and then start it again the fw crashes. I have added advertiser_beacon.h and advertiser_beacon.c to my project, but only added the `app_beacon_start()` and `app_beacon_stop()` , beacon_adv_init() functions in my main.

static void on_ble_evt(ble_evt_t * p_ble_evt)
{
uint32_t err_code;

switch (p_ble_evt->header.evt_id)
{
case BLE_GAP_EVT_CONNECTED:
err_code = bsp_indication_set(BSP_INDICATE_CONNECTED);
APP_ERROR_CHECK(err_code);

m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
app_beacon_start();

break;

case BLE_GAP_EVT_DISCONNECTED:
err_code = bsp_indication_set(BSP_INDICATE_IDLE);
APP_ERROR_CHECK(err_code);

app_beacon_stop();
break;

default:
// No implementation needed.
break;
}
}


I believe that I need to add something like this in my main function to use the timeslot, but I am not sure if it is done automatically:


/**@brief Function for dispatching a BLE stack event to all modules with a BLE stack event handler.
 *
 * @details This function is called from the BLE Stack event interrupt handler after a BLE stack
 *          event has been received.
 *
 * @param[in]   p_ble_evt   Bluetooth stack event.
 */
static void ble_evt_dispatch(ble_evt_t * p_ble_evt)
{
    dm_ble_evt_handler(p_ble_evt);
    ble_hrs_on_ble_evt(&m_hrs, p_ble_evt);
    ble_bas_on_ble_evt(&m_bas, p_ble_evt);
    ble_conn_params_on_ble_evt(p_ble_evt);
    bsp_btn_ble_on_ble_evt(p_ble_evt);
    on_ble_evt(p_ble_evt);
    ble_advertising_on_ble_evt(p_ble_evt);
}


/**@brief Function for dispatching a system event to interested modules.
 *
 * @details This function is called from the System event interrupt handler after a system
 *          event has been received.
 *
 * @param[in]   sys_evt   System stack event.
 */
static void sys_evt_dispatch(uint32_t sys_evt)
{
    pstorage_sys_event_handler(sys_evt);
    app_beacon_sd_evt_signal_handler(sys_evt);
    ble_advertising_on_sys_evt(sys_evt);
}


/**@brief Function for initializing the BLE stack.
 *
 * @details Initializes the SoftDevice and the BLE event interrupt.
 */
static void ble_stack_init(void)
{
    uint32_t err_code;

    // Initialize the SoftDevice handler module.
    SOFTDEVICE_HANDLER_INIT(NRF_CLOCK_LFCLKSRC_XTAL_20_PPM, NULL);

    // Enable BLE stack 
    ble_enable_params_t ble_enable_params;
    memset(&ble_enable_params, 0, sizeof(ble_enable_params));
#if (defined(S130) || defined(S132))
    ble_enable_params.gatts_enable_params.attr_tab_size   = BLE_GATTS_ATTR_TAB_SIZE_DEFAULT;
#endif
    ble_enable_params.gatts_enable_params.service_changed = IS_SRVC_CHANGED_CHARACT_PRESENT;
    err_code = sd_ble_enable(&ble_enable_params);
    APP_ERROR_CHECK(err_code);

    // Register with the SoftDevice handler module for BLE events.
    err_code = softdevice_ble_evt_handler_set(ble_evt_dispatch);
    APP_ERROR_CHECK(err_code);

    // Register with the SoftDevice handler module for BLE events.
    err_code = softdevice_sys_evt_handler_set(sys_evt_dispatch);
    APP_ERROR_CHECK(err_code);
}

However, I believe many of the functions used in this example are not available in the latest version of the SDK. Do you have any suggestions on how I can implement this?

Best Regards,

Lara

  • Hi Lara,

    Are you early in development? If so, I would stronlgy advice that you migrate to the nRF Connect SDK (see nRF Connect SDK and nRF5 SDK statement). This is prticularily relevant here, as multiple advertising sets is supported out of the box in the nF Connect SDK (see BLE multiple advertising sets sample).

    Einar

  • Hello Einar,

    Thank you for your response.

    Unfortunately, I am already in an advanced stage of development and starting the project from scratch with the nRF Connect SDK is not a viable option for us. While I find the SDK interesting, I would like to know if it is still possible to have multiple advertising with nrf52 even if it is not as easy.

    Our original idea is for our device to serve as both a beacon and a connectable advertisement, triggered by a button. When the central device detects the beacon, a notification will be activated, prompting the user to connect to the device.

    If this option is not feasible, we are considering alternative solutions, such as having the device act as a beacon that can receive data and trigger a notification on the central device when data is detected. This notification would then send back data to the beacon, causing it to switch modes and advertise connectable once again.

    Another option we are considering is to advertise as a beacon for a few seconds before switching to a connectable mode.

    Thank you.

    Lara

  • Hi Lara,

    I understand. The SoftDevice simply does not support multiple advertising sets, so that cannot be configurd. But there are ways around it, as you have described. The most common approach is to alternate between the two (or more) advertising sets. Use an app_timer or similar to trigger re-configuration at a regular interval. This is simple and will likely work equally good on a high level.

    Another posibility is to implement an additional advertiser using the SoftDevice Timeslot API. I would not recomemnd that approach though, as it is more complex, you will be using a custom implementation for the advertising in timeslot that requiers aditional Bluetooth qualification work. Also, the end result will likely not be much better.

  • Hi Einar, 

    I'll try using app_timer  and alternate between my advertising sets.

    Thanks for your help,

    Lara

Related