2

I want to create android app, which can connect with bluetooth low energy module and can receive data. In my system microcontroller stm32f1 send data of measurements over UART to the BT LE module.

My question is how to start? I read a lot about GATT and UART Service, but still don't know how to start. Give me some information please.

ked2liz
  • 67
  • 2
  • 3
  • 11
Adrian M
  • 21
  • 1
  • 3
  • Do you have the services and characteristic structure? We use a Andoid app called "BLE Scanner". This apps shows the structure and you can read and write values in the characteristics. – JMA Nov 13 '18 at 13:48
  • Yes, i used this program and got list with UUID adresses, u talked about Custom Service overlap? what is the next step, how to connect characteristics with data send by UART? – Adrian M Nov 13 '18 at 13:56
  • What is you BLE Module, HM-10? – Augusto Nov 13 '18 at 14:04
  • Bolutek BLE CC41A – Adrian M Nov 13 '18 at 14:08
  • Create a custom service with custom characteristics with read + notify properties, then every time the measurement changes update the characteristics. I think this module uses AT commands to create and update characteristics. The andoid app can subscribe to the characteristics and will recive a notification every time your device updates it. – JMA Nov 13 '18 at 15:00

1 Answers1

2

You need:

  • UUIDs of your Service, Characteristic and Descriptor;

  • Permissions' Bluetooth Low Energy

The program must:

  1. Scan BLE devices
  2. Connect a device
  3. Set callbacks' BLE

AndroidManifest.xml

<uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/>
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

Activity.java

// Bluetooth's variables
    BluetoothAdapter bluetoothAdapter;
    BluetoothLeScanner bluetoothLeScanner;
    BluetoothManager bluetoothManager;
    BluetoothScanCallback bluetoothScanCallback;
    BluetoothGatt gattClient;

    BluetoothGattCharacteristic characteristicID; // To get Value

// UUID's (set yours)
final UUID SERVICE_UUID = UUID.fromString("ab0828b1-198e-4351-b779-901fa0e0371e");
final UUID CHARACTERISTIC_UUID_ID = UUID.fromString("1a220d0a-6b06-4767-8692-243153d94d85");
final UUID DESCRIPTOR_UUID_ID = UUID.fromString("ec6e1003-884b-4a1c-850f-1cfce9cf6567");

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // Bluetooth
    bluetoothManager = (BluetoothManager) getSystemService(BLUETOOTH_SERVICE);
    bluetoothAdapter = bluetoothManager.getAdapter();
    startScan();
}

 // BLUETOOTH SCAN

private void startScan(){
    Log.i(TAG,"startScan()");
    bluetoothScanCallback = new BluetoothScanCallback();
    bluetoothLeScanner = bluetoothAdapter.getBluetoothLeScanner();
    bluetoothLeScanner.startScan(bluetoothScanCallback);
}

// BLUETOOTH CONNECTION
private void connectDevice(BluetoothDevice device) {
    if (device == null) Log.i(TAG,"Device is null");
    GattClientCallback gattClientCallback = new GattClientCallback();
    gattClient = device.connectGatt(this,false,gattClientCallback);
}

// BLE Scan Callbacks
private class BluetoothScanCallback extends ScanCallback {

    @Override
    public void onScanResult(int callbackType, ScanResult result) {
        Log.i(TAG, "onScanResult");
        if (result.getDevice().getName() != null){
            if (result.getDevice().getName().equals(YOUR_DEVICE_NAME)) {
                // When find your device, connect.
                connectDevice(result.getDevice());
                bluetoothLeScanner.stopScan(bluetoothScanCallback); // stop scan
            }
        }
    }

    @Override
    public void onBatchScanResults(List<ScanResult> results) {
        Log.i(TAG, "onBathScanResults");
    }

    @Override
    public void onScanFailed(int errorCode) {
        Log.i(TAG, "ErrorCode: " + errorCode);
    }            
}

// Bluetooth GATT Client Callback
private class GattClientCallback extends BluetoothGattCallback {
    @Override
    public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
        super.onConnectionStateChange(gatt, status, newState);
        Log.i(TAG,"onConnectionStateChange");

        if (status == BluetoothGatt.GATT_FAILURE) {
            Log.i(TAG, "onConnectionStateChange GATT FAILURE");
            return;
        } else if (status != BluetoothGatt.GATT_SUCCESS) {
            Log.i(TAG, "onConnectionStateChange != GATT_SUCCESS");
            return;
        }

        if (newState == BluetoothProfile.STATE_CONNECTED) {
            Log.i(TAG, "onConnectionStateChange CONNECTED");
            gatt.discoverServices();
        } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
            Log.i(TAG, "onConnectionStateChange DISCONNECTED");
        }
    }

    @Override
    public void onServicesDiscovered(BluetoothGatt gatt, int status) {
        super.onServicesDiscovered(gatt, status);
        Log.i(TAG,"onServicesDiscovered");
        if (status != BluetoothGatt.GATT_SUCCESS) return;

        // Reference your UUIDs
        characteristicID = gatt.getService(SERVICE_UUID).getCharacteristic(CHARACTERISTIC_UUID_ID);
        gatt.setCharacteristicNotification(characteristicID,true);

        BluetoothGattDescriptor descriptor = characteristicID.getDescriptor(DESCRIPTOR_UUID_ID);
        descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
        gatt.writeDescriptor(descriptor);
    }

    @Override
    public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
        super.onCharacteristicRead(gatt, characteristic, status);
        Log.i(TAG,"onCharacteristicRead");
    }

    @Override
    public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
        super.onCharacteristicWrite(gatt, characteristic, status);
        Log.i(TAG,"onCharacteristicWrite");
    }

    @Override
    public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
        super.onCharacteristicChanged(gatt, characteristic);
        Log.i(TAG,"onCharacteristicChanged");
        // Here you can read the characteristc's value
        // new String(characteristic.getValue();
    }

    @Override
    public void onDescriptorRead(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
        super.onDescriptorRead(gatt, descriptor, status);
        Log.i(TAG,"onDescriptorRead");
    }

    @Override
    public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
        super.onDescriptorWrite(gatt, descriptor, status);
        Log.i(TAG,"onDescriptorWrite");
    }
}

Libs:

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCallback;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattDescriptor;
import android.bluetooth.BluetoothManager;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.le.BluetoothLeScanner;
import android.bluetooth.le.ScanCallback;
import android.bluetooth.le.ScanResult;

Notes:

  • The UUIDs must be same seted on the module.
  • In your program you must have two callbacks: ScanCallback and GattCallback. Scan callback is to manage the scan results and the GattCallback you can manage the data input/output.
  • This code the basic to show how use BLE on Android, works fine for me.
  • You can generate UUID here: https://www.uuidgenerator.net/
Augusto
  • 3,825
  • 9
  • 45
  • 93