主设备端向从设备传输数据,为了达到最大的传输速率可以采用write cmd(写命令,无需从设备回应)方式向从设备写数据;从设备向主设备发送数据,为了达到最大的传输速率可以使用Notification(通知,无需主设备回应)

本文代码以nordic平台为例进行说明

影响传输速率的主要因素

  • 连接间隔
  • 连接间隔传输的数据包数量
  • 数据包大小

1 连接间隔

如果启用了CLE(不受单个连接间隔内,只能发送 4~6个数据包的限制),因此只需要选择一个合适的连接间隔即可,无须使用低功耗蓝牙5.x协议栈中的最小连接间隔(7.5ms)。但需要注意的是,NRF_SDH_BLE_GAP_EVENT_LENGTH大于或等于连接间隔。根据 Nordic协议栈给出的参考数据可知,当实际连接间隔为50ms或者400ms 时,对应的传输速率分别是1327.5 kbps 和1376.2kbps。

因此连接间隔可以这样设置

#define CONN_INTERVAL_MIN               (uint16_t)(MSEC_TO_UNITS(50, UNIT_1_25_MS))    /**< Minimum acceptable connection interval, in units of 1.25 ms. */
#define CONN_INTERVAL_MAX               (uint16_t)(MSEC_TO_UNITS(60, UNIT_1_25_MS))    /**< Maximum acceptable connection interval, in units of 1.25 ms. */

2 连接间隔传输的数据包数量

有两个参数会影响到连接间隔数据包数量

  • CLE
  • 连接事件长度

2.1 CLE

CLE是Connection Event Length Extension 的简写,表示连接事件长度扩展。在4.0协议中,单个连接事件最多只能发送4个(IOS)或者6个(Android)数据包。当采用CLE时,协议栈会判断连接间隔剩下的时间是否还可以发送数据包,如果还可以发送数据包,则会继续发送数据,而且不限制数据包的数量。

在协议栈初始化完成之后进行开启CLE

//status 为true时,打开CLE
void conn_evt_len_ext_set(bool status)
{
    ret_code_t err_code;
    ble_opt_t  opt;

    memset(&opt, 0x00, sizeof(opt));
    opt.common_opt.conn_evt_ext.enable = status ? 1 : 0;

    err_code = sd_ble_opt_set(BLE_COMMON_OPT_CONN_EVT_EXT, &opt);
    APP_ERROR_CHECK(err_code);
}

2.2 连接事件的长度

连接事件的长度单位1.25ms,NRF_SDH_BLE_GAP_EVENT_LENGTH,可在sdk_config.h中修改,这个值可以等于连接间隔

// <o> NRF_SDH_BLE_GAP_EVENT_LENGTH - GAP event length. 
// <i> The time set aside for this connection on every connection interval in 1.25 ms units.
#ifndef NRF_SDH_BLE_GAP_EVENT_LENGTH
#define NRF_SDH_BLE_GAP_EVENT_LENGTH 400
#endif

3 数据包大小

两个参数可以影响数据包大小

  • ATT_MTU
  • DLE

3.1 ATT_MTU大小

4.0协议最大为23字节,5.x协议支持的最大ATT_MTU大小为 247字节,可在sdk_config.h中修改

// <o> NRF_SDH_BLE_GATT_MAX_MTU_SIZE - Static maximum MTU size. 
#ifndef NRF_SDH_BLE_GATT_MAX_MTU_SIZE
#define NRF_SDH_BLE_GATT_MAX_MTU_SIZE 247
#endif

3.2 DLE

目前BLE 5.x协议支持的最大DLE为251,可在sdk_config.h中修改

// <i> Requested BLE GAP data length to be negotiated.
#ifndef NRF_SDH_BLE_GAP_DATA_LENGTH
#define NRF_SDH_BLE_GAP_DATA_LENGTH 251
#endif

4 使用2M PHY

目前BLE支持3种LE PHY,分别是LE 1M PHY,LE 2M PHY,LE CODED PHY,其中LE 2M PHY用于高速率,,而理论距离是LE 1M PHY的一半,而LE CODED PHY用于长距离模式,LE 1M PHY兼顾了距离和速率,可以根据自己实际需要进行选择,如果对传输距离有要求,需要谨慎选择。

LE PHY 可以通过调用sd_ble_gap_phy_update(uint16_t conn_handle, ble_gap_phys_t const *p_gap_phys)接口发起更新,一般在peripheral端,收到ble_evt_connected事件的时候进行请求更新。如下所示,即可配置为只支持2M 的PHY:

static test_params_t m_test_params =
{
    .phys.tx_phys             = BLE_GAP_PHY_2MBPS,
    .phys.rx_phys             = BLE_GAP_PHY_2MBPS,
};
static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context)
{
    uint32_t              err_code;
    ble_gap_evt_t const * p_gap_evt = &p_ble_evt->evt.gap_evt;
    switch (p_ble_evt->header.evt_id)
    {
        case BLE_GAP_EVT_CONNECTED:
            //这里只写phy更新部分,其他的省略
             err_code = sd_ble_gap_phy_update(p_gap_evt->conn_handle, &m_test_params.phys);
             APP_ERROR_CHECK(err_code);
            break;
    }
 }

5 增大协议栈队列缓冲区

在RAM有剩余空间的情况下,可以给协议栈配置更大的队列缓冲区,队列缓冲区的默认值时1,可根据实际情况进行配置

// <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 7 
#endif