如何使用队列为Android中的BLE快速稳定地写出特征

时间:2018-04-12 08:18:03

标签: java android bluetooth-lowenergy gatt

在google ble应用程序之后,我在Android应用程序上创建了两个游戏杆。然后,我使用1个写入特性将操纵杆值从android手机发送到arduino over ble,数据包大小为4个字节。

当我从手机屏幕上抬起手指时。最后一个数据包将包含一个停止信号,但在我的arduino端,我无法在100%的时间内收到最后一个数据包。

我遇到this post并找到this source来构建队列以确保数据通过。

实现队列后,我可以使用logcat查看正在使用的队列。但是,在实现队列后,我仍然无法100%收到停止信号。

我认为这是因为当在最后一个数据包上调用writeCustomCharacteristic(packets,writecharacteristic_uuid)时,写操作仍然在忙着写,因此,它没有事件发送我的最后一个数据包

以下是我的代码:

   private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
    @Override
    public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
        Log.d("onCharacteristicWrite", "reach onCharacteristicWrite +++++++++++++");
        isWriting = false;
    }

                          .
                          .
                          .


            public void writeCustomCharacteristic(int value, String uuid_char) {
            if (mBluetoothAdapter == null || mBluetoothGatt == null) {
                Log.w(TAG, "BluetoothAdapter not initialized");
                return;
            }


        /*check if the service is available on the device*/
            BluetoothGattService mCustomService = mBluetoothGatt.getService(UUID.fromString(SampleGattAttributes.HEART_RATE_MEASUREMENT));
            if (mCustomService == null) {
                Log.w(TAG, "Custom BLE Service not found");
                return;
            }

              writeValue(value, uuid_char, mCustomService);

                   /*get the read characteristic from the service*/
    //        BluetoothGattCharacteristic mWriteCharacteristic = mCustomService.getCharacteristic(UUID.fromString(uuid_char));
    //        mWriteCharacteristic.setValue(value, android.bluetooth.BluetoothGattCharacteristic.FORMAT_UINT16, 0);
    //        Log.d("CONNECT", "reached writeCustomCharacteristic");
    //        if (mBluetoothGatt.writeCharacteristic(mWriteCharacteristic) == false) {
    //            Log.w(TAG, "Failed to write characteristic");
    //        }
        }

        public void writeValue(int dataInt, String uuid_char, BluetoothGattService mCustomService) {

            writeQueue.addFirst(dataInt);
            //Log.d("WriteQueue", "--------------write queue size: " + Integer.toHexString(writeQueue.peekFirst()));
            writeNextValueFromQueue(mCustomService, uuid_char);

        }

        public void writeNextValueFromQueue(BluetoothGattService mCustomService,String uuid_char) {

            if(isWriting) {
    //            if( (writeQueue.peekFirst() & LEFT_MOTOR_STOP_BIT_MASK ) != (1 << JoyStickActivity.LEFT_MOTOR_STOP_SIGNAL_MASK)) {
    //                return;
    //            }
                Log.d("isWritingFromQueue", "reach is writing equal to ture -----------> " + Integer.toHexString(writeQueue.peekFirst()));
                for(int s : writeQueue) {
                    System.out.println(Integer.toHexString(s));
                    Log.d("isWritingFromQueue",  Integer.toHexString(s));
                }
                return;
            }
            if(writeQueue.size() == 0) {
                Log.d("writeNextValueFromQueue", "reach queue size is zero --------------------");
                return;
            }
            isWriting = true;
            value = writeQueue.pollFirst();
            Log.d("writeNextValueFromQueue", "++++++++++++++++value: " + Integer.toHexString(value));

            /*get the read characteristic from the service*/
            BluetoothGattCharacteristic mWriteCharacteristic = mCustomService.getCharacteristic(UUID.fromString(uuid_char));
            mWriteCharacteristic.setValue(value,android.bluetooth.BluetoothGattCharacteristic.FORMAT_UINT32,0);
            Log.d("CONNECT", "reached writeCustomCharacteristic");
            if(mBluetoothGatt.writeCharacteristic(mWriteCharacteristic) == false){
                Log.w(TAG, "Failed to write characteristic");
            }
        }
  }

