Connecting to Multiple Devices
Example: stream Respiration from two devices at once.
- Turn on devices and wait for the pulsating green LED (ready to connect).
- Run the routine below.
- Wait for both connections to establish.
Examples
For Android, Flutter and Apple platforms, use the manager and delegate setup from Establishing Connections. Add the fields and replace the corresponding methods in your existing delegate.
dart
import 'dart:async';
import 'package:aidlab_sdk/aidlab_sdk.dart';
const firstAddress = '<FIRST DEVICE ADDRESS>';
const secondAddress = '<SECOND DEVICE ADDRESS>';
final Set<String> connecting = <String>{};
Future<void> run() async {
await aidlabManager.scan(ScanMode.aggressive);
}
@override
void didDiscover(Device device, int rssi) {
final bool isTarget =
device.address == firstAddress || device.address == secondAddress;
if (!isTarget || !connecting.add(device.address)) {
return;
}
unawaited(connectTo(device));
}
Future<void> connectTo(Device device) async {
try {
await device.connect(this);
} catch (error) {
print('Connection failed: $error');
}
}
@override
Future<void> didConnect(Device device) async {
try {
await device.collect([DataType.respiration], []);
} catch (error) {
print('Collection failed: $error');
}
}
@override
void didDisconnect(Device device, DisconnectReason reason) {
connecting.remove(device.address);
print('Disconnected from: ${device.address}');
}
@override
void didReceiveRespiration(Device device, int timestamp, double value) {
print('Respiration: $value from ${device.address}');
}kotlin
import java.util.EnumSet
private val firstAddress = "<FIRST DEVICE ADDRESS>"
private val secondAddress = "<SECOND DEVICE ADDRESS>"
private val connecting = mutableSetOf<String>()
fun run() {
aidlabManager.scan()
}
override fun didDiscover(device: Device, rssi: Int) {
val address = device.address()
if (address != firstAddress && address != secondAddress) return
if (!connecting.add(address)) return
lifecycleScope.launch {
try {
device.connect(this@MainActivity)
} catch (error: IllegalStateException) {
connecting.remove(address)
println("Connection failed: ${error.message}")
}
}
}
override fun didConnect(device: Device) {
lifecycleScope.launch {
device.collect(EnumSet.of(DataType.RESPIRATION), EnumSet.noneOf(DataType::class.java))
}
}
override fun didDisconnect(device: Device, reason: DisconnectReason) {
connecting.remove(device.address())
println("Disconnected from: ${device.address()}")
}
override fun didReceiveRespiration(device: Device, timestamp: Long, value: Float) {
println("Respiration: $value from ${device.address()}")
}python
import asyncio
from aidlab import AidlabManager, DataType, DeviceDelegate, DisconnectReason
FIRST_ADDRESS = "<FIRST DEVICE ADDRESS>"
SECOND_ADDRESS = "<SECOND DEVICE ADDRESS>"
class MainManager(DeviceDelegate):
async def run(self):
devices = await AidlabManager().scan()
first = next((d for d in devices if d.address == FIRST_ADDRESS), None)
second = next((d for d in devices if d.address == SECOND_ADDRESS), None)
if first:
await first.connect(self)
if second:
await second.connect(self)
while True:
await asyncio.sleep(1)
async def did_connect(self, device):
await device.collect([DataType.RESPIRATION], [])
def did_disconnect(self, device, reason: DisconnectReason):
print("Disconnected from:", device.address, reason)
def did_receive_respiration(self, device, _, value):
print("Respiration:", value, device.address)
asyncio.run(MainManager().run())swift
import Foundation
let firstDeviceAddress = "<FIRST DEVICE UUID>"
let secondDeviceAddress = "<SECOND DEVICE UUID>"
private var connected: Set<UUID> = []
func run() { aidlabManager.scan() }
func didDiscover(_ device: Device) {
let addr = device.address.uuidString
guard addr == firstDeviceAddress || addr == secondDeviceAddress else { return }
guard connected.insert(device.address).inserted else { return }
Task { try await device.connect(delegate: self) }
}
func didConnect(_ device: Device) {
Task {
do {
_ = try await device.collect(dataTypes: [.respiration], dataTypesToStore: [])
} catch {
print("Collection failed: \(error)")
}
}
}
func didDisconnect(_ device: Device, reason _: DisconnectReason) {
connected.remove(device.address)
print("Disconnected from: \(device.address.uuidString)")
}
func didReceiveRespiration(_ device: Device, timestamp: UInt64, value: Float) {
print("Respiration: \(value) from \(device.address.uuidString)")
}Unity
The Unity SDK supports one active connection through the singleton AidlabSDK object, selected by device name. Use Python, Android, Apple Platforms, or Flutter when your app must manage multiple supported devices in parallel.
Troubleshooting
Connection limits depend on the Bluetooth adapter, operating system, and signal conditions. Validate the required number of simultaneous connections on your target hardware.