Recieving multiple packets in one connection Android BLE - android

When reading a characteristic of ble in android device or even subscribing to it, I receive 2 packets at the same time but I know that these data are not complete because when decoding them i find a part of the data sent by the characteristic so I think that the problem is that the ble write multiple packets to the characteristic at the same connection interval but the android recieve only 2 of them
I need to know how to receive all of them so I can have the full data at the end ?
This is the code of onCharacteristicChanged method
#Override
public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
if (HEART_RATE_READING_CHAR.equals(characteristic.getUuid())){
byte[] char_float_value = characteristic.getValue();
String s="";
for(int i=0;i<char_float_value.length;i++){
s=s +String.format("%02x", char_float_value[i])+" ";
}
s = s.substring(0, s.length()-1);
Log.e("_____________", "_____________");
Log.d("TAG", s);
handler.sendMessage(Message.obtain(null,MSG_HEARTRATE,char_float_value[14]));
}
}
And these are the packets i receive at the same time
Packets

Related

Android BLE read Gatt Characteristic

I am trying to read some Bluetooth Characteristics in my APP.
Now i have a Problem with what to do after the characteristic changed from my Gatt Server. At first i've tried to use a thread to retrigger the read for the characteristic again and again like this:
new Thread(new Runnable() {
#Override
public void run() {
int[] newData = new int[30];
while(true){
try{
for(int i=0;i<newData.length;i++){
newData[i] = 0;
}
BluetoothGatt tmpGatt = refExtDataClass.getRefBluetoothGatt();
tmpGatt.readCharacteristic(characteristic);
byte[] value = characteristic.getValue();
for(int i=0;i<newData.length;i++){
newData[i] = value[i];
}
refExtDataClass.setNmData(newData);
}catch(Exception e){
break;
}
}
}
}).start();
But the Problem is that it's seems like the data is corrupt at one point (like i've always writing the same data into the characteristic from my MCU side).
Is it allowed to read BLE data like this? Is there any suggested way to read BLE data all the time? Or update it on my App side?
If you Need any additional code, please let me know.
Reading GATT characteristics is an asynchronous operation. The result is not available until you receive the onCharacteristicRead callback.
Anyway, you should rather configure your GATT server to send notifications when it has new data to send rather than polling it all the time.

Android bluetooth get the heart rate measurement

I want to get the value of the HRM of an "A&D UA-651BLE" device.
this is what's written in the datasheet of this device to get the HRM value:
Set the application to pairing mode to start scanning.
Start pairing of A&D BLE device following each instruction manual.
At pairing mode, the application should set time and date and any other device settings
to A&D BLE device. After successful pairing, A&D BLE device shows “End” on the screen.
Take a measurement and finish the measurement, then A&D BLE device start BLE
connection with advertising. The application starts scanning with suitable interval so that
the application catches the advertising of A&D BLE device as soon as it can.
At initial connection or pairing, the Application set “2” to CCCD (Client Characteristic
Configuration Descriptor) so that A&D BLE device sends a measurement data with
Indication.
After A&D device recognizes to be set “2” to CCCD and to be synchronized time and date
within 5 seconds after connected, send the data with Indication.
If the timeout set CCCD and time and date is expired, A&D BLE device will not send data
and store the data in memory. The stored data in A&D BLE device can send next
successful connection.
this is my service code:
public void setCharacteristicNotification(BluetoothGattCharacteristic characteristic,
boolean enabled) {
if (mBluetoothAdapter == null || mBluetoothGatt == null) {
Log.w(TAG, "BluetoothAdapter not initialized");
return;
}
mBluetoothGatt.setCharacteristicNotification(characteristic, enabled);
// This is specific to Heart Rate Measurement.
if (UUID_HEART_RATE_MEASUREMENT.equals(characteristic.getUuid())) {
BluetoothGattDescriptor descriptor = characteristic.getDescriptor(
UUID.fromString(SampleGattAttributes.CLIENT_CHARACTERISTIC_CONFIG));
descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
mBluetoothGatt.writeDescriptor(descriptor);
}
}
and this is the method that read data:
final byte[] data = characteristic.getValue();
if (data != null && data.length > 0) {
final StringBuilder stringBuilder = new StringBuilder(data.length);
for(byte byteChar : data)
stringBuilder.append(String.format("%02X ", byteChar));
Log.e("HRM value",stringBuilder.toString());
dataComposition.put(characteristic.getUuid().toString(),stringBuilder.toString());
intent.putExtra(EXTRA_DATA,dataComposition);
}
the problem is that this code doesn't return any data !!
There's an Android Open Source Project example that does precisely this, easiest option would be to clone the android-BluetoothLeGatt code, build and compare it to your own. If you can't spot the difference / issue simply deploy both app's and step through both sets of code. Having some known working code will also help to rule out the possibility that the HRM is not functioning properly.
Do you have and example , i try this with equal device and i cant obtain the information y try with
public String response() {
if (mConnected) {
mBluetoothLeService.readCharacteristic(characteristica);
byte response[] = characteristica.getValue();
String respuesta = ReadBytes(response);
mBluetoothLeService.disconnect();
return respuesta;
} else {
return null;
}
}

