3

I'm using BLE application on an Android phone communicating with a custom BLE sensor board. There are two characteristics provided by the board, acceleration and ecg. On the phone side, I'd like to receive the notifications of two characteristics from the sensor board. My code to set notifications:

mGatt.setCharacteristicNotification(ecgChar, true);
            BluetoothGattDescriptor descriptor = ecgChar.getDescriptor(
                    UUID.fromString("00002902-0000-1000-8000-00805f9b34fb"));
            descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
            mGatt.writeDescriptor(descriptor);
            mGatt.setCharacteristicNotification(accelChar, true);
            descriptor = ecgChar.getDescriptor(
                    UUID.fromString("00002902-0000-1000-8000-00805f9b34fb"));
            descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
            mGatt.writeDescriptor(descriptor);

However, I can only receive notifications for the first characteristics. When I only register notification for one characteristic, it worked well. The sampling frequency is 100Hz for both ECG and acceleration. So how can I receive notifications from both characteristics? Thanks.

Sentimental
  • 187
  • 2
  • 13

2 Answers2

11

You can only have one outstanding gatt operation at a time. In this case you do two writeDescriptor calls before waiting until the first has completed. You must wait for https://developer.android.com/reference/android/bluetooth/BluetoothGattCallback.html#onDescriptorWrite(android.bluetooth.BluetoothGatt, android.bluetooth.BluetoothGattDescriptor, int) until you can send the next one.

Emil
  • 16,784
  • 2
  • 41
  • 52
  • In fact, I know the gatt operation is serialized, so I had tried to add delay between two writes but didn't work. Now I use callbacks to handle serialization, which is the correct way, and it works well! Thanks! – Sentimental Feb 09 '17 at 04:12
  • Thanks you saved my life. There is no information regarding this. – Haroun Hajem Dec 04 '18 at 12:30
2

I agree with Emil answer. When you have write descriptor for first characteristic:

boolen isSucsess = mGatt.writeDescriptor(descriptor);

You should wait callback for this first characteristic from:

onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) - method of BluetoothGattCallback.

Only after that you are should go to next characteristic and its descriptor processing.

As example you are able to extend BluetoothGattDescriptor and run next characteristic and its descriptor processing in method

onDescriptorWrite(...) { ... here ...}.

As well be informed that sometimes you should set notification for all characteristics and after that write its descriptors. I have met this in my practice with weight scale device. To get the weight I need to set notification for battery, for time, for weight, after that to write descriptor for all characteristics (waiting callbacks for everyone)).

For clear code you've better work with multitrading.

Best, StaSer.

  • I have followed same strategy still I'm not getting value for both characteristics. I'm writing first descriptor after getting value from that descriptor, then writing second descriptor. Can you suggest any solution. – YBDevi Mar 12 '20 at 05:25