用户
 找回密码
 立即注册

33

主题

96

帖子

1791

积分

金牌会员

Rank: 6Rank: 6

积分
1791
发表于 2019-7-25 20:53:32
各位高人,

小弟还在挣扎于经典蓝牙的接收,问题还是没解决:DataReceived事件接收效果不可控,通过蓝牙模块接收到的数据有分块情况,也有数据丢失的情况,而且似乎并无规律可循。
我把近期的测试情况再汇总如下,希望Smobiler的专家和社区的高人指点。

现场环境:  有效接收到的数据包有若干种,均为二进制字节,数据包大小不同(即byte数量不同),但第一字节均为控制字,最后一个字节是前面所有字节的简单校验,
即 byte[n] = SUM(byte[0] .. byte[n-1]) & 0xFF.  数据包接收前必须由APP先向对端设备发送数据请求命令,因此程序可以预知需要正确接收的数据包的大小。

我设计的接收方案中,有三条主线:

1.  DataReceived 事件中,仅将收到的数据(e.Data)添加到数据接收缓冲区(程序中 由 byte[] Data_Buffer 表示),该缓冲区大小不定,根据接收到的数据大小自动扩展。
     这样的设置是为了确保它的一次运行时间足够短,不会出现在全部代码运行完之前 又接收到新的数据(我自己认为这可能导致接收异常)
2.  子线程中的设置无限循环( while(true) ),在循环中对数据接收缓冲区中的数据长度进行判断,如果连续3次(可调整)得到的数据长度保持不变,即认为这次完整的数据接收已经完成
     此时设置 标识,该标识被DataReceived 事件用于判断是否继续接收外部输入的数据( 这个主要是为了防止干扰,万一后续又收到其他数据,实际工程环境中未必又这种情况)
     每两次数据长度测试之间的间隔设置为5ms(可调整),也就是说如果连续15ms时间内接收到的数据长度不发生变化,即认为数据收全
3.  定时器,设置为3s(可调整)间隔,在其中判断死循环中设置的标识,如果标识置位,则将数据缓冲区中的数据复制出来,并清空缓冲区(Data_Buffer = null), 并清除标识,以便
     再次接收数据。 并对收到的数据进行判断: 数据长度是否符合预期;校验值是否正确;如果一切无误,则认定收到了正确的数据并进行其他处理,否则向对端发送相同的数据请求包

对上面的方案进行测试,我发现数据成功接收的成功率和接收数据包的大小有相关性。
-  当接收数据包为16 bytes时,数据接收成功率在95%左右,单个包的接收时间约为40ms,  也就是说,每次进入DATa Received事件的数据包的处理事件在 2.5ms - 40ms 之内。间接
    反映我在第二和第三条中的事件基本合适。
-  当接收数据包为20 bytes时,数据接收成功率下降到50%左右,,即两次接收的数据就有一次不成功,需要重复一次才可以,没有测试单包的接收时间。
-  当接收数据包为24 bytes时,数据接收成功率已经降到2%左右,也就是说经过50次上述流程,才能正确接收一个包,已经完全不能够使用,没有测试单包的接收时间。

由于在通信环节中有存在24个byte的接收数据,上面的方案基本就是无法使用   

在此我想请各位专家帮我分析一下,可能的问题出在哪里?  我个人倾向于和硬件无关,但我也会去更换蓝牙模块再去测试(很麻烦,毕竟不是自己设计的)

另外我想了解,由于Smobiler的 服务器-客户端 模式,网络的时延会不会也是一个问题因素?我现在是在局域网环境下测试,如果换成公网,时延增大的话,会不会影响到数据接收?
这里我就想了解一下,当APP所在的硬件(比如手机)上的蓝牙模块接收到数据时,该数据是如何处理的?是不是发送通过网络到服务器侧进行处理?也就是说我上面测试8byte数据包
的接收时间40ms其中包含了网络传输的时间?

另外我想问Smobiler的专家的是,我上面观察到的接收数据分段的情况,是APP蓝牙接收器本身的问题,还是APP OS的问题?我之所以这么问,是因为当我APP向对端发送数据包时,
对方可是能够一次性接收到所有数据,并不存在发包被分段 (对端是PC上的C# 程序)。之前测试该蓝牙功能的时候,有没有类似的问题出现?

还有一个问题,如果换成BLE蓝牙,性能上是否会有提高? 我对接的蓝牙模块是双模的,同时支持经典蓝牙和BLE蓝牙,如果确切的克制BLE效果更好更稳定,我来试一下BLE的方式,
顺便问一下有BLE的使用说明吗?

多谢 多谢 多谢。请多多支持。

大杰米




使用道具 举报 回复
发表于 2019-7-26 11:11:03
一. 我们测试了经典蓝牙通讯,没有出现接收不全的现象,本身是通过getInputStream接收,设置的最大单次接收值是1024byte
二. 请需要确认以下几点:
   1. 蓝牙设备购买时有没有demo,是否是正常使用通讯.
   2. PC-1 发送数据包给蓝牙的数据是否有可能本身是分段的.
三. BLE蓝牙通讯功能测试是正常使用的
使用道具 举报 回复 支持 反对
发表于 2019-7-27 16:51:57
本帖最后由 bigjimmy8257 于 2019-7-29 09:57 编辑
neil 发表于 2019-7-26 11:11
一. 我们测试了经典蓝牙通讯,没有出现接收不全的现象,本身是通过getInputStream接收,设置的最大单次接收值 ...

Neil,

多谢您的回复。我下载了‘蓝牙串口’APP, 通过它测试蓝牙设备的时候,能够无误的接收从PC上发出的数据包,没有任何丢包的现象(不过我无法确定它是如何实现的,是一次接收,还是多次接收 PC发出的单个数据包)通过APP发出的数据包也可以完整的在PC上接收。这说明蓝牙设备本身是没有问题的,而且看起来PC发出的时间也是一次性的到达蓝牙设备的,因为我在PC上是以1ms的频率连续发送数据的,在这种情况下, APP 也能够正确的接收。

我想继续了解一下,您所说的单次最大接收值是1024byte, 是说如果收到的包小于这个大小,就会一次性接收而不会将数据包进行拆分吗?我在调试时发生的情况似乎不是这样,但是从和上面 蓝牙串口 的对调过程看,好像也不是蓝牙设备的问题,您可以在帮助分析一下其中的可能性吗?+
+
补充一下,在我单步调试的时候,从SMOBILER 手机APP发出一个16byte的数据包时,PC上可以一次收到。但PC上回送一个16byte的数据包时,从单步调试中看到,在触发
bluetooth1_DataReceived 事件中后 第一时间 查看 e.Data, 我从没遇到收到对方发来的全部byte的情况,绝大多数时候只能得到对方发来的第一个byte。
请问您这边测试的时候,是达到的数据包通过DataReceived事件一次接收完成吗,还是分成若干次触发完成? 这个会不会与SMOBILER 的 服务器+客户端运行机制有关呢?


谢谢
大杰米





本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
使用道具 举报 回复 支持 反对
发表于 2019-7-29 13:20:48
这边测试的蓝牙通讯设备没有发生分段情况.
基于你的问题,这边尝试了在客户端增加一个缓存时间,然后获取蓝牙信息. 可在官网下载Smobiler内测版本测试. (蓝牙插件版本2.0.2)
使用道具 举报 回复 支持 反对
发表于 2019-7-31 18:16:08
本帖最后由 bigjimmy8257 于 2019-7-31 18:19 编辑
neil 发表于 2019-7-29 13:20
这边测试的蓝牙通讯设备没有发生分段情况.
基于你的问题,这边尝试了在客户端增加一个缓存时间,然后获取蓝牙 ...

Neil, 首先非常感谢SMobiler团队能专门做一个内测版本,对我的问题进行更新。感觉自己好受重视啊

我下载了您说的内侧版本进行了测试。感觉上效果基本上和现有的稳定版本相当。我自己分析一下,在我的测试环境中,数据是从串口送出然后通过蓝牙透明传输送到接收端(手机)的。串口的波特率是9600,即1秒钟发送9600个字节,即每字节的发送时间大概是 1/9600 = 0.1ms 的样子,我的测试数据是16字节,因此大概需要1.6ms来收到这16个字节。

我不确定您说的在客户端增加的缓冲时间是指什么,是否是指从DataReceived 事件被触发,到开始读取数据的缓冲区之间的时间?如果是的话,现在的这个延迟设置的是多少?

我个人有两个小的想法,一个是可不可以将上面这个换成时间作为蓝牙插件的公有属性,这样可以根据实际需求进行调整,第二是否可以将蓝牙插件的内部数据接收缓冲区做成公有属性,这样可以跳过接收时间,而直接对该缓冲区进行访问,然后可以在子线程中循环监测其中的数据。请评估。
另外,刚刚想起来,问一下,使用内测版本后,原有程序中之前拖入的蓝牙插件可以直接使用吗,还是需要重新再拖入一次? 我现在用的还是以前的。不知道会不会有问题。另外
如果蓝牙插件升级了,之前购买的蓝牙插件会自动更新吗?我购买了稳定版本的蓝牙插件来做生产环境中的测试。

谢谢
大杰米
使用道具 举报 回复 支持 反对
发表于 2019-8-1 16:17:52
本帖最后由 neil 于 2019-8-1 16:28 编辑
bigjimmy8257 发表于 2019-7-31 18:16
Neil, 首先非常感谢SMobiler团队能专门做一个内测版本,对我的问题进行更新。感觉自己好受重视啊

我下 ...

1. 请确认下载的版本是官网内测版本,其中缓存时间为100ms,即从收到蓝牙信息状态到获取蓝牙信息,会有100ms的缓存. 按你的说法,16byte肯定能接受完整的.现在还是会出现多段的情况吗?
2. 购买的蓝牙插件,可下载打包插件的所有版本,新发布的版本也是可以直接打包的,不用重新购买.



本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
使用道具 举报 回复 支持 反对
发表于 2019-8-1 20:58:14
neil 发表于 2019-8-1 16:17
1. 请确认下载的版本是官网内测版本,其中缓存时间为100ms,即从收到蓝牙信息状态到获取蓝牙信息,会有100ms ...

哦哦, 我以为是要下载Designer的内测版本。。这个我再重新试一下。

多谢多谢
大杰米
使用道具 举报 回复 支持 反对
发表于 2019-8-6 09:38:25
好的
使用道具 举报 回复
发表于 2019-8-8 11:32:02
本帖最后由 bigjimmy8257 于 2019-8-8 14:18 编辑

Neil 您好,

最近有点私事处理,没能及时回复,请见谅,这里我把我的测试情况给您总结一下,总体来说这个测试版本的效果不如之前。

我使用的环境如下:
环境1:    VS2017 社区版 +  Smobiler Designer 470.1548307665  + Smobiler Android Client 4.7 (因为4.8 的 Numeric 控件的bug问题,我没有使用4.8 的正式版,不过我也用4.8的正式版做过测试,和4.7相当)

环境2:  VS2017 社区版 +  Smobiler Designer 内测版 480.1557982701 + Smobiler Android Client 内测版 v4.8.0.12

蓝牙模块 DX BT-18 蓝牙双模串口透传无线模块,使用的是它的经典蓝牙模式(未测试BLE模式)
串口参数设置 : BAND: 9600, 校验位:None, 数据位:8, 停止位:1

蓝牙测试APP:  ‘蓝牙串口’(前面的帖子内容中有图片)

我刚刚修改了我发的帖子,因为似乎我找到了问题原因,请看下面的跟帖

另外,内测版还有一个问题,一旦通过bluetooth.Connect()方法连接成功一次,在SMobiler APP的环境下,即使后来通过bluetooth.Close() 方法关闭了连接, 下一次再用bluetooth.Connect()方法的时候,会报错,说蓝牙已经连接,需要关闭后再连。 这种情况下,只能将Smobiler APP 退出再重新打开,才能重新连接。

谢谢
大杰米。
使用道具 举报 回复 支持 反对
发表于 2019-8-8 11:35:57
本帖最后由 bigjimmy8257 于 2019-8-8 14:29 编辑
bigjimmy8257 发表于 2019-8-8 11:32
Neil 您好,

最近有点私事处理,没能及时回复,请见谅,这里我把我的测试情况给您总结一下,总体来说这 ...

Neil,您好,
我刚刚发现了一个现象,如果是传输ASCII码 为 0x1 - 0x7F 的数据,那么接收是完全没有问题的,比如下面:

发送方:
            byte[] WriteBuffer = new byte[80] { 0x7F, 0x1, 0x2, 0x9, 0x8, 0xF, 0x7e, 59 };
            ComPort.Write(WriteBuffer, 0, WriteBuffer.Length);

接收方:
            buffer = new byte[e.Data.Length];
            e.Data.CopyTo(buffer, 0);
            
在接收方打断点,可以看到数据一次性接收到e.Data 中

如果 传送的数据中有 0x0, 0x80-0xFF 的字节数据,DataReceived 会中断,并且设置 e.Data = 0x0, e.Data.Length = 0,  这个会导致数据接收的错误。

我使用 ‘蓝牙串口’工具进行了测试,它可以正常的接收这些字节数据。

因为在二进制数据传输的时候,上述0, 0x80 -0xFF 的数据是很正常的数据,希望开发团队能修复这个可能的bug ?

大杰米。


使用道具 举报 回复 支持 反对
发新帖
您需要登录后才可以回帖 登录 | 立即注册