Implementation of Bluetooth BLE One Master and Multiple Slaves with nRF52832

When implementing Bluetooth one master and multiple slaves functionality using Nordic Semiconductor’s nRF52832 chip, you need to use the development kit and Bluetooth protocol stack provided by Nordic. Below are the detailed implementation steps and key code examples, based on the latest nRF5 SDK v17.1.0 and SoftDevice S132.

1. Development Environment Setup

Essential Tools:

  1. nRF5 SDK: Download the latest SDK (v17.1.0) from the Nordic website.
  2. SoftDevice S132: This is the protocol stack that supports Bluetooth multi-connection, suitable for nRF52832.
  3. Development Toolchain:
  • Keil, Segger Embedded Studio (SES), or GCC.
  • nRF Connect tool for debugging and testing Bluetooth functionality.

2. Introduction to Bluetooth One Master and Multiple Slaves

  • Master Device (Central): nRF52832 acts as the master device, capable of connecting to multiple slave devices simultaneously.
  • Slave Device (Peripheral): Multiple slave devices can connect to the master device at the same time.
  • Maximum Connection Count: nRF52832 supports up to 8 connections (total of master and slave roles), depending on RAM configuration.

3. Implementation Steps

The following are the key steps to implement Bluetooth one master and multiple slaves functionality.

1. Configure Connection Count

Configure the number of connections for master and slave roles in <span>sdk_config.h</span>:

#define NRF_SDH_BLE_CENTRAL_LINK_COUNT 8   // Number of slave devices connected to the master device#define NRF_SDH_BLE_PERIPHERAL_LINK_COUNT 0 // Number of connections for slave role (set to 0 if only acting as master)#define NRF_SDH_BLE_TOTAL_LINK_COUNT 8     // Total number of connections (master + slave)

2. Initialize BLE Stack

When initializing the BLE stack, you need to set the connection roles and maximum connection count:

void ble_stack_init(void){    ret_code_t err_code;
    // Enable SoftDevice    err_code = nrf_sdh_enable_request();    APP_ERROR_CHECK(err_code);
    // Configure maximum connection count for BLE stack    uint32_t ram_start = 0;    ble_cfg_t ble_cfg;
    memset(&ble_cfg, 0, sizeof(ble_cfg));    ble_cfg.gap_cfg.role_count_cfg.periph_role_count = NRF_SDH_BLE_PERIPHERAL_LINK_COUNT;    ble_cfg.gap_cfg.role_count_cfg.central_role_count = NRF_SDH_BLE_CENTRAL_LINK_COUNT;    ble_cfg.gap_cfg.role_count_cfg.central_sec_count = 0;
    err_code = sd_ble_cfg_set(BLE_GAP_CFG_ROLE_COUNT, &ble_cfg, ram_start);    APP_ERROR_CHECK(err_code);
    // Enable BLE stack    err_code = nrf_sdh_ble_enable(&ram_start);    APP_ERROR_CHECK(err_code);}

Please open in WeChat client

3. Scan and Connect to Slave Devices

The master device needs to scan for nearby slave devices and initiate connections.

Configure Scan Parameters:
static ble_gap_scan_params_t const m_scan_params = {    .active        = 1,                       // Active scanning    .interval      = 0x00A0,                  // Scan interval (in units of 0.625ms)    .window        = 0x0050,                  // Scan window (in units of 0.625ms)    .timeout       = 0,                       // Scan timeout (unlimited)    .scan_phys     = BLE_GAP_PHY_1MBPS,       // PHY configuration    .filter_policy = BLE_GAP_SCAN_FP_ACCEPT_ALL,};
Start Scanning:
void scan_start(void){    ret_code_t err_code;
    err_code = sd_ble_gap_scan_start(&m_scan_params, NULL);    APP_ERROR_CHECK(err_code);}
Handle Scan Events:

Handle device discovery and connection in the scan event callback function:

void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context){    switch (p_ble_evt-&gt;header.evt_id)    {        case BLE_GAP_EVT_ADV_REPORT:        {            ble_gap_evt_adv_report_t const * p_adv_report = &p_ble_evt-&gt;evt.gap_evt.params.adv_report;
            // Determine whether to connect to this device            if (is_target_device(p_adv_report))            {                // Initiate connection                ret_code_t err_code = sd_ble_gap_connect(&p_adv_report-&gt;peer_addr,                                                         &m_scan_params,                                                         &m_connection_params,                                                         APP_BLE_CONN_CFG_TAG);                APP_ERROR_CHECK(err_code);            }            break;        }
        case BLE_GAP_EVT_CONNECTED:            NRF_LOG_INFO("Connected.");            // Save connection handle            m_conn_handle = p_ble_evt-&gt;evt.gap_evt.conn_handle;            break;
        case BLE_GAP_EVT_DISCONNECTED:            NRF_LOG_INFO("Disconnected.");            // Restart scanning            scan_start();            break;
        default:            break;    }}

4. Handle Connection Events

In connection events, save the handle for each connection and handle related logic:

#define MAX_CONNECTIONS NRF_SDH_BLE_CENTRAL_LINK_COUNT
static uint16_t m_conn_handles[MAX_CONNECTIONS]; // Save connection handles
void on_ble_evt(ble_evt_t const * p_ble_evt){    switch (p_ble_evt-&gt;header.evt_id)    {        case BLE_GAP_EVT_CONNECTED:            NRF_LOG_INFO("Device connected, handle: %d", p_ble_evt-&gt;evt.gap_evt.conn_handle);
            // Save connection handle            for (uint8_t i = 0; i &lt; MAX_CONNECTIONS; i++)            {                if (m_conn_handles[i] == BLE_CONN_HANDLE_INVALID)                {                    m_conn_handles[i] = p_ble_evt-&gt;evt.gap_evt.conn_handle;                    break;                }            }            break;
        case BLE_GAP_EVT_DISCONNECTED:            NRF_LOG_INFO("Device disconnected, handle: %d", p_ble_evt-&gt;evt.gap_evt.conn_handle);
            // Clear connection handle            for (uint8_t i = 0; i &lt; MAX_CONNECTIONS; i++)            {                if (m_conn_handles[i] == p_ble_evt-&gt;evt.gap_evt.conn_handle)                {                    m_conn_handles[i] = BLE_CONN_HANDLE_INVALID;                    break;                }            }            break;
        default:            break;    }}

4. Optimization and Considerations

  1. RAM Configuration: Multi-connection requires more RAM. When using <span>nrf_sdh_ble_enable()</span>, the SDK will prompt for the RAM starting address, which you need to adjust in the project settings.
  2. Connection Parameters: Reasonably configure connection intervals and timeout values to ensure performance and stability in multi-connection scenarios.
  3. Event Priority: When handling multiple connections, ensure that event priorities are sufficiently high to avoid missing critical events.
  4. Power Management: Multi-connection increases power consumption; it is recommended to optimize advertising intervals and connection parameters to reduce power consumption.

5. Testing and Debugging

  • Use nRF Connect Mobile App to test the connection capabilities of the master device.
  • Use nRF Sniffer to capture Bluetooth packets and analyze connection status.

6. Reference Documents

  • nRF5 SDK Documentation
  • SoftDevice S132 Specification

Leave a Comment