|
各位大神,求助啊。
最近一直在和 蓝牙模块 做斗争。问题不停的冒出来 。。。 现在遇到的问题是, 蓝牙插件的 DataReceived 事件接收到的数据时好时坏,而且是坏的时候居多。
我的环境场景如下:
- 一个 DX-BT18蓝牙双模模块,作为透明模式传输,并将蓝牙数据转成RS232的串口数据, 并通过串口转USB接口连接到PC-1
- PC-1 上运行一个自己写的 串口发送接收 的程序,通过串口,接收从蓝牙模块接收到的数据,并 发送数据到蓝牙模块。
- PC-2 上运行SMO 应用程序,在窗体上加载蓝牙插件,并通过该插件与外部的DX-BT18通信。
开始遇到的情况是:
当PC-1 发送数据包时,比如 byte[16] { 0x24, 1, 2, 0, 4, 5, 1,2,3,4,6,4,7,7,9, 90 } , 接收到的数据会触发 蓝牙插件的 DataReceived 事件,但不能确定是分几次接收。比如说一下的几种方式:
- 分2次接收,一次2个byte (0x24 和 1),第二次剩余的14个byte
- 分3次接收,一次1个byte(0x24, 第二次2个byte(1,2), 第三次剩余byte
- 其他的组合
上面的组合没有任何规律,不清楚其内在的逻辑是什么。由于我需要在不同的场合接收不同大小的数据包,为了能够做成通用的方式,我的做法如下:
1) 在开启蓝牙插件的接收事件前,在子线程中周期性(比如5ms) 扫描接收缓冲区中的数据长度 (byte[] Buffer.Length), 如果连续若干次(比如2次)扫描
到缓冲区中的数据长度未发生变化,则认为这次蓝牙的DataReceived事件已经接收完成了一个完整的数据包,于是将缓冲区中的数据复制到其他数组中进行处理,
并清空缓冲区,等待下一次的扫描。
2)在DataReceived事件中,代码只负责将接收到的数据(e.Data)添加到缓冲区的尾部,已提高DataReceived 的响应速度(之前DataReceived中的代码过多,怀疑因此导致在代码
尚未执行完成时就需要处理下一个数据的场景)
用上面的方式,可以正确的处理多个一个蓝牙数据包分多次触发DataReceived事件的问题,但前提时,数据包中的数据是正确的。
我现在发现几个问题. 一是发送端发出的数据包在DataReceived中被收到时丢失了某些数据,还以上面的数据为例,当这个16字节的数据包分成若干个数据包到达后,可能的数据是:
- 第一个包,2个byte (0x24,1)
- 第二个包,13个byte (0,4, 5, 1,2,3,4,6,4,7,7,9, 90)
原数据中的byte[2] 没有收到
这个只是个例子,丢失的数据可能在任何一个位置。
第二个问题是 byte 0 在单独被接收到的时候 ,其 e.Data.Length = 0, 而不是我想象中的1。 由于我接受的是二进制的数据,因此0值是一个正常的值。
我可以确定这个不是硬件的问题,理由是从蓝牙插件发出的数据,在PC-1的串口程序中可以正确的获取,而且是一次性获取,不会出现分包的情况(但是有个小问题,一个数据包发出后,
在PC-1上会收到两个包,永远如此,第一个包中包含所有数据,第二个包是个长度为0 的包,不知道怎么回事,但是我简单的把第二个长度为0的包丢弃掉就好了)
我想了解一下 蓝牙插件的DataReceived 内部是如何工作的,看是否能够找到有效的数据接收方法。 SMO的大神们,麻烦给一点指示。
之前大家有使用过蓝牙插件吗?是否也遇到类似的情况? 请分享一下您的经验?
谢谢
大杰米
|
|