I am making Android app which can make communication with Arduino. This program is simple echo service. if Android app send a data, Arduino return the data by BLE. I have successed to make Android app send data, and it's time to send back data to Android. I made a descriptor on Arduino, so Android can detect the characteristic value change.
but here is the problem. BluetoothGattCallback
method's onCharacteristicChanged
method never called.
I checked code several times but cannot found where is wrong...
This is the code setCharacteristicNotification. I put it in the onServicesDiscovered
.
if(charService.equals("741c12b9-e13c-4992-8a5e-fce46dec0bff")){
btGattCharacteristic = btGattService.getCharacteristic(UUID.fromString(charService));
if(btGattCharacteristic == null)
{
MainThreadPrint("btGattCharacteristic failed");
}
else
{
MainThreadPrint("1 - btGattCharacteristic success");
BluetoothGattDescriptor bluetoothGattDescriptor = btGattCharacteristic.getDescriptor(UUID.fromString("beca6057-955c-4f8a-e1e3-56a1633f04b1"));
MainThreadPrint("2 - Descriptor found! : beca6057-955c-4f8a-e1e3-56a1633f04b1");
bluetoothGattDescriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
MainThreadPrint("3 - Descriptor set value done.");
btGatt.writeDescriptor(bluetoothGattDescriptor);
MainThreadPrint("4 - descriptor setting finished.");
}
}
I have confirmed above codes are viable.
And this is BluetoothGattCallBack
's onCharacteristicChanged
code.
I just temporary put MainThreadPrint
for see onCharacteristicChanged
method works or not
private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
@SuppressLint("MissingPermission")
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
runOnUiThread(new Runnable() {
public void run() {
logAdapter.add("BluetoothCallBack - newState : " + String.valueOf(newState));
}
});
switch (newState){
case 0:
runOnUiThread(new Runnable() {
public void run() {
logAdapter.add("device disconnected");
}
});
break;
case 2:
runOnUiThread(new Runnable() {
public void run() {
logAdapter.add("device connected");
}
});
btGatt.discoverServices();
break;
default:
runOnUiThread(new Runnable() {
public void run() {
logAdapter.add("unknown error : " + String.valueOf(newState));
}
});
break;
}
logAdapter.notifyDataSetChanged();
}
@Override
public void onServicesDiscovered(final BluetoothGatt gatt, final int status) {
// this will get called after the client initiates a BluetoothGatt.discoverServices() call
MainActivity.this.runOnUiThread(new Runnable() {
public void run() {
tvState.setText("device services have been discovered");
}
});
//displayGattServices(btGatt.getServices());
ProfileInitializer(btGatt.getServices());
}
@Override
public void onCharacteristicChanged (BluetoothGatt gatt, BluetoothGattCharacteristic characteristic){
super.onCharacteristicChanged(gatt, characteristic);
MainThreadPrint("onCharacteristicChanged");
}
@Override
public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
super.onCharacteristicRead(gatt, characteristic, status);
MainThreadPrint("onCharacteristicRead");
}
};
but it still not calling onCharacteristicChanged
.
this is my Arduino code.
#include <ArduinoBLE.h>
BLEService echoService("00000000-0000-1000-8000-00805f9b34fb");
BLEStringCharacteristic charac ("741c12b9-e13c-4992-8a5e-fce46dec0bff", BLERead | BLEWrite | BLENotify,40);
BLEDescriptor Descriptor("beca6057-955c-4f8a-e1e3-56a1633f04b1","characDescriptor");
String var = "";
void setup(){
Serial.begin(9600);
while(!Serial);
if(!BLE.begin()){
Serial.println("starting BLE failed.");
while(1);
}
BLE.setLocalName("Arduino BLE Echo");
BLE.setAdvertisedService(echoService);
charac.addDescriptor(Descriptor);
echoService.addCharacteristic(charac);
BLE.addService(echoService);
BLE.advertise();
Serial.println("Bluetooth device active, waiting for connections...");
Serial.println(" ");
}
void loop(){
BLEDevice central = BLE.central();
if(central){
Serial.println("* Connected to central device!");
Serial.print("Connected to central : ");
Serial.println(central.address());
Serial.println(" ");
while(central.connected()){
if(charac.written()){
var = charac.value();
Serial.println(var);
delay(500);
charac.writeValue(var);
Serial.println("write stringCharacteristic");
}
}
Serial.print("Disconnected from central: ");
Serial.println(central.address());
}
}
I also used nRFConnect App to check it works properly or not.
can some one tell me the reason why my onCharacteristicChanged
not calling?
As nRFConnect clearly states notifications an indications are disabled.
Instead of ENABLE_NOTIFICATION_VALUE for "beca6057-955c-4f8a-e1e3-56a1633f04b1" you need to do this for the "Client Characteristic Configuration (0x2902)"