Как эффективно считывать температуру с двух устройств BLE одновременно?
Прежде всего, я использую библиотеку RxAndroidBLE для управления моими BLE-соединениями.
У меня есть два устройства SensorTag, и я хочу считывать температуру с обоих одновременно. Например, я хотел бы считывать температуру с обоих устройств точно каждые 500 мс и отображать ее пользователю в двух TextView.
Мое приложение в настоящее время успешно подключается к обоим устройствам BLE следующим образом:
@OnClick(R.id.connectButton1)
public void connectFirstSensorTag(Button b) {
if (!isDeviceConnected(sensorTag1)) {
connectionObservable1 = sensorTag1.establishConnection(getApplicationContext(), false).compose(new ConnectionSharingAdapter());
}
connectionObservable1.subscribe(new Subscriber<RxBleConnection>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
updateStatus(statusTextView1, "SensorTag not found");
}
@Override
public void onNext(RxBleConnection rxBleConnection) {
updateStatus(statusTextView1, "Connected");
enableSensorTagTemperatureSensor(connectionObservable1);
}
});
}
@OnClick(R.id.connectButton2)
public void connectSecondSensorTag(Button b) {
if (!isDeviceConnected(sensorTag2)) {
connectionObservable2 = sensorTag2.establishConnection(getApplicationContext(), false).compose(new ConnectionSharingAdapter());
}
connectionObservable2.subscribe(new Subscriber<RxBleConnection>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
updateStatus(statusTextView2, "SensorTag not found");
}
@Override
public void onNext(RxBleConnection rxBleConnection) {
updateStatus(statusTextView2, "Connected");
enableSensorTagTemperatureSensor(connectionObservable2);
}
});
}
Теперь я ищу лучший способ считывать температуру одновременно с интервалом в 500 мс.
Прямо сейчас я делаю что-то вроде этого:
connectionObservable1
.flatMap(rxBleConnection -> rxBleConnection.readCharacteristic(uuidFromShortCode("AA01")))
.subscribe(bytes -> {
// first temperature was successfully read here
connectionObservable2
.flatMap(rxBleConnection -> rxBleConnection.readCharacteristic(uuidFromShortCode("AA01")))
.subscribe(bytes -> {
// second temperature was successfully read here
}, error -> {
updateStatus(error.toString());
});
}, error -> {
updateStatus(error.toString());
});
И этот блок кода находится внутри исполняемого файла, который вызывается каждые 500 мс.
Я чувствую, что это крайне неэффективный способ сделать это. Может кто-нибудь, пожалуйста, дайте мне знать, если есть лучший способ сделать это?
2 ответа
Прежде всего, вы не можете выполнять по-настоящему параллельное чтение или любые другие операции на BLE, поскольку у вас есть только одна радиостанция, и операции должны быть последовательными. Лучшее, что вы можете сделать, это уволить их как можно скорее один за другим. Используя RxAndroidBle, вы получаете управляемую сериализацию для вас.
Способ делать то, что вы хотите, я вижу так:
RxBleDevice sensorTag0 = // your first SensorTag
RxBleDevice sensorTag1 = // your second SensorTag
UUID characteristicUuid = uuidFromShortCode("AA01");
Subscription flowSubscription = Observable.combineLatest(
sensorTag0.establishConnection(this, false), // establishing connections
sensorTag1.establishConnection(this, false),
Pair::new // merging them together
)
.flatMap(connections -> Observable
.interval(500, TimeUnit.MILLISECONDS) // every 500 ms
.flatMap(aLong -> Observable.combineLatest(
connections.first.readCharacteristic(characteristicUuid), // performing reads
connections.second.readCharacteristic(characteristicUuid),
Pair::new // and merging the results
)))
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
readings -> {
updateUISensorTag0(readings.first); // updating the UI
updateUISensorTag1(readings.second);
},
throwable -> updateStatus(throwable.toString()) // or showing the error
);
Надеюсь, это поможет вам.
С уважением.
Я хотел бы предложить вам начать две темы. Поток 1 проверяет первое устройство, поток 2 проверяет второе. Это гарантирует, что оба читаются одновременно. Чтобы продолжить работу с кодом только после завершения обоих, я бы сделал блокирующий цикл соединения.
//Threads array has been created, with 0 checking the first
//device and 1 checking the second
for(i = 0; i < threads.length(); i++)
threads[i].join();