0

Its taking too long to write a single command on characteristics. I am using below code for a single command and a loop on it.

getConnObservable()
  .first()
  .flatMap(rxBleConnection -> rxBleConnection.writeCharacteristic(characteristics, command))
  .observeOn(AndroidSchedulers.mainThread())
  .subscribe(
    bytes -> onWriteSuccess(),
    this::onWriteFailure
  );

Its taking almost 600ms to write on device. I need to write like 100 of commands 1 by 1.

Can anyone please explain what is the best way to do that batch operation

Dariusz Seweryn
  • 3,212
  • 2
  • 14
  • 21
Usman Afzal
  • 558
  • 1
  • 6
  • 13
  • Do you have any constraints? – Dariusz Seweryn Jan 08 '18 at 10:37
  • Its taking too long for this process I have seen another app using this library takes just 4 second for that batch operation of 100 of commands. https://github.com/MacroYau/Blue2Serial – Usman Afzal Jan 08 '18 at 11:30
  • The speed is dependent on many factors: 1. connection interval 2. supported number of commands for a single connection event for each of devices 3. peripheral supporting write without response 4. amount of radio traffic nearby. etc. – Dariusz Seweryn Jan 08 '18 at 11:39
  • Do you know the commands beforehand? – Dariusz Seweryn Jan 08 '18 at 11:43
  • @DariuszSeweryn same communication with same hardware with above library takes only 4sec. Mostly commands are like onCharacteristic(mControlCharacteristics, new byte[]{0x02, 0x07, 0x01}); – Usman Afzal Jan 08 '18 at 11:46
  • The above library uses `BluetoothSocket`s which are from standard Bluetooth. The `RxAndroidBle` is library for Bluetooth Low Energy. The peripheral you are talking to seems to be a dual mode one. If this is the case you will not get the same performance over BLE. – Dariusz Seweryn Jan 08 '18 at 11:54

1 Answers1

0

The best way to get the highest performance possible over BLE is to use the same RxBleConnection to carry out all writes—this means to mitigate the overhead of RxJava i.e.:

getConnObservable()
  .first()
  .flatMapCompletable(rxBleConnection -> Completable.merge(
    rxBleConnection.writeCharacteristic(characteristics, command0)).toCompletable(),
    rxBleConnection.writeCharacteristic(characteristics, command1)).toCompletable(),
    (...)
    rxBleConnection.writeCharacteristic(characteristics, command99)).toCompletable(),
  ))
  .observeOn(AndroidSchedulers.mainThread())
  .subscribe(
    this::onWriteSuccess,
    this::onWriteFailure
  );

Additionally one could try to negotiate the shortest possible Connection Interval (CI) by subscribing to rxBleConnection.requestConnectionPriority(BluetoothGatt.CONNECTION_PRIORITY_HIGH, delay, timeUnit)

Further speedup can be achieved by setting bluetoothGattCharacteristic.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE‌​_WITHOUT_RESPONSE) if the peripheral/characteristic supports this write type.*
*Be aware that the internal buffer for writes without response is limited and depending on the API level behaves a bit differently. It should not matter for ~100 writes though.

In regards to this conversation: RxAndroidBle is a Bluetooth Low Energy library and comparing it to Blue2Serial (which uses standard Bluetooth) in terms of performance is not the best thing to do. These have different use-cases—just like using a WiFi or Ethernet cable to get access to the Internet.

Best Regards

Dariusz Seweryn
  • 3,212
  • 2
  • 14
  • 21