OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 7067|回复: 6

转载:nRF52832跟手机之间速率通讯压力测试

[复制链接]

13

主题

40

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
344
金钱
344
注册时间
2012-7-13
在线时间
83 小时
发表于 2018-10-20 12:33:15 | 显示全部楼层 |阅读模式
如何开发BLE数据透传应用程序?什么是BLE service和characteristic?如何开发自己的service和characteristic?如何区分ATT和GATT?有没有什么工具可以对BLE设备进行压力测试?如何提高BLE设备的数据上传速度?本文将对以上问题进行解答。
在很多应用场合,BLE只是作为一个数据透传模块,即将设备端数据上传给手机,同时接收手机端下发的数据。本文将和大家一起,一步一步演示如何开发一个BLE透传应用程序。按照本文的说明,大家可以很快就实现一个BLE透传应用,BLE透传应用已经是BLE应用中比较复杂的一种,一旦大家掌握了BLE透传应用,其他BLE应用开发就更不在话下了。本文还会以BLE透传为例子,来解释BLE service和characteristic等概念,以帮助大家理解如何定义和开发自己的BLE service和characteristic等,从而彻底理解BLE协议栈中的ATT和GATT的运行原理。然后,本文还将手把手教大家如何提高BLE数据传输速度(蓝牙4.2的理论吞吐率大概为100kB/s,而我们实际达到了80kB/s,已经非常接近理论值)。最后,我们将告诉大家如何使用安卓版nRF Connect来对你的BLE设备进行压力测试,以测试设备的稳定性和可靠性。当然,文章的最后也会告诉大家如何找到安卓和iOS手机app开发参考代码。

1. 开发准备
1)     Nordic nRF52或者nRF51开发板1块。请参考“Nordic nRF51/nRF52开发流程说明”,购买相应开发板(DK)。
2)     开发环境搭建。简述如下(详细说明请参考“Nordic nRF51/nRF52开发环境搭建”):
注:如果你使用的是Linux系统/Mac系统,或者你使用的不是Keil5-MDK,请参考“Nordic nRF51/nRF52开发环境搭建”来搭建你的开发环境。
2. 运行Nordic ble_app_uart应用程序
Nordic SDK已经提供了一个直接就可以编译和运行的数据透传应用程序:ble_app_uart,Nordic将BLE透传服务称为Nordic UART Service(NUS),所以在Nordic SDK中,NUS就是BLE透传服务。请按照如下步骤运行SDK自带的ble_app_uart程序:
1)     确认自己的芯片型号或者开发板。如果采用Nordic官方开发板的话,芯片型号和开发板编号对应关系如下:
  • nRF51系列对应开发板编号为PCA10028
  • nRF52832和nRF52810对应开发板编号为PCA10040。虽然52832和52810共用同一块开发板,但是他们在SDK中的项目编号是不一样的,52832对应PCA10040目录,52810对应PCA10040e目录,由于52810和52832 PIN to PIN兼容,软件也是完全兼容的,因此SDK很多项目只有PCA10040的目录,而没有PCA10040e目录,此时需要你自己来建立PCA10040e对应的目录和工程,具体说明可参考:http://infocenter.nordicsemi.com/index.jsp?topic=%2Fcom.nordic.infocenter.sdk5.v15.0.0%2Fnrf52810_user_guide.html&cp=4_0_0_5_0
  • nRF52840对应开发板编号为PCA10056
  • nRF52840 dongle编号为PCA10059
这里我会以nRF52832开发板PCA10040为例来阐述整个开发过程,其他开发板与之类似,大家自己可以举一反三来开始自己的开发之旅。
2)     将开发板与PC机通过USB线相连,同时打开开发板电源(将左下角的拨位开关打到“ON”位置),打开桌面版nRF Connect,选择启动“Programmer”应用,由于驱动之前已经安装好了,设备可以立即识别成功。执行“full erase”操作,以擦除芯片原始内容
最后我们来看main循环,它只有一个函数: idle_state_handle,idle_state_handle先把需要打印的日志打印完,然后让系统进入idle状态(Nordic SoC spec称其为System ON状态),一旦有协议栈事件或者中断事件发生,系统将唤醒,以处理相关事件回调函数,然后再执行一遍idle_state_handle。注意:idle状态下,蓝牙连接或者广播可以正常进行而不受影响,蓝牙连接或者广播都是周期性的,在一个周期中,蓝牙连接或者广播只持续很短一段时间(这段时间CPU有可能会退出idle状态),其余时间系统都是处于idle状态的,从而大大节省系统功耗。

