分享

[解决方法]安卓与蓝牙模块HM05,HM06数据接收不完全的一种解决方法

 ada_lib 2015-01-11

一开始用的蓝牙模块HM10,是蓝牙4.0的,可以和我的魅族MX2配对成功,但是却不能连接上,最后没办法,换成了蓝牙2.0,HM05 HM06,这两个模块都可以通信成功,但是,这个时候问题又出现了,数据不能按我发送的帧接收,比如我发送6个字符,但是接收的时候要么是先接收1个字符,再接收5个字符,或者先3个后3个,总之,很少可以完整的接收一帧的。

关键是里面还有错误的数据。所以最后就算是定了帧头帧尾还是会丢数据,之前的上位机上也会出现丢数据的现象,但是是因为UI线程阻塞照成的,加一个处理数据的线程就可以了。但是这次加了还是不行,所以我也不知道怎么处理丢数据的问题,这个只能保证数据不出错。所以不能接收那些连续的波形数据或者图片数据。如果有谁能提供一个更好的解决方法,请告诉一句。


还准备偷懒一下的,但是没办法,看来还是得定义包头和包尾和帧长度了,因为以前用C#开发过串口的上位机的,所以基本的实现肯定是没有问题的。

这个是改于官方的例程,BluetoothChat的,这个是ConnectedThread线程中的经过我改过之后的run() 函数。

        @Override
public void run() {
            Log.i(TAG,DEBUG_NAME+ "BEGIN mConnectedThread");
            byte[] buffer = new byte[1024];
            int bytes;


            // Keep listening to the InputStream while connected
            while (true) {
                try {
                    // Read from the InputStream
                //如果没有在输入流中没有数据,将会阻塞线程
                    bytes = mmInStream.read(buffer);
                    if(isReceiveByteData==false){
                        // Send the obtained bytes to the UI Activity
                        mHandler.obtainMessage(MESSAGE_READ, bytes, -1, buffer)
                                .sendToTarget();
                    }
                    else{
                    for(int i=0;i<bytes;i++){
                    receiveBuffer.offer(buffer[i]);
                    }
                    }
                } catch (IOException e) {
                    Log.e(TAG,DEBUG_NAME+ "disconnected", e);
                    connectionLost();
                    break;
                }
            }

        }

定义两个全局变量

    private boolean isReceiveByteData = false;
    private BlockingQueue<Byte> receiveBuffer = new ArrayBlockingQueue<Byte>(1024);

BlockingQueue是一个阻塞队列,用来建立一个1024字节大小的数据缓冲区,

isReceiveByteData 是我自己定义的一个标志位,就是来定义数据是否是流数据的,如果不是,那我就直接显示,如果是就将接收到的数据插入到队列中去。

大家可以不需要这个标志位,因为我只是想改动小一点,通过主Activity中设置这个标志位来确定接收数据模式而已。

接下来在主Activity中建立一个线程。

private class ReceiveThread extends Thread{
private BlockingQueue<Byte> receiveBuffer = null;
byte start1,start2,end1,end2;
byte[] data = new byte[data_legth];
boolean isDataNoError = true; 
@Override
public void run() {
while(isReceiveThreadOn){
try{
receiveBuffer = mChatService.getReceiveBuffer();
while(start1!=start1_byte||start2!=start2_byte){
start1 = start2;
start2 = receiveBuffer.take();
}
for(int i=0; i<data_legth;i++){
data[i] = receiveBuffer.take();
if((data[i]<'0'||data[i]>'9')&&data[i]!='.'&&data[i]!='-'){
isDataNoError = false;
break;
}
}
if(isDataNoError==true){
end1 = receiveBuffer.take();
end2 = receiveBuffer.take();
if(end1==end1_byte&&end2==end2_byte){
                       // Send the obtained bytes to the UI Activity
                       mHandler.obtainMessage(DRAW_GRAPH, -1, -1, new String(data, 0, data_legth))
                               .sendToTarget();
}
}
isDataNoError = true;
start1=0;start2=0;
}
catch(InterruptedException e){
                    Log.e(TAG,DEBUG_NAME+ "数据处理失败", e);
}



}
super.run();
}
}

里面详细的实现过程,大家可以研究研究,就是判断数据是否正确的,然后如果是正确的话,将数据通过Handler传数据到Activity中显示mHandler.obtainMessage(DRAW_GRAPH, -1, -1, new String(data, 0, data_legth)).sendToTarget();

然后自己定义的一些信息

    private boolean isReceiveThreadOn = true;//接收流数据
    private int data_legth = 5;//数据长度5
    private byte start1_byte = '#';//帧头第一个字节为#
    private byte start2_byte = 'S';//帧头第一个字节为S
    private byte end1_byte = 'E';//帧尾第一个字节为E
    private byte end2_byte = '$';//帧尾第一个字节为$
    private ReceiveThread mReceiveThread;
    private static final int DRAW_GRAPH = 6;


最后接收数据的效果就是


表面上貌似没丢数据,但是应还是会丢一点点,但是这样基本的数据传输应该是没问题的,发送间隔定为10ms都可以接收。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多