writeCharacteristic() returns true, but does not call onCharacteristicWrite()

I wish to read a characteristic value stored in a device, modify the value, and then write it to the device. For some reason, writeCharacteristic() return true, but the internal device value does not change and onCharacteristicWrite() is not called. In fact, for some reason it is only called if I attempt to write something, and then is called shortly after I close or reopen the app - and doesn't change the device value. I've been looking into this for a few days and it's driving me crazy. It may be worth noting that reading characteristics both manually and via a notification both work fine.
Why is the writeCharacteristic() not going through, and why is onCharacteristicWrite() being called at such an odd time?
I am not sure where the issue stems from. It could be something dumb and simple like calling writeCharacteristic() incorrectly (my implementation is based off the question "Working with BLE Android 4.3 how to write characteristics?"). Would it be possible that the request is being ignored because onCharacteristicRead() is somehow unfinished?
I believe these links appear most helpful for indicating the issue but I haven't been able to pull anything from them myself:
Android BLE API: GATT Notification not received
https://code.google.com/p/android-developer-preview/issues/detail?id=1714
As a walkthrough of my code, an onItemClick() event is hit, which initiates the sequence.
int flag = 1;
((MainActivity)getActivity()).BtService.readFlag(flag);
It calls a function (in a Service) which verifies the Bluetooth connection and reads the characteristic.
public boolean readFlag(int flag){
/*... removed code here verifies that the Bluetooth Gatt is available,
that the Service exists...*/
BluetoothGattCharacteristic characteristic = Service.getCharacteristic(SEND_FLAGS_CHAR);
if (characteristic == null) {
Log.e(TAG, "char not found!");
return false;
}
try {
// Store intended flag value in SharedPreferences, then read the current one.
Editor fEditor = sPrefs.edit();
fEditor.putInt(calibrationSetFlagToSendKey, flag);
fEditor.commit();
mConnectedGatt.readCharacteristic(characteristic);
// Catch response in onCharacteristicRead() callback.
return true;
}
catch (NullPointerException e) {
Log.w("readCharacteristic", "The characteristic could not be read.");
return false;
}
}
onCharacteristicRead() is called, which only calls a Handler to modify and broadcast the result back to MainActivity. trueFlagValue is a byte that is stored globally within the Service (bad practise I know, but I intend to modify this later.)
case MSG_SEND_FLAG:
characteristic = (BluetoothGattCharacteristic) msg.obj;
if (characteristic.getValue() == null) {
Log.w(TAG, "Error obtaining current flags");
return;
}
int recentReadDeviceFlag = characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT8, 0);
int initialFlag = sPrefs.getInt(calibrationSetFlagToSendKey, 0);
if (initialFlag == 0) Log.e("Write Debug", "Flag to send is apparently 0");
/*... Arithmetic modifying flag integer value...*/
//Desired value is the OR'd value of the value read and value desired
trueFlagValue = (byte) ((byte) initialFlag | (byte) recentReadDeviceFlag);
Log.d("Read Debug", "OR'd value is " + trueFlagValue +", sending broadcast");
Intent fIntent = new Intent("com.example.appwithble.SEND_FLAGS");
sendBroadcast(fIntent);
break;
The BroadcastReceiver in MainActivity then calls a method in my Service, verifying an asking for a writeCharacteristic(), as was done for readCharacteristic(). Accesses the trueFlagValue set earlier.
else if("com.example.appwithble.SEND_FLAGS".equals(intent.getAction())) {
BtService.performWriteFlag();
}
// ...
public boolean performWriteFlag () {
/*... check Gatt is available and that Service exists...*/
BluetoothGattCharacteristic characteristic = Service.getCharacteristic(SEND_FLAGS_CHAR);
if (characteristic == null) {
Log.e(TAG, "char not found!");
return false;
}
byte[] byteValue = new byte[1];
byteValue[0] = trueFlagValue;
characteristic.setValue(byteValue);
boolean status = mConnectedGatt.writeCharacteristic(characteristic);
return status;
}
My onCharacteristicWrite() callback should then be called, and currently contains only a line of code to log a message. In reality, this is only ever called sometimes, as the app is closed or reopened. The value stored in my peripheral's characteristic never changes.
I am not an expert, but in my BLE app
I first connect to peripheral
then pair to it (by calling createBond() method),
then discover services,
then discover characteristics (and store them in app variables) and
finally write values to characteristics (by using the app variables)
Have you tried that?
Such a rookie mistake.
As I've not experimented with writing data before I assumed something was wrong with the writing process or the device. After looking at the kinds of data coming from by readCharacteristic() and by asking around about the device I am sending to, I started to realise that perhaps the data I am sending is in the wrong format.
It turns out that even though only four different flags need to be sent through (could be done with two bits), the characteristic needs to be formatted at two bytes for my particular device, not one. So if I had made my byte array something like this, it would've worked.
byte[] byteValue = new byte[2];
byteValue[0] = trueFlagValue;
byteValue[1] = (byte)0;
characteristic.setValue(byteValue);
I expect if anyone else had an odd problem where the write is initiated but not completed, then it's likely an issue like this - at least, something in the device is rejecting the write.

