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

Overview
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.
Also,
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.
Description
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.
#ifndef NRF_SDH_BLE_PERIPHERAL_LINK_COUNT
#define NRF_SDH_BLE_PERIPHERAL_LINK_COUNT 2
#endif
// <o> NRF_SDH_BLE_CENTRAL_LINK_COUNT - Maximum number of central links.
#ifndef NRF_SDH_BLE_CENTRAL_LINK_COUNT
#define NRF_SDH_BLE_CENTRAL_LINK_COUNT 2
#endif
// <o> NRF_SDH_BLE_TOTAL_LINK_COUNT - Total link count.
// <i> Maximum number of total concurrent connections using the default configuration.
#ifndef NRF_SDH_BLE_TOTAL_LINK_COUNT
#define NRF_SDH_BLE_TOTAL_LINK_COUNT 4
#endif
Requirement
- Peripheral Role — NRF52840 DK / NRF52832 DK
- Central Role — NRF52840 DK
- Combo Role — NRF52832 DK
- IDE Segger Embedded Studio
Source code : https://github.com/jimmywong2003/nrf5-ble-multiple-role-example
The example code is based at the nRF5 SDK 15.3.
GATT Table
The device has included 3 difference services.
- Nordic Blinky Service (LBS) (Server and Client)
- Nordic UART Service (NUS) (Server and Client)
- 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",
conn_handle);
(void)sd_ble_gap_disconnect(conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
// Do not process the event further.
return;
}
switch (p_ble_evt->header.evt_id)
{
case BLE_GAP_EVT_CONNECTED:
// Assign connection handle to available instance of QWR module.
multi_qwr_conn_handle_assign(conn_handle);
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)
{
on_peripheral_connected(p_gap_evt);
}
else if ((p_gap_evt->params.connected.role == BLE_GAP_ROLE_CENTRAL) || (p_ble_evt->header.evt_id == BLE_GAP_EVT_ADV_REPORT))
{
on_central_connected(p_gap_evt);
}
break;


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.
Thanks for your interests on my blog. Since 2019, I have created this blog and shared the idea how to do some funny stuffs. I am very pleasure that I get quite a lot of positive feedback. I really hope that this blog helps your own embedded solution development. May I get support from you to keep it in order to maintain the wordpress host service? Your appreciation would be very helpful.
https://jimmywongiot.com/2021/05/26/asking-for-support/

Good post however , I was wanting to know if you could write a litte more on this topic? I’d be very grateful if you could elaborate a little bit more. Thank you!
LikeLike
Multiple concurrent role example on nRF5 SDK such as combo ( peripheral + central), multiple central x 8, peripheral
LikeLike
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!
LikeLike
very useful in on field
LikeLike
Hi Jimmey, thanks for your example code. I have a question that how to set up communication between specific peripheral and central. For example, there are two peripherals and I want to turn on the led of one of them. Thank you.
LikeLike
Hey,
I’m currently interested in the way of making the simultaneous connection with different roles and would love to get hands on the simple example. Looking forward to your response. I don’t want to get my em@il public, so i hope you see my email:)
Best regards,
Saulius
LikeLike