This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Connecting to multiple devices problem


Problem:
While connecting with smartphone to several devices based on nrf52832, works only last connected device.
Smartphone Application uses Nordic Android library (no.nordicsemi.android:ble:2.3.0)

In application created instances of class for each of devices

       public class BleDeviceManager extends BleManager {

    	   public BluetoothGatt Gatt;

	       public BleDeviceManager(@NonNull final Context context) {
	            super(context);
	       }
       ...
       }


, which store into

HashMap<String, BleDeviceManager> dbMacDeviceManager = new HashMap<>();
bdm = new BleDeviceManager(context);
bdm.setConnectionObserver(co);
bdm.setBondingObserver(bo);
dbMacDeviceManager.put(rp.mac, bdm);


Make connection to the first device:

	BleDeviceManager bdm = dbMacDeviceManager.get(rp.mac);
	BluetoothDevice new_device;
	new_device = (bdm.getBluetoothDevice() != null) ? bdm.getBluetoothDevice() : MacToDevice(rp.mac);

	bdm.connect(new_device).timeout(5000).retry(1, 100).fail((device, status) -> {
	    Log.i(TAG, String.format("%s->fail %s", rp.method, device));
	    result.error("errorConnect",
		    String.format("Method %s(%s) return error", rp.method, device.getAddress()),
		    rp.toMap(status));
	}).done(device -> {
	    Log.i(TAG, String.format("%s->done %s", rp.method, device.getAddress()));
	    result.success(true);
	}).enqueue();
	



After connection all works is correct (reading and writing of characteristics and notifying).

	bdm.simpleWriteCharacteristic(rp.characteristic, rp.data)
	    .with(dataSentCallback)
	    .done(device -> {
	    Log.d(TAG, String.format("%s-> done: %s", rp.method, device.getAddress()));
	    result.success(getSuccessMap);
	}).fail((device, status) -> {
	    Log.d(TAG, String.format("%s -> fail: %s %d", rp.method, device.getAddress(), status));
	    result.error("error" + rp.method, String.format("%s -> Error <%s> for characteristic <%s> (device<%s>)",
		    rp.method, status, rp.charHandle, rp.mac), rp.toMap(status));
	}).enqueue();

, where simpleWriteCharacteristic is method of simpleWriteCharacteristic class:

public WriteRequest simpleWriteCharacteristic(BluetoothGattCharacteristic firstCharacteristic, byte[] data) {
Log.d(TAG, "write");
return writeCharacteristic(firstCharacteristic, data);
}

When I make connection to the second device (while first connection is active), I'm get the next:
1. Exchange with the second device is fine.
2. For the first device functions "connect", "disconnect" and "writeCharacteristic", never worked call or return handlers "done" and "fail".
3. At same time "notify" handler for the first device continue works fine and change the GUI state.
4. When, before connect to the second drvice, I'm switch off the first connection, then swith off the second connection and connect to the first device, all works correct. In other words, only one device can work at same time.

Question:
How do I work properly with multiple devices?

  • Hello,

    Looks like you're doing everything correct. We have an example of multi connect in Proximity profile in nRF Toolbox.

    The implementation is very similar to what you have: BleMulticonnectProfileService. There's a HashMap containing BluetoothDevice and a manager, similar to what you have. Each Ble Manager is independent and responsible for connection with only one device. Fun fact: you may even have many Ble Manager instances for the same device. A phone should be able to connect simultaneously to at least 6 devices.

    Few comments. Try avoiding having an instance to BluetoothGatt in your manager. The Ble Manager implementation does a lot to hide this object internally, and it is not needed. Instead, hold references to characteristics. The manager should expose a "high level" API. E.g. switchLed(boolean), instead of writeCharcteristic(char, data). An example may be found in nRF Blinky

Related