2

I have been implementing the module to send the bytes in chunks, 20 bytes each onto the MCU device via BLE. When it comes to writing the bytes more than 60 bytes and so on, the last chunk of the bytes ( usually less than 20 bytes) is often missed. Hence, the MCU device cannot get the checksum and write the value. I have modified the call back to Thread.sleep(200) to change it but it sometimes works on writing 61 bytes or sometimes not. Would you please tell me are there any synchronous method to write the bytes in chunks ? The below is my working :

    @Override
    public void onCharacteristicWrite(BluetoothGatt gatt,
            BluetoothGattCharacteristic characteristic, int status) {

        try {
            Thread.sleep(300);
            if (status != BluetoothGatt.GATT_SUCCESS) {
                disconnect();
                return;
            }

            if(status == BluetoothGatt.GATT_SUCCESS) {
                System.out.println("ok");
                broadcastUpdate(ACTION_DATA_READ, mReadCharacteristic, status);
            }
            else {
                System.out.println("fail");
                broadcastUpdate(ACTION_DATA_WRITE, characteristic, status);
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }



public synchronized boolean writeCharacteristicData(BluetoothGattCharacteristic characteristic ,
        byte [] byteResult ) {
    if (mBluetoothAdapter == null || mBluetoothGatt == null) {
        return false;
    }
    boolean status = false;
    characteristic.setValue(byteResult); 
    characteristic.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE);

    status = mBluetoothGatt.writeCharacteristic(characteristic); 
    return status;

}

private void sendCommandData(final byte []  commandByte) {
        // TODO Auto-generated method stub

    if(commandByte.length > 20 ){
        final List<byte[]> bytestobeSent = splitInChunks(commandByte);
        for(int i = 0 ; i < bytestobeSent.size() ; i ++){
            for(int k = 0 ; k < bytestobeSent.get(i).length   ; k++){
                System.out.println("LumChar bytes : "+ bytestobeSent.get(i)[k] );
            }

            BluetoothGattService LumService = mBluetoothGatt.getService(A_SERVICE); 
            if (LumService == null) {  return; } 
            BluetoothGattCharacteristic LumChar = LumService.getCharacteristic(AW_CHARACTERISTIC);
            if (LumChar == null) {  System.out.println("LumChar"); return; } 
            //Thread.sleep(500);
            writeCharacteristicData(LumChar , bytestobeSent.get(i));
        }
    }else{

....

Jeff Bootsholz
  • 2,971
  • 15
  • 70
  • 141

1 Answers1

0

You need to wait for the onCharacteristicWrite() callback to be invoked before sending the next write. The typical solution is to make a job queue and pop a job off the queue for each callback you get to onCharacteristicWrite(), onCharacteristicRead(), etc.

In other words, you can't do it in a for loop unfortunately, unless you want to set up some kind of lock that waits for the callback before going on to the next iteration. In my experience a job queue is a cleaner general-purpose solution though.

Doug Koellmer
  • 407
  • 2
  • 8
  • I have set the thread sleep for dfferent types of command but nothing can work . – Jeff Bootsholz Nov 14 '14 at 02:15
  • I would not mess around with `Thread.sleep()` because of how variable the write time can be, especially under poor conditions like long range. Have you tried what I suggested? Waiting for the previous write to complete before performing the next write? – Doug Koellmer Nov 14 '14 at 14:42
  • That means using same global writeCharacteristics may overwrite the bytes to be sent , so we have to implement the writing part to be in queues ? How to use the BLocking queue to implement synchronous characteristics writing ? http://stackoverflow.com/questions/21791948/android-ble-gatt-characteristic-write-type-no-response-not-working – Jeff Bootsholz Nov 17 '14 at 03:43