BLE Disconnessioni frequenti tra Arduino Nicla Sense ME e app iOS

Hardware

  • Board: Arduino Nicla Sense ME

  • Sensore: BHI260AP (IMU con sensor fusion integrato)

  • Client: iPhone (iOS 26+)

Il Problema

La connessione BLE si stabilisce correttamente, ma dopo un tempo variabile (da pochi secondi a qualche minuto) si disconnette inaspettatamente. A volte la riconnessione automatica funziona, altre volte devo riavviare il dispositivo.


Configurazione BLE (config.h)

#define DEVICE_NAME                   "MySensor"

// Service & Characteristic UUIDs
#define SERVICE_UUID                  "19B10000-E8F2-537E-4F6C-D104768A1214"
#define DATA_CHAR_UUID                "19B10001-E8F2-537E-4F6C-D104768A1214"
#define EVENT_CHAR_UUID               "19B10002-E8F2-537E-4F6C-D104768A1214"
#define STATUS_CHAR_UUID              "19B10003-E8F2-537E-4F6C-D104768A1214"
#define CONTROL_CHAR_UUID             "19B10004-E8F2-537E-4F6C-D104768A1214"

// BLE timing
#define DATA_INTERVAL_MS              50   // 20 Hz streaming
#define STATUS_INTERVAL_MS            2000 // Heartbeat ogni 2s


Codice BLE Arduino

bool BLEService::begin() {
    if (!BLE.begin()) return false;

    BLE.setDeviceName(DEVICE_NAME);
    BLE.setLocalName(DEVICE_NAME);
    BLE.setAdvertisedService(_service);

    // Connection Parameters per iOS
    BLE.setConnectionInterval(12, 24);  // 15ms - 30ms
    BLE.setAdvertisingInterval(160);    // 100ms

    // Caratteristiche
    _service.addCharacteristic(_dataChar);    // BLERead | BLENotify, 16 bytes
    _service.addCharacteristic(_eventChar);   // BLERead | BLENotify, 8 bytes
    _service.addCharacteristic(_statusChar);  // BLERead | BLENotify, 2 bytes
    _service.addCharacteristic(_controlChar); // BLEWrite, 1 byte

    BLE.addService(_service);
    
    BLE.setEventHandler(BLEConnected, onConnect);
    BLE.setEventHandler(BLEDisconnected, onDisconnect);

    BLE.advertise();
    return true;
}

void BLEService::update() {
    BLE.poll();

    // Advertising watchdog
    if (!_connected && (millis() - _lastAdvRefresh) >= 5000) {
        _lastAdvRefresh = millis();
        BLE.advertise();
    }
}

void BLEService::sendData(const DataPacket& packet) {
    if (!_connected) return;
    _dataChar.writeValue(&packet, sizeof(DataPacket)); // 16 bytes @ 20Hz
}


Struttura Pacchetto (16 bytes @ 20Hz)

struct __attribute__((packed)) DataPacket {
    uint32_t timestamp;
    int16_t  value1;
    uint8_t  state;
    int16_t  quat_w;
    int16_t  quat_x;
    int16_t  quat_y;
    int16_t  quat_z;
    uint8_t  flags;
};


Codice iOS (Swift)

// Connessione
centralManager.connect(peripheral, options: [
    CBConnectPeripheralOptionNotifyOnDisconnectionKey: true,
    CBConnectPeripheralOptionNotifyOnNotificationKey: true
])

// Gestione disconnessione
func centralManager(_ central: CBCentralManager, 
                    didDisconnectPeripheral peripheral: CBPeripheral, 
                    error: Error?) {
    if let error = error {
        print("[BLE] Disconnected: \(error.localizedDescription)")
        reconnect()
    }
}


Cosa ho già provato

  • :white_check_mark: Heartbeat ogni 2 secondi

  • :white_check_mark: Connection interval 15-30ms (ottimizzato per iOS)

  • :white_check_mark: Re-advertising automatico dopo disconnessione

  • :white_check_mark: Auto-reconnect lato iOS

Output Serial durante disconnessione

[BLE] Connected to: XX:XX:XX:XX:XX:XX
... streaming attivo ...
[BLE] Disconnected from: XX:XX:XX:XX:XX:XX
[BLE] Re-advertising...

Domande

  1. Il connection interval (15-30ms) è appropriato per streaming a 20Hz (16 bytes/pacchetto)?

  2. ArduinoBLE su Nicla Sense ME supporta negoziazione MTU?

  3. Come posso impostare il supervision timeout esplicitamente?

  4. Il buffer BLE potrebbe riempirsi troppo velocemente?

Ambiente

  • Arduino IDE 2.x

  • ArduinoBLE 1.3.x

  • Arduino Mbed OS Nicla Boards

  • iOS 26+

  • Xcode 26.2 (17C52)

@Skatedan ,

:warning:
Ti segnalo che, nella sezione in lingua Inglese, si può scrivere SOLO in Inglese ... quindi, per favore, la prossima volta presta più attenzione in quale sezione metti i tuoi post; questa volta esso è stato spostato, da un moderatore della sezione di lingua Inglese, nella sezione di lingua Italiana ... la prossima volta potrebbe venire direttamente eliminato. Grazie.