7. 定制你的BLE数据透传应用程序7.1 BLE数据上传吞吐率
如何快速的把大量数据上传给手机?这是一个很常见的应用场合,现在我们尝试去修改一下Nordic的原生例程,以实现最高的数据吞吐率。下面我们通过几种不同的方法来看看每种方法下它的吞吐率能到多少。
方法1:(通过宏METHOD1来开关)
蓝牙spec规定,蓝牙连接间隔最小只能为7.5m,为了达到最高的吞吐率,我们创建一个timer,让其每7ms发一次数据,看一看此时吞吐率能达到多少。7ms中断服务函数代码如下所示:
[u
通过查看nRF connect日志,你会发现此时不会发生丢包了,但吞吐率直接降到了1.6kB/s左右。
方法1+:(通过宏METHOD1_PLUS来开关)
       然后我们把连接间隔设为尽可能小,以期提高吞吐率,如下:
[url=][/url]
#ifdef CONN_INTERVAL_OPTIMIZ#define MIN_CONN_INTERVAL               MSEC_TO_UNITS(8, UNIT_1_25_MS)   #define MAX_CONN_INTERVAL               MSEC_TO_UNITS(12, UNIT_1_25_MS)#endif[url=][/url]


这种方法吞吐率能达到10kB/s,但离我们的目标还是很远。
最后我们把connection event length extension和data length extension都打开(我们将在方法2+中详细阐述这2个有效提高吞吐率的利器),即定义如下宏:


可以看到吞吐率将达到70kB/s,这个吞吐率还是不错的。但仔细查看nRF connect日志,你会发现这种模式下还是有小概率事件会导致“丢包”发生,而且整个发送逻辑也不是很优化,为此我们想到了METHOD2.
方法2:(通过宏METHOD2来开关)
ble_nus_data_send每次成功发送数据包,都会产生一个BLE_NUS_EVT_TX_RDY事件,收到这个事件后,再去调用ble_nus_data_send,丢包的情况就不会再发生了,核心代码如下所示:
大家可以自己去查看一下nRF  Connect的数据log,这种方式是没有丢包的,但是打开RTT viewer,你会发现他的吞吐率低得可怜,只有1kB/s。
方法2+:(通过宏METHOD2_PLUS来开关)
与方法1+类似,我们在方法2基础上,持续往发送buffer送数据直到返回值不为0,如下:
然后我们增加gap event length extension功能,gap event length跟connection event length两者意思差不多,都是为了实现一个连接间隔可以发或收多个包的目的。为了使能gap event length extension功能,首先将gap event length修改成一个合适的值,以使其尽可能占满整个连接间隔,如下将gap event length修改为30ms
#define NRF_SDH_BLE_GAP_EVENT_LENGTH 24

然后我们再将连接间隔设为尽可能小,以保证上述connection event可以占据整个连接间隔:
[url=][/url]
#ifdef CONN_INTERVAL_OPTIMIZE#define MIN_CONN_INTERVAL               MSEC_TO_UNITS(8, UNIT_1_25_MS)   #define MAX_CONN_INTERVAL               MSEC_TO_UNITS(12, UNIT_1_25_MS)#endif[url=][/url]


同时我们使能connection event extension功能,如下:
[url=][/url]
#ifdef EVT_LEN_EXT_ON    ble_opt_t  opt;    memset(&opt, 0x00, sizeof(opt));    opt.common_opt.conn_evt_ext.enable = true;    err_code = sd_ble_opt_set(BLE_COMMON_OPT_CONN_EVT_EXT, &opt);    APP_ERROR_CHECK(err_code);#endif[url=][/url]


我现在使用的是华为P9手机,它将把MTU设为241,在DLE不开的情况下(此时链路层每个数据包的长度还是只有27个字节!),我们可以看到throughput可以达到10kB以上,如下:




然后我们再打开DLE功能,此时链路层每个数据包的长度将变成251字节,如下:
[url=][/url]
#ifdef DLE_ON        case BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST:        {            NRF_LOG_DEBUG("DLE update request.");            ble_gap_data_length_params_t dle_param;            memset(&dle_param, 0, sizeof(ble_gap_data_length_params_t));   //0 means auto select DLE                                                                                err_code = sd_ble_gap_data_length_update(p_ble_evt->evt.gap_evt.conn_handle, &dle_param, NULL);            APP_ERROR_CHECK(err_code);        } break;#endif[url=][/url]


此时我们可以看到throughput可以达到77kB/s,离蓝牙4.2的理论throughput已经很接近了。这里特别需要指出的是,当DLE使能情况下,connection interval不是越小吞吐率越高,我这里使用的connection interval大概为10ms,如果大家把这个connection interval提高到30ms,有可能吞吐率更高,这里就不再演示了。






上述代码工程已经上传到百度云盘中,有需要的同学可以到如下链接下载:
下载“tutorial_ble_app_uart_SDK15_0_0.rar”,然后解压缩到SDK15.0.0如下目录下:nRF5_SDK_15.0.0_a53641a\examples\ble_peripheral,即可成功编译运行。

7.2使用安卓版nRF connect测试BLE设备的稳定性和可靠性
先说明一下,以下内容只能通过安卓版nRF Connect来实现,iOS版nRF Connect不支持如下特性。
手机端宏录制方式
相信到现在大家对BLE数据上传机理和实践有个大概的了解,那如何测试BLE数据下行性能,即怎么测试数据从手机传到设备的稳定性和可靠性?我们是不是必须开发一款手机app来进行相关测试吗?答案是否定的,感谢Nordic给我们带来了nRF connect,nRF connect支持宏录制,我们可以通过nRF connect来对我们的设备进行压力测试。下面我们来讲讲宏录制是怎么工作的。
所谓宏录制,就是把你对nRF connect的操作录制下来,然后通过宏播放实现自动化操作。由于nRF connect是一个容器,并支持JavaScript和HTML语法,宏其实就是一个XML脚本,nRF connect定义了自己的一套XML标签操作,遵守这套XML标签操作,就可以对nRF connect进行自动化操作。nRF connect支持的所有XML语法都在手机安装目录\Nordic Semiconductor中的示例中体现,只要示例中出现过的标签就支持,相反示例中没有的标签就不支持。下面具体讲一下宏录制的操作过程。
当nRF connect连接设备成功后,你会发现右下角有一个红点,那个就是宏录制菜单。


点击下面的红点,我们开始宏录制操作


然后我们按照普通操作来操作nRF connect,这些操作最终对应的BLE指令会被录制下来,以便后续重复播放。我们先把“1234”发送给设备,如下:


发送完上述指令后,我们加一个300ms的延时,如下:


然后我们点击完成按钮,保存该宏,可以看出这个宏包括两条操作:发送“1234”到设备,然后睡眠300ms。


将宏命名为“test”并保存:


到此宏已经录制成功了,现在我们开始展示宏的神奇功能。如下,选择循环播放模式,然后点击“开始”按钮开始循环播放该录制宏。


大家可以看到,nRF connect先执行“Write 0x31323334 to RX characteristic”,然后睡眠300ms,然后又执行“Write 0x31323334 to RX characteristic”,如此循环往复。打开串口助手,你会发现设备已经收到了手机发过来的一连串“1234”,如下。


我们把刚才的test宏导出为XML,看一看它到底长什么样:
[url=][/url]
<macro name="test" icon="PLAY">   <assert-service description="Ensure Nordic UART Service" uuid="6e400001-b5a3-f393-e0a9-e50e24dcca9e">      <assert-characteristic description="Ensure RX Characteristic" uuid="6e40002-b5a3-f393-e0a9-e50e24dcca9e">         <property name="WRITE" requirement="MANDATORY"/>      </assert-characteristic>   </assert-service>   <write description="Write 0x31323334 to RX Characteristic" characteristic-uuid="6e400002-b5a3-f393-e0a9-e50e24dcca9e" service-uuid="6e400001-b5a3-f393-e0a9-e50e24dcca9e" val

大家可以看到,宏就是一些XML标记,大家也可以在此基础上,去修改该XML文件,以实现更复杂的自动化测试,然后通过nRF connect把最新的XML文件装载进来,就可以自动播放了。

电脑端XML方式
前面的宏录制方式,功能还是比较单一,如果要实现更复杂的自动化测试,可以通过在PC端执行XML脚本方式来实现。通过安卓调试工具ADB,我们可以直接通过PC来操作nRF connect,而nRF connect又能识别XML脚本,这样就可以让nRF connect按照XML脚本意图去执行相关自动化操作。nRF connect支持的所有XML语法都在手机安装目录中(手机内部存储/ Nordic Semiconductor目录)的示例中体现,只要示例中出现过的标签就支持,相反示例中没有的标签就不支持。


正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

0

主题

6

帖子

0

精华

新手上路

积分
29
金钱
29
注册时间
2012-7-2
在线时间
2 小时
发表于 2018-12-11 09:59:41 | 显示全部楼层
回复 支持 反对

使用道具 举报

0

主题

6

帖子

0

精华

新手上路

积分
29
金钱
29
注册时间
2012-7-2
在线时间
2 小时
发表于 2018-12-11 10:00:07 | 显示全部楼层
图片看不到哎
回复 支持 反对

使用道具 举报

0

主题

6

帖子

0

精华

新手上路

积分
29
金钱
29
注册时间
2012-7-2
在线时间
2 小时
发表于 2018-12-11 16:47:04 | 显示全部楼层
大神,你好。下载下来你的demo,我这跑出来怎么只有8KBS啊,我这哪里出错了?
607 *10ms == bytes send: 6558588 Bytes == avg speed: 7939 B/s
0>
0> <info> app: time: 82905 *10ms == bytes send: 6582388 Bytes == avg speed: 7939 B/s
0>
0> <info> app: time: 83206 *10ms == bytes send: 6606188 Bytes == avg speed: 7939 B/s
0>
0> <info> app: time: 83505 *10ms == bytes send: 6629988 Bytes == avg speed: 7939 B/s
0>
0> <info> app: time: 83790 *10ms == bytes send: 6653788 Bytes == avg speed: 7941 B/s
0>
0> <info> app: time: 84067 *10ms == bytes send: 6677588 Bytes == avg speed: 7943 B/s
0>
0> <info> app: time: 84391 *10ms == bytes send: 6701388 Bytes == avg speed: 7940 B/s
0>
0> <info> app: time: 84719 *10ms == bytes send: 6725188 Bytes == avg speed: 7938 B/s
0>
回复 支持 反对

使用道具 举报

3

主题

7

帖子

0

精华

新手上路

积分
40
金钱
40
注册时间
2012-8-21
在线时间
0 小时
发表于 2019-8-21 17:33:04 | 显示全部楼层
圖片看不到欸:@
回复 支持 反对

使用道具 举报

12

主题

64

帖子

0

精华

初级会员

Rank: 2

积分
99
金钱
99
注册时间
2020-2-17
在线时间
8 小时
发表于 2020-2-25 16:17:49 | 显示全部楼层
SYD8811对标nR*52832 (Pin to pin兼容不用改板子)
4e077d997e645f24a3d334c7ca5e659.png
0_2.jpg
回复 支持 反对

使用道具 举报

0

主题

2

帖子

0

精华

新手上路

积分
20
金钱
20
注册时间
2020-6-30
在线时间
5 小时
发表于 2020-7-26 22:04:07 | 显示全部楼层
你好,我想问一下我试跑nrf52832的uart例程,手机通过蓝牙软件发送给板子,然后想在串口显示。但是有个问题,我的G到Z的字母无法在串口中显示是为啥???求求大佬解惑
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-22 16:08

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表