更新 我在writeNextValueFromQueue()函数中添加了一个while语句,现在它捕获了当我收到带有停止信号的数据包时,我使用while循环等待onCharacteristicWrite()完成,然后发送我的最后一个数据包。这样我确保每次都发送最后一个数据包,但是,它会延迟电机停止几百毫秒的时间。

有没有办法,我可以在收到停止信号时丢弃我发送的数据包而不是等待数据包完成发送,然后发送包含我的停止信号的数据包?

public void writeNextValueFromQueue(BluetoothGattService mCustomService,String uuid_char) {

    if(isWriting) {
        if( (writeQueue.peekFirst() & LEFT_MOTOR_STOP_BIT_MASK ) != (1 << JoyStickActivity.LEFT_MOTOR_STOP_SIGNAL_MASK)) {
            return;
        }
        while(isWriting) {

        }
        Log.d("isWritingFromQueue", "reach is writing equal to ture -----------> " + Integer.toHexString(writeQueue.peekFirst()));
        for(int s : writeQueue) {
            System.out.println(Integer.toHexString(s));
            Log.d("isWritingFromQueue",  Integer.toHexString(s));
        }
       // return;
    }
    if(writeQueue.size() == 0) {
        Log.d("writeNextValueFromQueue", "reach queue size is zero --------------------");
        return;
    }
    isWriting = true;
    value = writeQueue.pollFirst();
    Log.d("writeNextValueFromQueue", "++++++++++++++++value: " + Integer.toHexString(value));

    /*get the read characteristic from the service*/
    BluetoothGattCharacteristic mWriteCharacteristic = mCustomService.getCharacteristic(UUID.fromString(uuid_char));
    mWriteCharacteristic.setValue(value,android.bluetooth.BluetoothGattCharacteristic.FORMAT_UINT32,0);
    Log.d("CONNECT", "reached writeCustomCharacteristic");
    if(mBluetoothGatt.writeCharacteristic(mWriteCharacteristic) == false){
        Log.w(TAG, "Failed to write characteristic");
    }
}

更新更新: 由于添加while语句导致我的应用程序滞后,我试图找出一个不同的解决方案。按照Emil的建议,我开始在onCharacteristicWrite()回调中打印出来。显示在下面的代码中:

               public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
        final StringBuilder stringBuilder;
       // Log.d("onCharacteristicWrite", "reach onCharacteristicWrite +++++++++++++");
        if(status == BluetoothGatt.GATT_SUCCESS){
            final byte[] data = characteristic.getValue();
            if (data != null && data.length > 0) {
                 stringBuilder = new StringBuilder(data.length);
                for (byte byteChar : data)
                    stringBuilder.append(String.format("%02X ", byteChar));
                Log.d("onCharacteristicSuccess", "Value is " +stringBuilder.toString() );
            }


        }
        isWriting = false;
    }

以下是成功发送停止信号的log cat:

    04-22 21:21:36.242 11242-11255/com.example.android.toybot D/onCharacteristicSuccess: Value is 00 00 80 FF 
04-22 21:21:36.392 11242-11254/com.example.android.toybot D/onCharacteristicSuccess: Value is 00 00 80 FF 
04-22 21:21:36.544 11242-11254/com.example.android.toybot D/onCharacteristicSuccess: Value is 00 00 80 FF 
04-22 21:21:36.694 11242-11255/com.example.android.toybot D/onCharacteristicSuccess: Value is 00 00 80 FF 
04-22 21:21:36.843 11242-11254/com.example.android.toybot D/onCharacteristicSuccess: Value is 00 00 80 FF 
04-22 21:21:36.993 11242-11254/com.example.android.toybot D/onCharacteristicSuccess: Value is 00 00 80 FF 
04-22 21:21:37.143 11242-11284/com.example.android.toybot D/onCharacteristicSuccess: Value is 00 00 80 FF 
04-22 21:21:37.292 11242-11255/com.example.android.toybot D/onCharacteristicSuccess: Value is 00 00 80 FF 
04-22 21:21:37.442 11242-11284/com.example.android.toybot D/onCharacteristicSuccess: Value is 00 00 80 FF 
04-22 21:21:38.947 11242-11284/com.example.android.toybot D/onCharacteristicSuccess: Value is 00 00 C0 00 

如您所见,最后一个数据包包含C0,这是一个停止信号。但是,大部分时间都没有收到此信号。

0 个答案:

没有答案