Android BLE BluetoothGattCharacteristic writing additional values

I want to write a command to a BluetoothGattCharacteristic with a parameter on it. I know how to write a command in bytes by setValue() method. But do not know how to write the parameter.
Here is an example of how to perform a BLE write:
public void writeValue(final String uuid, final byte[] value)
{
final BluetoothGattCharacteristic characteristic = getCharacteristic(bluetoothGatt, uuid);
characteristic.setValue(value);
bluetoothGatt.writeCharacteristic(characteristic);
}
The first argument of the method is a specified characteristic UUID of a service in your remote device
you want to access. The second argument is a byte Array you want to write to the characteristics of the remote device.

HM-10 Bluetooth Module - BLE 4.0 Keep Losing Connection

has anyone tried using HM-10 Bluetooth module?
I'm able to pair with it using an Android device and passing the pre-defined PIN. Based on the UART return, the pairing is successful (module returns OK+CONN - means a connection was established)
However, after a few seconds (2-3), the UART receives OK+LOST; means the connection was lost. Also, the LED starts blinking (normally, when a connection is active, it stays lit)
Is this normal behaviour for bluetooth in general or the HM-10 module.
This is the product's website: http://www.jnhuamao.cn/bluetooth.asp?ID=1
I'm not sure, but HM -10 don't support rfcom. It's mean that you must use GATT functionality for communication. Entity of BLE is usage of minimum data package as it possible, so BLE don't hold the connection all times and use something like statuses [attributes].
So, few code lines for example, how work with BLE:
1.
BluetoothAdapter mBluetoothAdapter = mBluetoothManager.getAdapter();
BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(DEVICE_ADDR);
That's device initiation, the same like with simple bluetooth, where DEVICE_ADDR is the MAC of your BLE(how to find this address you can find in google or stack overflow, its trivial)
2.
BluetoothGattService mBluetoothGattService;
BluetoothGatt mBluetoothGatt = device.connectGatt(this, false, mGattCallback);
BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
#Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
if (newState == BluetoothProfile.STATE_CONNECTED) {
mBluetoothGatt.discoverServices();
}
}
#Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
if (status == BluetoothGatt.GATT_SUCCESS) {
List<BluetoothGattService> gattServices = mBluetoothGatt.getServices();
for(BluetoothGattService gattService : gattServices) {
if("0000ffe0-0000-1000-8000-00805f9b34fb".equals(gattService.getUuid().toString()))
{
mBluetoothGattService = gattService;
}
}
} else {
Log.d(TAG, "onServicesDiscovered received: " + status);
}
}
};
So, what this code mean: if u can see from this part of code, i describe how GATT service find. This service needed for "attribute" communication. gattService.getUuid() has few uuids for communication(4 in my module), some of them used for RX, some for TX etc. "0000ffe0-0000-1000-8000-00805f9b34fb" that is one of uuid that use for communication thats why i check it.
The final part of code is message sending:
BluetoothGattCharacteristic gattCharacteristic = mBluetoothGattService.getCharacteristic(UUID.fromString("0000ffe1-0000-1000-8000-00805f9b34fb"));
String msg = "HELLO BLE =)";
byte b = 0x00;
byte[] temp = msg.getBytes();
byte[] tx = new byte[temp.length + 1];
tx[0] = b;
for(int i = 0; i < temp.length; i++)
tx[i+1] = temp[i];
gattCharacteristic.setValue(tx);
mBluetoothGatt.writeCharacteristic(gattCharacteristic);
After sending message contain hold on and you can send another message or can close connection.
More info, you can find on https://developer.android.com/guide/topics/connectivity/bluetooth-le.html.
PS: MAC address of your module can find with ble scanner code or with AT cmd:
on my firmware AT+ADDR or AT+LADDR
About UUIDs usage: not sure, but in my case, i find it with next AT+UUID [Get/Set system SERVER_UUID] -> Response +UUID=0xFFE0, AT+CHAR [Get/Set system CHAR_UUID] - Response +CHAR=0xFFE1. Thats why i make conclusion that UUID which i must use fe "0000[ffe0/is 0xFFE0 from AT response]-0000-1000-8000-00805f9b34fb"

Categories

Resources