Hi there,
SO, it’s been asked many times if more than one BLE connection can be made at a time with Peripherals to a Central and is the Seeed Studio Round Display up to the effort. YES!
Albeit NOT a standard method but uses another BLE LIB available in the Arduino tool box(works in ESP-IDF) also This is the NimBLE LIB
it is somewhat better for multiple peripherals and with some effort and understanding , 3 concurrent BLE connections can be made with 6 Notifications possible. How , Watch the video and Examine the code.
It’s a two part Series , with this being the SensorNode (peripheral) portion first.
ask any question you might have here, I’ll do my best to answer them.
HTH
GL 
 PJ ![]()
/* =====================================================================================
   Project    : SensorNode BLE Peripheral with OLED & RGB Status
   Platform   : Seeed Studio XIAO nRF52840 Sense with Xiao DEV/expansion Base.
   BSP        : Seeeduino mbed @ 2.9.3
   Core       : Arduino mbed (nRF52840)
   MCU        : Nordic nRF52840 (Cortex-M4F @ 64MHz, 1MB Flash, 256KB RAM)
   Board FQBN : Seeeduino:mbed:xiaonRF52840Sense
   IDE        : Arduino IDE 2.x
   
      Libraries  : 
      - ArduinoBLE v1.4.0 (BLE Peripheral GATT Profile)
      - Wire (I2C OLED via Dev Expansion Board)
      - U8x8lib or U8g2lib (for SSD1306 OLED on Expansion Base)
   Peripherals:
      - OLED Display (via I2C)
      - RGB LED (Builtin)
      - USER Button (D1)
      - Buzzer (A3)
   Features   :
      - BLE advertising as SensorNodeX (custom 181A service) "B" and "M" OLED indicators for Notify states,
      - OLED Display showing device name and BLE status
      - RGB LED feedback (Yellow=Advertising, Green=Connected, Red=Disconnected)
      - Animated "..." progress indicator
      - Placeholder for future sensor expansion (Temp, Humidity, Motion, Battery)
   Author     : Pj Glasso, & Embedded AI Assistant (ESP32 Expert Mode) , wiki.seeedstudio.com/
   Version    : REV 1.0 // 2025-05-26 02:00 EDT
===================================================================================== */
// ===================================================================================
// Features : BLE 0x181A service, "B" and "M" OLED indicators for Notify states,
//            RGB LED, buzzer feedback, dynamic re-advertising after disconnect
// Version  : REV 1.6d // 2025-05-29 08:50 PM
// Added Vertual Battery Level Notify (changes the Level cuases the notify to fire)
// accepts Subscribes to both Notify's Beep on Connect/Disconnect.
// ===================================================================================
#include <ArduinoBLE.h>
#include <U8x8lib.h>
#define REVISION "REV 1.6d"
#define SENSOR_NODE_NUMBER 4    // each node number should be unique, It is posssible to use the MAC address to derive it also.
#define BUZZER_PIN A3           // Buzzer on Expansion Base
U8X8_SSD1306_128X64_NONAME_HW_I2C oled(U8X8_PIN_NONE);    // OLED on DEV Base
BLEService envService("181A");
BLEUnsignedCharCharacteristic tempChar("2A6E", BLERead);
BLEUnsignedCharCharacteristic humidityChar("2A6F", BLERead);
BLEUnsignedCharCharacteristic batteryChar("2A19", BLERead | BLENotify);
BLEUnsignedCharCharacteristic motionChar("2A56", BLERead | BLENotify);
int batteryLevel = 99;
unsigned long lastBatteryUpdate = 0;
bool batteryNotifySubscribed = false;
bool motionNotifySubscribed = false;
int scrollOffset = 0;
unsigned long lastScrollUpdate = 0;
unsigned long lastFlashTime = 0;
bool flashState = false;
void initdisplay() {
  pinMode(LEDR, OUTPUT);
  pinMode(LEDG, OUTPUT);
  pinMode(LEDB, OUTPUT);
  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(BUZZER_PIN, OUTPUT);
  digitalWrite(LEDR, HIGH);
  digitalWrite(LEDG, HIGH);
  digitalWrite(LEDB, HIGH);
  digitalWrite(BUZZER_PIN, LOW);
}
void setLedRGB(bool red, bool green, bool blue) {
  digitalWrite(LEDR, red ? LOW : HIGH);
  digitalWrite(LEDG, green ? LOW : HIGH);
  digitalWrite(LEDB, blue ? LOW : HIGH);
}
void drawCenteredNodeNumber() {
  oled.setFont(u8x8_font_inb33_3x6_r);
  String numStr = String(SENSOR_NODE_NUMBER);
  uint8_t col = (numStr.length() == 1) ? 5 : 4;
  oled.drawString(col, 2, numStr.c_str());
  oled.setFont(u8x8_font_7x14_1x2_r);
  oled.drawString(9, 2, batteryNotifySubscribed ? "B" : " ");
  oled.setFont(u8x8_font_7x14_1x2_r);
  oled.drawString(9, 5, motionNotifySubscribed ? "M" : " ");
  oled.setFont(u8x8_font_chroma48medium8_r);
  oled.drawString(2, 7, "Connected     ");
}
void setup() {
  Serial.begin(115200);
  delay(2000);
  printBuildInfo();
  Serial.println("\nPower ON\n");
  startsound();
  oled.begin();
  oled.setFlipMode(1);
  oled.clear();
  oled.setFont(u8x8_font_chroma48medium8_r);
  oled.drawString(0, 0, "Power ON");
  initdisplay();
  setLedRGB(false, true, false);  // GREEN
  delay(1500);
  oled.clear();
  oled.setFont(u8x8_font_7x14_1x2_r);
  oled.drawString(2, 0, "SensorNode");
  drawCenteredNodeNumber();
  oled.setFont(u8x8_font_chroma48medium8_r);
  oled.drawString(2, 7, "Advertising");
  setLedRGB(false, false, true);  // BLUE
  if (!BLE.begin()) {
    oled.drawString(0, 6, "BLE Failed");
    while (1);
  }
  String nodeName = "SensorNode" + String(SENSOR_NODE_NUMBER);
  BLE.setLocalName(nodeName.c_str());
  BLE.setDeviceName(nodeName.c_str());
  BLE.setAdvertisedService(envService);
  envService.addCharacteristic(tempChar);
  envService.addCharacteristic(humidityChar);
  envService.addCharacteristic(batteryChar);
  envService.addCharacteristic(motionChar);
  BLE.addService(envService);
  tempChar.writeValue(77);
  humidityChar.writeValue(55);
  batteryChar.writeValue(batteryLevel);
  motionChar.writeValue(0);
  BLE.advertise();
  Serial.println(nodeName + " advertising...");
}
void loop() {
  BLEDevice central = BLE.central();
  if (central) {
    oled.drawString(0, 7, "               ");
    oled.drawString(2, 7, "Connected     ");
    Serial.print("Connected to: ");
    Serial.println(central.address());
    beepConnected();
    while (central.connected()) {
      unsigned long now = millis();
      // Battery Notify + Simulate Drop every 25 sec
      if (batteryChar.subscribed() && now - lastBatteryUpdate > 25000) {
        lastBatteryUpdate = now;
        batteryLevel -= random(1, 3);
        if (batteryLevel < 70) batteryLevel = 99;
        batteryChar.writeValue(batteryLevel);
        Serial.print("Battery Level: ");
        Serial.println(batteryLevel);
      }
      // Detect notify subscription state changes
      bool currentBatterySubscribed = batteryChar.subscribed();
      bool currentMotionSubscribed = motionChar.subscribed();
      if (currentBatterySubscribed != batteryNotifySubscribed ||
          currentMotionSubscribed != motionNotifySubscribed) {
        batteryNotifySubscribed = currentBatterySubscribed;
        motionNotifySubscribed = currentMotionSubscribed;
        drawCenteredNodeNumber();
      }
      if (now - lastFlashTime > 15000) {
        lastFlashTime = now;
        setLedRGB(false, true, true);
        delay(300);
        setLedRGB(false, false, false);
      }
      delay(100);
    }
    // --- DISCONNECT HANDLING + BLE RE-INIT ---
    oled.setFont(u8x8_font_7x14_1x2_r);
    oled.drawString(9, 2, " ");  // Clear B
    oled.setFont(u8x8_font_chroma48medium8_r);
    oled.drawString(9, 5, " ");  // Clear M
    oled.drawString(0, 7, "Disconnected  ");
    setLedRGB(true, false, false);
    beepDisconnected();
    delay(10000);
    batteryNotifySubscribed = false;
    motionNotifySubscribed = false;
    batteryChar.unsubscribe();
    motionChar.unsubscribe();
    BLE.stopAdvertise();
    delay(200);
    String nodeName = "SensorNode" + String(SENSOR_NODE_NUMBER);
    BLE.setLocalName(nodeName.c_str());
    BLE.setDeviceName(nodeName.c_str());
    BLE.setAdvertisedService(envService);
    BLE.advertise();
    oled.drawString(0, 7, "               ");
    scrollOffset = 0;
    lastScrollUpdate = millis();
    Serial.println("Disconnected.");
    Serial.println("Re-advertising as: " + nodeName);
  }
  unsigned long now = millis();
  if (!BLE.connected() && (now - lastScrollUpdate > 200)) {
    lastScrollUpdate = now;
    oled.drawString(0, 7, "               ");
    String scrollText = "     Advertising     ";
    int windowSize = 11;
    if (scrollOffset >= scrollText.length()) scrollOffset = 0;
    String view;
    if (scrollOffset + windowSize <= scrollText.length()) {
      view = scrollText.substring(scrollOffset, scrollOffset + windowSize);
    } else {
      int firstPart = scrollText.length() - scrollOffset;
      view = scrollText.substring(scrollOffset);
      view += scrollText.substring(0, windowSize - firstPart);
    }
    oled.drawString(0, 7, view.c_str());
    scrollOffset++;
    flashState = !flashState;
    setLedRGB(false, false, flashState);
  }
}
void startsound() {
  tone(BUZZER_PIN, 890); delay(220); noTone(BUZZER_PIN); delay(20);
  tone(BUZZER_PIN, 800); delay(220); noTone(BUZZER_PIN); delay(20);
  tone(BUZZER_PIN, 800); delay(220); noTone(BUZZER_PIN); delay(20);
  tone(BUZZER_PIN, 990); delay(420); noTone(BUZZER_PIN); delay(20);
}
void beepConnected() {
  tone(BUZZER_PIN, 880); delay(250); noTone(BUZZER_PIN);
}
void beepDisconnected() {
  delay(200);
  tone(BUZZER_PIN, 480); delay(300); noTone(BUZZER_PIN);
}
void printBuildInfo() {
  String filename = String(__FILE__);
  int lastSlash = filename.lastIndexOf('/');
  if (lastSlash == -1) lastSlash = filename.lastIndexOf('\\');
  String sketchName = filename.substring(lastSlash + 1);
  Serial.println("\n=== Build Info ===");
  Serial.println("Sketch: " + sketchName);
  Serial.println("Version: " + String(REVISION));
  Serial.println("Compiled: " + String(__DATE__) + " at " + String(__TIME__));
  Serial.println("==================\n");
}
Full Screen, you can see the serial port messages from the SensorNode_4 in the IDE.













