A
A
alk2017-04-27 14:35:22
Android
alk, 2017-04-27 14:35:22

OnCharacteristicRead in android does not always respond to changes in characteristics in arduino. What is the problem?

Colleagues, such a problem:
There is a Curie Nano board, there is a phone with android 5.0+. They communicate via Bluetooth Low Energy.
As planned, Curie Nano should periodically transmit 3 parameters (characteristics) to the phone. Here is the code currently on the board:

#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; 
}

All characteristics are successfully filled with parameters every 3 seconds, I output them to the port for verification.
From the android side, when the onServicesDiscovered event occurs, I set descriptors to these parameters in order to catch notifications about their changes. Under the debug you can see that the descriptors are put down successfully. Here is the code:
@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);
            }
        }
    }

After executing this code, the onCharacteristicRead callback is executed every 3 seconds, but only 1 characteristic with UUID = 6e400002-b5a3-f393-e0a9-e50e24dcca9e comes there, nothing comes for other characteristics.
On the board, I tried to send different characteristics in turn with an interval of 3 seconds, on the android the result did not change at all.
What could be the problem?

Answer the question

In order to leave comments, you need to log in

1 answer(s)
A
alk, 2017-04-27
@Alexey_Kutepov

Understood the problem. I set the value of the descriptors in a row, but I had to wait for the onDescriptorWrite callback to fire and only after that set the value of the next descriptor.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question