使用多个 BLE 外设连接处理 Android 上的通知
Handling Notifications on Android with Multiple BLE Peripheral Connections
所以,我是 Android 开发的新手,我正在尝试将我的设备连接到多个 BLE 设备 (T-Wristband) 以接收频繁的通知(IMU 传感器数据少于 20 个字节 50Hz).
当连接到多个设备时,我丢失一个或多个设备的数据。我怀疑原因是我的 BluetoothGattCallback
方法 onCharacteristicChanged
在所有设备的同一个线程上工作(注意: 我已经通过记录 Thread.currentThread.getName()
).
我尝试过的:
1. Android 4.3: How to connect to multiple Bluetooth Low Energy devices
I suspect everyone adding delays is just allowing the BLE system to complete the action you have asked before you submit another one.
问题:我无法在接收通知时添加延迟,因为这会干扰我的采样率,而且我不确定何时可以从另一台设备收到新通知,甚至相同的设备。
2。
To achieve multiple BLE connections you have to store multiple BluetoothGatt
objects and use those objects for a different device
.
在这方面:我已经尝试为我的设备TTGODevice
编写自定义class,它保存了相应[=17的实例=] 连接后:
public class TTGODevice {
/* Bunch of psf constants */
private BluetoothDevice device;
private Context context;
private Accelerometer acc;
private BluetoothGatt server;
private int deviceStatus;
private final BluetoothGattCallback bluetoothGattCallback = new BluetoothGattCallback() { ...
};
public TTGODevice(Context context, BluetoothDevice device) {
this.device = device;
this.context = context;
this.acc = new Accelerometer(); // My custom class for accelerometer on the T-Wristband device(s)
}
public void connect(boolean autoConnect) {
server = device.connectGatt(context, false, bluetoothGattCallback);
}
/*Getters for device, server, and deviceStatus*/
}
在 BluetoothGattCallback
中,我重写了我的 onCharacteristicChanged
,如下所示:
@Override
public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
byte[] bytes = characteristic.getValue();
// updating the Accelerometer
acc.update(bytes);
Log.d(TAG, "onCharacteristicChanged: " + Thread.currentThread().getName());
}
我也试过在上面的回调中使用我的 server
的确切实例,但我运气不好。
byte[] bytes = server.getService(SERVICE_UUID).getCharacteristic(CHARACTERISTIC_UUID).getValue();
长话短说,我一直没有成功。我将不胜感激任何其他相关话题。
[注:有人建议我使用Fragments
and/orViewModels
。我不确定它们之间的关系。]
Android 上的 BLE 似乎无法处理 50Hz 及更高的采样率。我不确定这是 BLE-related 问题还是与 onCharacteristicCHanged
方法调用过于频繁有关。我通过每 50 毫秒 发送更大的数据包来解决这个问题,这与我每 20 毫秒 的原始情况相反。从 Bluetooth 4.2 开始,可以使用更大的 BLE 数据包,它使用 MTU、最大吞吐量单位[=31= 进行控制]. This blog 对我理解底层机制有很大帮助。
当通过 BLE 以高采样率接收大数据包时,最好在 Android 上相应的 BluetoothGattCallback
中使用 gatt.requestMtu(MY_DESIRED_MTU)
和 MY_DESIRED_MTU > 20Bytes
。需要注意的是,更大的MTU意味着数据写入服务器设备的BLE特性需要更长的时间。
总之,我是用更大的数据包和更大的延迟来弥补采样率的限制。对于 T-Wristband 中 IMU 上 100Hz 的采样率,我使用 95 字节 的 MTU,由 Android 设备,50ms 延迟 T-Wristband 上的计时器。这允许我每 50ms.
接收五个连续的数据样本
所以,我是 Android 开发的新手,我正在尝试将我的设备连接到多个 BLE 设备 (T-Wristband) 以接收频繁的通知(IMU 传感器数据少于 20 个字节 50Hz).
当连接到多个设备时,我丢失一个或多个设备的数据。我怀疑原因是我的 BluetoothGattCallback
方法 onCharacteristicChanged
在所有设备的同一个线程上工作(注意: 我已经通过记录 Thread.currentThread.getName()
).
我尝试过的:
1. Android 4.3: How to connect to multiple Bluetooth Low Energy devices
I suspect everyone adding delays is just allowing the BLE system to complete the action you have asked before you submit another one.
问题:我无法在接收通知时添加延迟,因为这会干扰我的采样率,而且我不确定何时可以从另一台设备收到新通知,甚至相同的设备。
2。
To achieve multiple BLE connections you have to store multiple
BluetoothGatt
objects and use those objects for a differentdevice
.
在这方面:我已经尝试为我的设备TTGODevice
编写自定义class,它保存了相应[=17的实例=] 连接后:
public class TTGODevice {
/* Bunch of psf constants */
private BluetoothDevice device;
private Context context;
private Accelerometer acc;
private BluetoothGatt server;
private int deviceStatus;
private final BluetoothGattCallback bluetoothGattCallback = new BluetoothGattCallback() { ...
};
public TTGODevice(Context context, BluetoothDevice device) {
this.device = device;
this.context = context;
this.acc = new Accelerometer(); // My custom class for accelerometer on the T-Wristband device(s)
}
public void connect(boolean autoConnect) {
server = device.connectGatt(context, false, bluetoothGattCallback);
}
/*Getters for device, server, and deviceStatus*/
}
在 BluetoothGattCallback
中,我重写了我的 onCharacteristicChanged
,如下所示:
@Override
public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
byte[] bytes = characteristic.getValue();
// updating the Accelerometer
acc.update(bytes);
Log.d(TAG, "onCharacteristicChanged: " + Thread.currentThread().getName());
}
我也试过在上面的回调中使用我的 server
的确切实例,但我运气不好。
byte[] bytes = server.getService(SERVICE_UUID).getCharacteristic(CHARACTERISTIC_UUID).getValue();
长话短说,我一直没有成功。我将不胜感激任何其他相关话题。
[注:有人建议我使用Fragments
and/orViewModels
。我不确定它们之间的关系。]
Android 上的 BLE 似乎无法处理 50Hz 及更高的采样率。我不确定这是 BLE-related 问题还是与 onCharacteristicCHanged
方法调用过于频繁有关。我通过每 50 毫秒 发送更大的数据包来解决这个问题,这与我每 20 毫秒 的原始情况相反。从 Bluetooth 4.2 开始,可以使用更大的 BLE 数据包,它使用 MTU、最大吞吐量单位[=31= 进行控制]. This blog 对我理解底层机制有很大帮助。
当通过 BLE 以高采样率接收大数据包时,最好在 Android 上相应的 BluetoothGattCallback
中使用 gatt.requestMtu(MY_DESIRED_MTU)
和 MY_DESIRED_MTU > 20Bytes
。需要注意的是,更大的MTU意味着数据写入服务器设备的BLE特性需要更长的时间。
总之,我是用更大的数据包和更大的延迟来弥补采样率的限制。对于 T-Wristband 中 IMU 上 100Hz 的采样率,我使用 95 字节 的 MTU,由 Android 设备,50ms 延迟 T-Wristband 上的计时器。这允许我每 50ms.
接收五个连续的数据样本