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
-
Heartbeat ogni 2 secondi -
Connection interval 15-30ms (ottimizzato per iOS) -
Re-advertising automatico dopo disconnessione -
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
-
Il connection interval (15-30ms) è appropriato per streaming a 20Hz (16 bytes/pacchetto)?
-
ArduinoBLE su Nicla Sense ME supporta negoziazione MTU?
-
Come posso impostare il supervision timeout esplicitamente?
-
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)