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

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

Войти через центр авторизации
Похожие вопросы
YLab Тольятти
от 80 000 до 130 000 руб.
RentaTeam Москва
от 120 000 до 170 000 руб.
Rambler Group Москва
До 220 000 руб.