主设备端向从设备传输数据,为了达到最大的传输速率可以采用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