如何同时有效地读取两个 BLE 设备的温度?

How do I effectively read temperature from two BLE devices at the same time?

首先,我正在使用 RxAndroidBLE 库来管理我的 BLE 连接。

我有两个 SensorTag devices,我想同时读取两个的温度。例如,我想每 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 毫秒调用一次的可运行对象中。

我觉得这是一种极其低效的方法。有人可以告诉我是否有更好的方法吗?

我建议你启动两个线程。线程 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();

首先,您无法在 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
            );

希望对您有所帮助。

此致。