Не всегда отрабатывает onCharacteristicRead в android на изменения характеристик в arduino. В чём проблема? Коллеги, такая проблема:
Есть плата Curie Nano, есть телефон с android 5.0+. Взаимодействуют они через Bluetooth Low Energy.
По задумке Curie Nano должна периодически передавать на телефон 3 параметра (характеристики). Вот код который сейчас на плате:#include
BLEPeripheral blePeripheral;
BLEService uartService = BLEService("6e400001-b5a3-f393-e0a9-e50e24dcca9e");
BLECharacteristic temperatureInsideString = BLECharacteristic("6e400002-b5a3-f393-e0a9-e50e24dcca9e", BLENotify, 20); // температура одежды
BLECharacteristic temperatureOutsideString = BLECharacteristic("6e400003-b5a3-f393-e0a9-e50e24dcca9e", BLENotify, 20); // температура окружающей среды
BLECharacteristic batteryString = BLECharacteristic("6e400004-b5a3-f393-e0a9-e50e24dcca9e", BLENotify, 20); // от 0 до 100
long previousMillis = 0;
byte buff[20];
String tempInside;
String tempOutside;
String battery;
void setup () {
Serial.begin(9600);

blePeripheral.setLocalName("temperature");
blePeripheral.setAdvertisedServiceUuid(uartService.uuid());

blePeripheral.addAttribute(uartService);
blePeripheral.addAttribute(temperatureInsideString);
blePeripheral.addAttribute(temperatureOutsideString);
blePeripheral.addAttribute(batteryString);
blePeripheral.begin();
}
void loop () {
BLECentral central = blePeripheral.central();
if ( central ) {
while ( central.connected() ) {
long currentMillis = millis();
if ( currentMillis - previousMillis >= 3000 ) {
previousMillis = currentMillis;
updateTemperature();
}
}
}
}
void updateTemperature () {
tempInside = getInsideTemp();
tempInside.getBytes(buff, 20);
temperatureInsideString.setValue((unsigned char*)buff, 20);

tempOutside = getOutsideTemp();
tempOutside.getBytes(buff, 20);
temperatureOutsideString.setValue((unsigned char*)buff, 20);
battery = getBattery();
battery.getBytes(buff, 20);
batteryString.setValue((unsigned char*)buff, 20);
}
String getInsideTemp () {
return (String)36.6;
}
String getOutsideTemp () {
return (String)-20.0;
}
String getBattery () {
return (String)50;
}
Все характеристики успешно заполняются параметрами раз в 3 секунды, я выводил их на порт для проверки.
Со стороны андроид во время возникновения события onServicesDiscovered я проставляю дескрипторы этим параметрам, для того чтобы ловились оповещения об их изменении. Под дебагом видно что дескрипторы проставляются успешно. Вот код:@Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
if (status == BluetoothGatt.GATT_SUCCESS) {
BluetoothGattService service = gatt.getService(Constants.TEMP_SERVICE_UUID);
if (service != null) {
BluetoothGattCharacteristic characteristicInsideTemp = service.getCharacteristic(Constants.INSIDE_TEMP_UUID);
if (characteristicInsideTemp != null) {
setCharacteristicNotification(characteristicInsideTemp, true);
}
BluetoothGattCharacteristic characteristicOutsideTemp = service.getCharacteristic(Constants.OUTSIDE_TEMP_UUID);
if (characteristicOutsideTemp != null) {
setCharacteristicNotification(characteristicOutsideTemp, true);
}
BluetoothGattCharacteristic characteristicBattery = service.getCharacteristic(Constants.BATTERY_UUID);
if (characteristicBattery != null) {
setCharacteristicNotification(characteristicBattery, true);
}
}
} else {
Log.w(TAG, "onServicesDiscovered received: " + status);
}
}
public void setCharacteristicNotification(BluetoothGattCharacteristic characteristic,
boolean enabled) {
if (mBluetoothAdapter == null || mBluetoothGatt == null) {
Log.w(TAG, "BluetoothAdapter not initialized");
return;
}
mBluetoothGatt.setCharacteristicNotification(characteristic, enabled);
if (enabled) {
for (BluetoothGattDescriptor descriptor : characteristic.getDescriptors()) {
descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
mBluetoothGatt.writeDescriptor(descriptor);
}
}
}
После выполнения этого кода раз в 3 секунды отрабатывает калбек onCharacteristicRead, но туда приходит только 1 характеристика с UUID = 6e400002-b5a3-f393-e0a9-e50e24dcca9e, по остальным характеристикам не приходит ничего.
На плате пробовал отправлять разные характеристики по очереди с интервалом в 3 секунды, на андройде результат абсолютно не изменился.
В чём может быть проблема?

21 Авг 2019 в 06:29
202 +1
0
Ответы
1

Проблема может быть связана с тем, что в вашем коде на устройстве Curie Nano вы вызываете функцию setValue для всех трех характеристик одновременно в методе updateTemperature(). Это может привести к тому, что Bluetooth стек на устройстве не успевает обработать все три характеристики одновременно и происходит конфликт.

Попробуйте изменить свой код на устройстве Curie Nano так, чтобы вы устанавливали значение для каждой характеристики по отдельности, с интервалом в несколько миллисекунд, чтобы дать Bluetooth стеку возможность обработать каждую характеристику отдельно.

Также убедитесь, что у вас есть обработчики для всех трех характеристик на устройстве Android и что дескрипторы устанавливаются корректно для каждой характеристики.

Если после этих изменений проблема останется, попробуйте также проверить логи на устройстве Android и устройстве Curie Nano, чтобы увидеть какие именно пакеты данных отправляются и принимаются.

20 Апр в 13:17
Не можешь разобраться в этой теме?
Обратись за помощью к экспертам
Название заказа не должно быть пустым
Введите email
Бесплатные доработки
Гарантированные бесплатные доработки
Быстрое выполнение
Быстрое выполнение от 2 часов
Проверка работы
Проверка работы на плагиат
Интересные статьи из справочника
Поможем написать учебную работу
Название заказа не должно быть пустым
Введите email
Доверьте свою работу экспертам
Разместите заказ
Наша система отправит ваш заказ на оценку 94 757 авторам
Первые отклики появятся уже в течение 10 минут
Прямой эфир