0
votes

For a project I want to send acceleration data via BLE 4.2 (with DLE). An acceleration packet consists of 81 values (24 bits each, total 243 bytes). My goal is to send 18 packets (1458 acceleration packets or 4374 bytes). I use a Samsung Galaxy A3 2017 Edition as a central and a microcontroller (nRF52832dk) as a peripheral. After all packets have been sent, the connection to the smartphone is terminated and new 1458 acceleration packets are recorded. After that, an RTC activates sleep mode, on the nRF52832dk, for 1 minute. After 1 minute, the nRF52832dk is going to advertising for a new connection with the smartphone. The following figure illustrates the problem:

https://ibb.co/Syb4GDg

The software on the nRF52832dk works perfectly fine. I am able to record data, go into sleep mode, wake-up after 1 minute and advertise for new connection. My problem is the software application. I use these tutorials:

https://github.com/googlesamples/android-BluetoothLeGatt

https://developer.android.com/guide/topics/connectivity/bluetooth-le

in BluetoothLeGatt I have changed:

mBluetoothGatt = device.connectGatt(this, true, mGattCallback);

with the second parameter on true its possible for the smartphone to autoconnect. This works fine (for the first connection with the nRF)

Originally it was: mBluetoothGatt = device.connectGatt(this, false, mGattCallback);

Once a connection has been established, the callback routine is called by the GATT handler.

    // Implements callback methods for GATT events that the app cares about.  For example,
    // connection change and services discovered.
    private final BluetoothGattCallback mGattCallback =
            new BluetoothGattCallback() {
        @Override
        public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
            String intentAction;
            if (newState == BluetoothProfile.STATE_CONNECTED) {
                intentAction = ACTION_GATT_CONNECTED;
                mConnectionState = STATE_CONNECTED;
                broadcastUpdate(intentAction);
                Log.i(TAG, "Connected to GATT server.");
                // Attempts to discover services after successful connection.
                Log.i(TAG, "Attempting to start service discovery:" +
                        mBluetoothGatt.discoverServices());

            } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
                intentAction = ACTION_GATT_DISCONNECTED;
                mConnectionState = STATE_DISCONNECTED;
                Log.i(TAG, "Disconnected from GATT server.");
                broadcastUpdate(intentAction);
            }
        }
        @Override
        // New services discovered
        public void onServicesDiscovered(BluetoothGatt gatt, int status) {
            if (status == BluetoothGatt.GATT_SUCCESS) {
                broadcastUpdate(ACTION_GATT_SERVICES_DISCOVERED);
            } else {
                Log.w(TAG, "onServicesDiscovered received: " + status);
            }
        }

        @Override
        // Result of a characteristic read operation
        public void onCharacteristicRead(BluetoothGatt gatt,
                                         BluetoothGattCharacteristic characteristic,
                                         int status) {
            if (status == BluetoothGatt.GATT_SUCCESS) {
                broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
            }
        }

        @Override
        // Change in the characteristic
        public void onCharacteristicChanged(BluetoothGatt gatt,
                                            BluetoothGattCharacteristic characteristic) {
            broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
        }
    }; </i>

after the connection is established and the first packet is received, i get into the broadcastUpdate

    <i>private void broadcastUpdate(final String action,
                                 final BluetoothGattCharacteristic characteristic) {
        final Intent intent = new Intent(action);

        // This is special handling for the nRF52 profile.  Data parsing is
        // carried out as per profile specifications:
        // http://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.heart_rate_measurement.xml
        if (UUID_NRF.equals(characteristic.getUuid())) {

            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));
                intent.putExtra(EXTRA_DATA, new String(data) + "\n" + stringBuilder.toString());
            }

        } else {
            // For all other profiles, writes the data formatted in HEX.
            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));
                intent.putExtra(EXTRA_DATA, new String(data) + "\n" + stringBuilder.toString());
            }
        }
        sendBroadcast(intent);
    }

Now I got two problems (I had the same two problems before did the change in the code).

First Problem: My first problem is, that I just receive only one of the 18 BLE package (the first one).

Second Problem: My first Problem is also causing my second Problem. The Application does not recognize that the connection has been terminated from the nRF52832dk.

and I have another question. what exactly does

endBroadcast(intent);

?

1
This post is rather complex and unlikely to get an answer. It includes a lot of code but only a fraction to reproduce the problem. And it includes three questions. I recommend you start a new question or modify this one such that it focuses only on the first problem. And I also recommend that you try to come up with a short but complete piece of code. One question I had is whether you activate notifications for the characteristics. But the code in the question is insufficient for that and the code in the linked example project is not specific enough to answer it.Codo
And even aside from this StackOverflow question: Bluetooth is rather complex and you are more likely to master it if go step by step and don't throw DLE, long packets, sleep mode, reconnection etc. into the mix at once. Does your Bluetooth at least work without all those extra features?Codo

1 Answers

0
votes

This post is very complicated, I think you mean you cannot receive nrf52 data.

  1. You need check nrf52 support how many MTU, BLE protect max is '247' and valid data length is '244' valid length is (DEVICE_MTU - OPCODE_LENGTH(1) - HANDLE_LENGTH(2));

  2. So as you say you want receive 2474 bytes, it's at least 17 times.

  3. current process at android is onCharacteristicChanged - > onCharacteristicRead

  4. if you want trigger onCharacteristicChanged you need open remote device notification like this:

    private void EnableNotification(BluetoothGattDescriptor d, BluetoothGatt gatt)
    {
        gatt.SetCharacteristicNotification(d.Characteristic, true);
        d.SetValue(new byte[] { 1, 1 });
        gatt.WriteDescriptor(d);
    }