@Alexey_Kutepov
Разработчик программного обеспечения

Не всегда отрабатывает onCharacteristicRead в android на изменения характеристик в arduino. В чём проблема?

Коллеги, такая проблема:
Есть плата Curie Nano, есть телефон с android 5.0+. Взаимодействуют они через Bluetooth Low Energy.
По задумке Curie Nano должна периодически передавать на телефон 3 параметра (характеристики). Вот код который сейчас на плате:
#include <CurieBLE.h> 

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 секунды, на андройде результат абсолютно не изменился.
В чём может быть проблема?
  • Вопрос задан
  • 362 просмотра
Решения вопроса 1
@Alexey_Kutepov Автор вопроса
Разработчик программного обеспечения
Разобрался с проблемой. Я устанавливаю значение дескрипторов вподряд, а нужно было ожидать срабатывания калбека onDescriptorWrite и только после этого устанавливать значение следующего дескриптора.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы