arduino-libraries / ArduinoBLE

ArduinoBLE library for Arduino
GNU Lesser General Public License v2.1
311 stars 205 forks source link

[nano33ble] Multiple concurrent connections #108

Open polldo opened 4 years ago

polldo commented 4 years ago

ArduinoBLE library supports up to ATT_MAX_PEERS multiple concurrent connections. https://github.com/arduino-libraries/ArduinoBLE/blob/8a49b8c1e0ac195db38a0639378a1b50b7bdd566/src/utility/ATT.h#L29-L35 However, using the latest versions of the nano33ble core there are problems when trying to handle multiple connections.

SETUP: ArduinoBLE version: 1.1.3-10-g89fd740 https://github.com/arduino-libraries/ArduinoBLE/commit/89fd740aca3c95434215f45b9aa661c86c43493b , in branch 'multi-connection' https://github.com/arduino-libraries/ArduinoBLE/tree/multi-connection

Test sketches

void setup() { Serial.begin(115200); while(!Serial); BLE.begin(); BLE.debug(Serial); BLE.scanForName("peripheral"); }

void connectionLoop() { // If not already connected to 2 peripherals, try to connect to a new found peripheral. if (BLE.peripheralCount() < 2) {

BLEDevice peripheral = BLE.available();
if (peripheral) {
  BLE.stopScan();

  if (!peripheral.connect()) {
    Serial.println("Failed to connect!");
    return;
  }

  if (!peripheral.discoverAttributes()) {
    Serial.println("Attribute discovery failed!");
    peripheral.disconnect();
    return;
  }
}

} }

auto timeRef = millis(); void loop() { connectionLoop();

if (millis() - timeRef >= 5000) { timeRef = millis();

int periphCount = BLE.peripheralCount();
Serial.print(" Peripheral connected: ");
Serial.println(periphCount);

if (periphCount < 2) {
  BLE.scanForName("peripheral");
}

// Loop through all connected peripherals
for (int periphIdx = 0; periphIdx < periphCount; periphIdx++) {
  BLEDevice peripheral = BLE.peripheral(periphIdx);
  if (peripheral) {
    BLECharacteristic batteryLevelChar = peripheral.characteristic("2A19");

    if (!batteryLevelChar) {
      Serial.println("Peripheral does not have battery level characteristic!");
      peripheral.disconnect();
    } else {
      Serial.print("Peripheral connected, value: ");
      batteryLevelChar.read();
      Serial.println(*batteryLevelChar.value());
    }
  }
}

} }

- Peripherals:
```C++
#include <ArduinoBLE.h>

BLEService batteryService("180F");
BLEUnsignedCharCharacteristic batteryLevelChar("2A19", BLERead | BLEWrite); 

void setup() {
  Serial.begin(115200);    
  pinMode(LED_BUILTIN, OUTPUT); 
  if (!BLE.begin()) {
    Serial.println("starting BLE failed!");
    while (1);
  }

  // Configure peripheral
  BLE.setLocalName("peripheral");
  BLE.setAdvertisedService(batteryService); 
  batteryService.addCharacteristic(batteryLevelChar); 
  BLE.addService(batteryService);
  BLE.advertise();

  Serial.println("peripheral configured - central connected: 0");
}

auto timeRef = millis();
void loop() {
  static uint8_t battery = 0;
  BLE.poll();
  if (millis() - timeRef >= 3000) {
    timeRef = millis();
    if (BLE.centralCount() > 0) {
      digitalWrite(LED_BUILTIN, HIGH);
      batteryLevelChar.writeValue(battery);
      battery++;
    } else {
      digitalWrite(LED_BUILTIN, LOW);
    }
  }
}
polldo commented 4 years ago

The problem was introduced here https://github.com/arduino/ArduinoCore-nRF528x-mbedos/commit/01adfdccd26a4d618f0c14761cfb705f978c38ed , by setting the WSF_MS_PER_TICK to 10. I created a new branch in my fork of the nRF core, here https://github.com/Polldo/ArduinoCore-nRF528x-mbedos/commits/ble-multiconnection , that follows the core version 1.1.6. It reverts the problematic commit and adds another fix for enabling multiple connections. It seems to work, any help in testing and reporting feedback is very much appreciated.

iactiva commented 3 years ago

There seems branch 'multi-connection' is no longer working with Arduino Mbed boards v.2.0.0, both deprecated and Nano versions.