Bluetooth LE — множественное характерное поведение

Я написал приложение Kotlin Compose Coroutine SharedFlow, которое подключает мой телефон к сенсорному устройству с поддержкой BLE. Приложение демонстрирует странное поведение. Если я просто подключаюсь к устройству, значение напряжения от датчика правильно считывается и отображается на моем одном экране. Однако мое устройство уведомляет две характеристики, а именно ampsValue. Значение ampsValue не читается для каждого логарифма и не отображается на моем экране. Обнаружен UUID характеристики усилителя, но не значение характеристики усилителя.

Если я поменяю характерные UUID вольт и ампер соответственно, ampsValue начнет уведомлять в logcat и отображаться на моем экране. Конечно, соответствующие показания датчиков отображаются в неправильных текстовых полях, но если я поменяю UUID обратно, то и вольты, и амперы будут отображаться правильно. Другая проблема возникает, когда я выключаю устройство и снова включаю его. Мое приложение повторно подключится, но снова будет отображать только значение voltsValue. Единственный способ заставить его читать/уведомлять оба значения — это поменять характерные UUID. Такое поведение кажется кому-нибудь знакомым? Обратите внимание, что nRF правильно считывает и отображает оба значения уведомления.

Это обратный вызов onServicesDiscovered(), в котором считываются UUID:

@SuppressLint("MissingPermission")
        override fun onServicesDiscovered(gatt: BluetoothGatt?, status: Int) {
            when (status) {
                BluetoothGatt.GATT_SUCCESS -> {
                    // Service discovery successful
                    val service = gatt?.getService(SERVICE_UUID)
                    if (service != null) {
                        // Read volts characteristic
                        val voltsCharacteristic =
                            service.getCharacteristic(VOLTS_UUID)
                        voltsCharacteristic?.let {
                            gatt.readCharacteristic(it)
                            Log.d("Frank - read voltsCharacteristic", "Volts Characteristic = $it")
                        } ?: run {
                            Log.e("Frank", "Volts characteristic not found")
                        }

                        // Read amps characteristic
                        val ampsCharacteristic = service.getCharacteristic(AMPS_UUID)
                        ampsCharacteristic?.let {
                            gatt.readCharacteristic(it)
                            Log.d("Frank - read ampsCharacteristic", "Amps Characteristic = $it")
                        } ?: run {
                            Log.e("Frank", "Amps characteristic not found")
                        }
                    } else {
                        Log.e("Frank", "Service not found")
                    }
                }

                else -> {
                    // Service discovery failed
                    Log.e("Frank", "Service discovery failed with status: $status")
                }
            }
0
0
56
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Одновременно у вас может быть только одна невыполненная операция GATT для каждого объекта BluetoothGatt. Пожалуйста, подождите, пока не получите обратный вызов onReadCharacteristic, пока не отправите следующий запрос (readCharacteristic).

Спасибо @Emil... Я пробовал некоторые методы организации очередей, но у меня недостаточно опыта, чтобы успешно их реализовать. В итоге я реализовал прокси для формальной настройки очереди, и теперь приложение работает как положено. Я предполагаю, что одного использования SharedFlow недостаточно, чтобы справиться с асинхронным характером операций BLE. Еще раз спасибо за ваш ответ.

FrankBLE 29.04.2024 01:59

Другие вопросы по теме