Не всегда отрабатывает 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.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 секунды, на андройде результат абсолютно не изменился. В чём может быть проблема?
Проблема может быть связана с тем, что в вашем коде на устройстве Curie Nano вы вызываете функцию setValue для всех трех характеристик одновременно в методе updateTemperature(). Это может привести к тому, что Bluetooth стек на устройстве не успевает обработать все три характеристики одновременно и происходит конфликт.
Попробуйте изменить свой код на устройстве Curie Nano так, чтобы вы устанавливали значение для каждой характеристики по отдельности, с интервалом в несколько миллисекунд, чтобы дать Bluetooth стеку возможность обработать каждую характеристику отдельно.
Также убедитесь, что у вас есть обработчики для всех трех характеристик на устройстве Android и что дескрипторы устанавливаются корректно для каждой характеристики.
Если после этих изменений проблема останется, попробуйте также проверить логи на устройстве Android и устройстве Curie Nano, чтобы увидеть какие именно пакеты данных отправляются и принимаются.
Проблема может быть связана с тем, что в вашем коде на устройстве Curie Nano вы вызываете функцию setValue для всех трех характеристик одновременно в методе updateTemperature(). Это может привести к тому, что Bluetooth стек на устройстве не успевает обработать все три характеристики одновременно и происходит конфликт.
Попробуйте изменить свой код на устройстве Curie Nano так, чтобы вы устанавливали значение для каждой характеристики по отдельности, с интервалом в несколько миллисекунд, чтобы дать Bluetooth стеку возможность обработать каждую характеристику отдельно.
Также убедитесь, что у вас есть обработчики для всех трех характеристик на устройстве Android и что дескрипторы устанавливаются корректно для каждой характеристики.
Если после этих изменений проблема останется, попробуйте также проверить логи на устройстве Android и устройстве Curie Nano, чтобы увидеть какие именно пакеты данных отправляются и принимаются.