I want to create an android application in order to connect and retrieve data from an ESP32 board as well as the ability to send values to the board using Bluetooth Low Energy communication.
I have an ESP32 board with BLE server inside.I've implemented a custom Service with the following characteristic.
/* define the characteristic and it's propeties */
BLECharacteristic dataCharacteristic(
BLEUUID((uint16_t)0x1A00),
BLECharacteristic::PROPERTY_READ |
BLECharacteristic::PROPERTY_WRITE |
BLECharacteristic::PROPERTY_NOTIFY);
I successfully implemented all the scanning, reading and notifying functions inside the android application but when it comes to writing BluetoothGatt.writeCharacteristic always returns false in the first Condition:
if ((characteristic.getProperties() & BluetoothGattCharacteristic.PROPERTY_WRITE) == 0
&& (characteristic.getProperties()
& BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE) == 0) {
return false;
}
While Debugging the android application the characteristic.getProperties() is always 18.
public boolean writeCharacteristic(BluetoothGattCharacteristic characteristic) {
if ((characteristic.getProperties() & BluetoothGattCharacteristic.PROPERTY_WRITE) == 0
&& (characteristic.getProperties()
& BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE) == 0) {
return false;
}
if (VDBG) Log.d(TAG, "writeCharacteristic() - uuid: " + characteristic.getUuid());
if (mService == null || mClientIf == 0 || characteristic.getValue() == null) return false;
BluetoothGattService service = characteristic.getService();
if (service == null) return false;
BluetoothDevice device = service.getDevice();
if (device == null) return false;
synchronized (mDeviceBusy) {
if (mDeviceBusy) return false;
mDeviceBusy = true;
}
try {
mService.writeCharacteristic(mClientIf, device.getAddress(),
characteristic.getInstanceId(), characteristic.getWriteType(),
AUTHENTICATION_NONE, characteristic.getValue());
} catch (RemoteException e) {
Log.e(TAG, "", e);
mDeviceBusy = false;
return false;
}
return true;
}
Here is the write characteristic code that uses the above function:
//Get BLE Service
BluetoothGattService service = gatt.getService(SERVICE_UUID);
//Get the characteristic
BluetoothGattCharacteristic dataCharacteristic =
service.getCharacteristic(DATA_CHARACTERISTIC_UUID);
//Pass value
dataCharacteristic.setValue(value);
//Write characteristic
boolean success = gatt.writeCharacteristic(dataCharacteristic);
if(success){
Log.d(TAG, "Write characteristic successful");
}
else{
Log.e(TAG, "Write characteristic failed");
}
I have already tried executing write operation without the read or notify, to prevent multiple requests, but the result is the same.
I also tried using external BLE applications with read write notify functionality and they all worked perfectly with my ESP32 setup.
After a lot of searching and experimenting with various ways of implementing the above communication of an android application and an ESP32 board with BLE server inside, I was able to find the solution.
In all my tests I used UUIDs in the following way:
Declaring characteristic uuid inside ESP32
Characteristic_UUID = BLEUUID((uint16_t) 0x1A00))
And Searching this uuid from android using
Characteristic _UUID = convertFromInteger (0x1A00)
convertFromInteger function:
public UUID convertFromInteger (int i)
{
final long MSB = 0x0000000000001000L;
final long LSB = 0x800000805f9b34fbL;
long value = i & 0xFFFFFFFF;
return new UUID (MSB | (value << 32), LSB);
}
The solution was found when I followed a tutorial in which I noticed the uuids and the differences with the ones I used.When I replaced my old uuids with randomly generated uuid such as "cff6dbb0-996f-427b-9618-9e131a1d6d3f", the whole writeCharacteristic process for BLE server was done without any problem.