BLE Peripheral Role · NRF52832 · NRF52840

BLE Multiple Concurrent Role Example


In this blog, I would share how to create the multiple role concurrently example on nRF5 SDK.  It would cover how to do the multiple peripheral role, single central role to connect multiple peripherals, combo example (2 x peripheral role + 2 x central role) concurrently.  This example is based on the Nordic NRF5 SDK 15.3 and can run on the nRF52832 and nRF52840 chipset.

This example is given to show how to set up the multiple role on Nordic SDK.   If you need to get more details, you may have a way to study the source code directly or ask the question on the Nordic Developer Zone.


Regarding to the classic (BR/EDR) bluetooth, each node can connect up to maximum 7 devices [Link].  It calls the connection in a piconet network.  The devices can switch roles, by agreement, and the slave can become the master.

Regarding to the Bluetooth Low Energy, after the bluetooth 4.1 specification, device has started to support the device to run multiple role (central/peripheral) concurrently.

On the Nordic Softdevice (Bluetooth Stack), S130 / S132 / S140 have started to support the multiple role.  For example, S132v4.x or later has support up to 20 concurrent links in all roles.  For example, if the device acts as central role, it can connect up to 20 peripherals.  Also, if the device can connect multiple mobile at the same time by using peripheral role.

For example, this demo shows the multilink capabilities of the nRF52 Series SoCs and their associated stacks. Both the nRF52840 and the nRF52832 together with the S140 and S132 SoftDevices respectively can support 20 concurrent Bluetooth Low Energy connections.


At the Nordic Playground Github [Link], it shows the demo code how to implement an aggregator node, running on an nRF52DK or an nRF52840 DK.  This aggregator can connect with an Android Host and 19 x peripheral devices (either DK or Thingy) at the same time.


Inside Nordic nRF5 SDK, it has the BLE mult-link central example which uses to connect more BLE Blinky Application as peripherals.

In this example, there are three difference roles.

  • Peripheral role
  • Central role
  • 2 x Peripheral Role + 2 x Central Role

All of them contains the GATT Server / Client.

  • NUS (Nordic UART Service)
  • Image Transfer Service (ITS)
  • BLE Blinky service (LBS)
/* Combo Role */

#define DEVICE_NAME                     "Multi_Role"                         /**< Name of device. Will be included in the advertising data. */

static char const m_target_periph_name[] = "LBS_NUS_Node";     
/**< Name of the device we try to connect to. This name is searched in the scan report data*/
//Inside sdk_config.h,

// <o> NRF_SDH_BLE_PERIPHERAL_LINK_COUNT - Maximum number of peripheral links.

// <o> NRF_SDH_BLE_CENTRAL_LINK_COUNT - Maximum number of central links.

// <o> NRF_SDH_BLE_TOTAL_LINK_COUNT - Total link count.
// <i> Maximum number of total concurrent connections using the default configuration.



  • Peripheral Role — NRF52840 DK / NRF52832 DK
  • Central Role — NRF52840 DK
  • Combo Role — NRF52832 DK
  • IDE Segger Embedded Studio

Source code :

The example code is based at the nRF5 SDK 15.3.

GATT Table

The device has included 3 difference services.

  1. Nordic Blinky Service (LBS) (Server and Client)
  2. Nordic UART Service (NUS) (Server and Client)
  3. Image Transfer Service (ITS) (Server and Client)

On the callback of the BLE batch routine, it has two difference routines to handle either peripheral role or central role.

static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context)
        ret_code_t err_code;
        // For readability.
        uint16_t conn_handle = p_ble_evt->evt.gap_evt.conn_handle;

        uint16_t role        = ble_conn_state_role(conn_handle);
        ble_gap_evt_t const * p_gap_evt = &p_ble_evt->evt.gap_evt;

        if (    (p_ble_evt->header.evt_id == BLE_GAP_EVT_CONNECTED)
                &&  (is_already_connected(&p_ble_evt->evt.gap_evt.params.connected.peer_addr)))
                NRF_LOG_INFO("%s: Already connected to this device as %s (handle: %d), disconnecting.",
                             (role == BLE_GAP_ROLE_PERIPH) ? "PERIPHERAL" : "CENTRAL",
                             (role == BLE_GAP_ROLE_PERIPH) ? "CENTRAL"    : "PERIPHERAL",

                (void)sd_ble_gap_disconnect(conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);

                // Do not process the event further.

        switch (p_ble_evt->header.evt_id)

                // Assign connection handle to available instance of QWR module.

                m_connected_peers[conn_handle].is_connected = true;
                m_connected_peers[conn_handle].address = p_ble_evt->evt.gap_evt.params.connected.peer_addr;

                // Handle central connections
                if (p_gap_evt->params.connected.role == BLE_GAP_ROLE_PERIPH)
                else if ((p_gap_evt->params.connected.role == BLE_GAP_ROLE_CENTRAL) || (p_ble_evt->header.evt_id == BLE_GAP_EVT_ADV_REPORT))
Peripheral Role Connected
Central Role Connected

This example is just for the proof of concept how to build up the multiple central and peripheral together. I don’t have any code guarantee and support.

if you would like to setup the 2 central + 2 peripheral role to run on the nRF52810, I have the simple example. Please let your message and email to me on such request.

Welcome to give any feedback and comments.

4 thoughts on “BLE Multiple Concurrent Role Example

  1. Wow that was odd. I just wrote an very long comment but
    after I clicked submit my comment didn’t appear. Grrrr…
    well I’m not writing all that over again.
    Anyways, just wanted to say superb blog!


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.