NRF52810传输速率测试

NRF52810传输速度测试

最近有项目要用到NRF52810这款蓝牙IC,于是就买了一个板子准备测试一下,项目目前的需求不是很高,传输速度能达到1KB/S就可以了。看网上大家测试的效果都挺不错的,在1M模式下能测试到80KB/S,于是我也想试试,借鉴了一下别人的方法,
前期测试思路是这样的,每10ms发送244个字节,然后连续发送100次,这样的话刚好1秒,然后传输速度的话就是100*244 = 24400B/S,然后后面只需要缩短包间隔就能提高理论传输速率。
于是我就开干了。
一. 环境搭建
测试环境搭建的话我主要参考这篇文章:手把手教你开发自己的BLE
主要思路也是根据这篇文章做了一些改动,环境的话需要改动的是NRF52810打开工程时,打开10040e下的工程,NRF52832是10040。
在看了网上很多篇博客,大家主要修改的主要参数有:
1.增大MTU,在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   // MTU大小
#endif

2.增大DLE,在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     // DLE 数据长度拓展
#endif

3.打开CLE,在main.c中加入如下代码,放在蓝牙协议栈后面初始化

//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);
}

4.连接事件长度定义,这里我设置的800,在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 800     

5.调整连接时间间隔,在main.c中

#define MIN_CONN_INTERVAL               MSEC_TO_UNITS(8, UNIT_1_25_MS)             /**< Minimum acceptable connection interval (20 ms), Connection interval uses 1.25 ms units. */
#define MAX_CONN_INTERVAL               MSEC_TO_UNITS(12, UNIT_1_25_MS)             /**< Maximum acceptable connection interval (75 ms), Connection interval uses 1.25 ms units. */

二. 软硬件准备
1.硬件准备
NRF52810模块一个。
支持蓝牙1M模式,2M模式手机一台,我这里用的是HUAWEI P40 PRO。
2.软件准备
打开官方例程ble_app_uart,将第一章的代码片段修改和加入。
创建测试定时器,在main.c中加入如下代码

/**@brief CreateTestTimer
 */
void CreateTestTimer(void)
{
  app_timer_create(&s_testTimer, APP_TIMER_MODE_REPEATED, timer_testCallback);
	app_timer_start(s_testTimer, APP_TIMER_TICKS(10), NULL);   // 10ms定时器
}

增加定时器回调函数,在main.c中加入如下代码

/**
 @brief 
 @param 
 @return 
*/
static void timer_testCallback(void *arg)
{
	UNUSED_PARAMETER(arg);
	nrf_ble_speed_test();   // 传输速度测试
}

添加速度测试函数,在main.c中加入如下代码

/**
 @brief 
 @param 
 @return 
*/
void nrf_ble_speed_test(void)
{
	static uint16_t DEBUG_CNT1 =0,DEBUG_CNT2 = 0;
	uint32_t   err_code;
	uint16_t   length = 244;  // 每一包数据长度
	static uint8_t   head_data =0;
	uint8_t buf[255];
	DEBUG_CNT1 ++;
	if(1){
	    // 头尾数据幅值
		head_data ++;
		if(head_data == 254)head_data = 0;
		buf[0]=head_data;
		buf[length-1]=head_data;
		// 发送数据
		err_code = ble_nus_data_send(&m_nus, buf,&length, m_conn_handle);
		if ((err_code != NRF_ERROR_INVALID_STATE) &&
				(err_code != NRF_ERROR_RESOURCES) &&
				(err_code != NRF_ERROR_NOT_FOUND))
		{
				APP_ERROR_CHECK(err_code);
		}
		// 判断数据是否发送成功,成功则成功次数加一
		if(err_code == NRF_SUCCESS){
			DEBUG_CNT2 ++;
		}
	}
	// 每10ms进入一次,计算1s内理论传输速度和实际传输速度
	if(DEBUG_CNT1 == 100){
		NRF_LOG_INFO("SUCCES Num = %d Theoretical speed = %d B/s Actual speed = %d B/s",DEBUG_CNT2,(DEBUG_CNT1*length),(DEBUG_CNT2*length));
		DEBUG_CNT1 = 0;
		DEBUG_CNT2 = 0;
	}
}

main函数总览

/**@brief Application main function.
 */
int main(void)
{
//	bool erase_bonds;
	uint8_t int_stu = 0;
	// Initialize.
	uart_init();                        // 串口初始化
	log_init();                         // LOG打印初始化  可选UART/RTT
	timers_init();                      // timer初始化 用来生成低功耗计时器
	buttons_leds_init(&erase_bonds);  // 按键和LED初始化,定义按键和LED功能
	power_management_init();            // 低功耗管理模块初始化,通过软件方式让设备自动进入低功耗
	ble_stack_init();                   // 协议初始化,能能蓝牙协议栈,并对其配置
	conn_evt_len_ext_set(1);            // 启用CLE功能
	gap_params_init();                  // GAP参数初始化 用来修改广播名字和连接间隔
	gatt_init();                        // GATT参数初始化 用来修改底层数据包长度
	services_init();                    // 添加蓝牙SERVER和CHARACTERISTIC
	advertising_init();                 // 广播参数初始化 用来修改广播内容、广播间隔及广播超时时间
	conn_params_init();                 // 用来请求更新连接间隔
	// by maozhi 20220127
	CreateTestTimer();     // 初始化定时器
	// Start execution.
//	printf("\r\nUART started.\r\n");
	NRF_LOG_INFO("Debug logging for UART over RTT started.");
	advertising_start();

	// Enter main loop.
	for (;;)
	{
		idle_state_handle();
	}
}

三. 测试及结果
将代码下载到开发板,开始打印如下LOG
NRF52810传输速率测试

如上图,在手机还没连接时,发送成功的包数为0,理论速度为24400B/S,实际速度为0。打开手机用BLE调试助手连接该模块,BLE软件初次打开默认是1M模式,然后测得到如下结果NRF52810传输速率测试NRF52810传输速率测试
可以看到每秒发送成功的次数为60次左右,最高速率为16KB/S左右,但和理论应该发送100包,速率为24400B/S还有差距,说明中间有很多包没有发送成功。
然后我试着打开BLE的2M模式,点右上角3个点
NRF52810传输速率测试
勾选LE 2M,然后点击SET,再打开通知,得到如下测试结果
NRF52810传输速率测试
NRF52810传输速率测试
可以看到最高实际速度已经来到了24156B/S,成功发送的包数也已经到了99包,但是也还是丢包了,平均速度23KB/S左右,确实2M模式要比1M模式下丢包很少。
目前的测试结果就是这样了,而且不同手机测出来的结果也会不一样,我用了另一台不同型号的手机来测试,速度却慢了很多。
最后因为时间的问题,我就先不做深究了,老大该炒我鱿鱼了。如果大家有和我有过类似环境下的测试,测试的结果很接近蓝牙的理论值的,请在下方评论,我会在以后的某一天将改正后的测试结果和方法分享出来。
第一篇博客,欢迎大家指正,谢谢。

上一篇:【ResourceManagerService 分析】第九篇:MediaCodec 的 init(),configure(),start() 函数的调用 reclaimResource()的逻辑


下一篇:使用DBLINK查询时报ORA-00600: internal error code, arguments: [kzdlk_zt2 err]