web-dev-qa-db-fra.com

Paramètres de connexion Bluetooth basse consommation pour Android, iOS et Win8

J'ai recherché partout les paramètres de connexion Bluetooth requis qui fonctionneraient pour ces trois plates-formes d'exploitation. J'utilise le profil HOGP (Bluetooth sur HID GATT) pour ce projet.

Mon projet est un système embarqué écrit par moi-même avec un module BLE dans lequel je contrôle les paramètres de connexion suivants. 

  1. Intervalle de connexion min.
  2. Intervalle de connexion max.
  3. Latence des esclaves
  4. Délai de supervision
  5. Intervalle publicitaire min
  6. Intervalle publicitaire maximum

Mes appareils cibles à connecter seront pour satisfaire les connexions avec Android> = 4.3, iOS7 et> = Win 8.1.

Apple a bien voulu donner un document contenant les paramètres appropriés à la page 22 du lien ci-dessous. Je n'ai trouvé aucune information sur Android et Win 8.

https://developer.Apple.com/hardwaredrivers/bluetoothdesignguidelines.pdf

Mes paramètres de travail actuels pour iOS7 ont été entièrement testés avec la communication bidirectionnelle avec le logiciel gratuit lightBlue. Mon code intégré et mon logiciel hôte pour iOS7 fonctionnent.

  1. Intervalle de connexion min. 30ms
  2. Intervalle de connexion maximum 56.25ms
  3. Esclave latence 3
  4. Délai de surveillance 5000ms

J'ai trouvé sur une autre page de débordement de pile qu'Android fonctionne sur un intervalle de connexion de 7,5 ms à partir des liens suivants.

  1. Intervalle de temps de connexion Android BLE
  2. http://processors.wiki.ti.com/index.php/Bluetooth_SensorTag?DCMP=lprf-stdroid&HQS=lprf-stdroid-pr-wiki1#Supported_Android_devices

Malheureusement, la deuxième exigence de la spécification Apple iOS est que "Intervalle minimal ≥ 20 ms".

Est-ce que je ne comprends pas ces plages ou comment elles sont interprétées? Si je règle l’intervalle min à 7,5 ms pour Android, les exigences relatives aux pommes ne seront-elles pas annulées? Comment puis-je satisfaire les deux systèmes et aussi Win8 si possible?

Je crois comprendre que le périphérique esclave propose un réglage suggéré entre les valeurs min et max et que le maître (smartphone) alerte l'utilisateur de la valeur actuellement sélectionnée dans cette plage. 

J'apprécie toute aide concernant ce problème et espère que ce poste profitera à d’autres, compte tenu de la base de connaissances relativement nouvelle et incomplète de BLE.

Merci d'avance!

14
bassplayer142

Tout d'abord, l'intervalle de connexion définit une fenêtre temporelle pendant laquelle les deux appareils utilisent la même fréquence pour transférer des données. Il existe 37 canaux de données au total, et les appareils connectés les traversent à chaque intervalle de connexion.

Ainsi, les deux dispositifs doivent s’accorder sur des valeurs précises pour ces paramètres dès le début afin d’être synchronisés, c’est-à-dire connectés.

Deuxièmement, lorsque la connexion est établie, le maître (ou le central) envoie les paramètres de connexion qu’il prend en charge. L'autre appareil (ou périphérique) les prend aveuglément. iOS par défaut définit l'intervalle de connexion à 30 ms. Une fois la connexion établie, le périphérique peut demander la mise à jour des paramètres de connexion en définissant les valeurs minimale et maximale, conformément aux instructions fournies par Apple. La partie réceptrice, lue iOS dans ce cas, choisira celle qui lui convient le mieux entre [min; max] et renverra la réponse avec les valeurs exactes qu’elle aura choisies. Il peut également rejeter la demande si les valeurs ne sont pas conformes aux instructions.

Enfin, 7,5 ms est la longueur minimale de l'intervalle de connexion défini par la spécification Bluetooth. La valeur maximale est de 4 s. Plus elle est basse, plus la bande passante est élevée, mais la consommation d'énergie est élevée. Et l'inverse dans les valeurs les plus élevées. La meilleure valeur dépend de l'application spécifique. Étant donné que vous travaillez avec un profil HID, je suppose que la latence est importante pour vous.

iOS indique qu'il prend en charge les intervalles de connexion jusqu'à 20 ms (bien que j'aie parfois du mal à y parvenir), mais dans votre cas (profil HID), ils autorisent également 11,25 ms.

J'espère que cela pourra aider.

13
ildarM

Pour modifier les paramètres dans Android (demande du central au périphérique), vous pouvez faire quelque chose comme ceci:

private String CONN_SERVICE_UUID = "00001800-0000-1000-8000-00805f9b34fb";
private static final UUID CONN_CHARACTERISTIC_UUID = UUID.fromString("00002a04-0000-1000-8000-00805F9B34FB");
private static final int CONN_INTERVAL = 0x0006;
private static final int SUPERVISION_TIMEOUT = 0x000A;
private void findServiceForConnectionParams(List<BluetoothGattService> gattServices){
    BluetoothGattService connGattService = filterServices(gattServices, CONN_SERVICE_UUID);
    if (connGattService != null) {
        setConnectionInterval(connGattService);
    }
}
private void setConnectionInterval(BluetoothGattService gattService) {
    if (gattService == null) {
        Log.e(TAG, "setConnectionInterval. Gatt service is null!");
        return;
    }
    BluetoothGattCharacteristic connCharacteristic = 
            gattService.getCharacteristic(CONN_CHARACTERISTIC_UUID);
    if (connCharacteristic != null) {
        byte[] value = { (byte) (CONN_INTERVAL & 0x00FF), // gets LSB of 2 byte value
                (byte) ((CONN_INTERVAL & 0xFF00) >> 8), // gets MSB of 2 byte value
                (byte) (CONN_INTERVAL & 0x00FF),
                (byte) ((CONN_INTERVAL & 0xFF00) >> 8),
                0, 0,
                (byte) (SUPERVISION_TIMEOUT & 0x00FF),
                (byte) ((SUPERVISION_TIMEOUT & 0xFF00) >> 8)
        };
        connCharacteristic.setValue(value);
        boolean status = mBluetoothGatt.writeCharacteristic(connCharacteristic);
        Log.d(TAG, "setConnectionInterval. Change connection interval result: " + status);
    } else {
        Log.e(TAG, "setConnectionInterval. Connection characteristic is null!");
    }

}
private BluetoothGattService filterServices(List<BluetoothGattService> gattServices, String targetUuid) {
    for(BluetoothGattService gattService : gattServices){
        String serviceUUID = gattService.getUuid().toString();
        Log.i(TAG, "serviceUUID: " + serviceUUID);

        if(serviceUUID.equals(targetUuid)){
            Log.i(TAG, "serviceUUID matches! UUID: " + serviceUUID + " Type: " + gattService.getType());
            // no needed, just to check which characteristics are offered
            for(BluetoothGattCharacteristic characteristic : gattService.getCharacteristics()) {
                Log.i(TAG, "serviceUUID characteristics: " + characteristic.getUuid().toString());
            }
            return gattService;
        }
    }
    return null;
}

Je dois dire cependant que cela n'a pas fonctionné pour moi d'utiliser des appareils Android 5 aussi bien périphériques que centraux, car le service d'accès générique (0x1800) ne propose pas dans mon appareil la caractéristique 0x2a04 pour les paramètres de connexion préférés. Il n'offre que 0x2a00 (nom de périphérique) et 0x2a01 (apparence). Références:

http://www.cumulations.com/blogs/7/Doing-firmware-upgrade-over-BLE-in-Android

https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.gap.peripheral_preferred_connection_parameters.xml

https://developer.bluetooth.org/gatt/services/Pages/ServiceViewer.aspx?u=org.bluetooth.service.generic_access.xml

https://farwestab.wordpress.com/2011/02/05/some-tips-on-Android-and-bluetooth/

4
bingen

Je crois que cette caractéristique est uniquement destinée à fournir des informations au périphérique central. C'est pourquoi il est généralement en lecture seule (pour moi et cxphong). La réponse de Bingen ne fonctionne pas universellement, et je ne suis pas sûre qu'elle soit censée fonctionner de cette façon. Quelqu'un l'a-t-il réellement fait fonctionner sur un périphérique spécifique?

Il semble qu'Android et iOS ne consultent pas les informations contenues dans cette caractéristique en lecture seule. Je ne suis donc pas sûr que cela soit très utile.

Ce qui fonctionne pour moi est décrit ci-dessous, pour Cypress Périphérique et Android Central. Une approche similaire devrait fonctionner avec d'autres appareils.

  1. Sur le périphérique, définissez les paramètres de connexion préférés dans une structure "params" CYBLE_GAP_CONN_UPDATE_PARAM_T.
  2. Après la connexion au GATT, dans le gestionnaire d'événements CYBLE_EVT_GATT_CONNECT_IND (par exemple), appelez CyBle_L2capLeConnectionParamUpdateRequest (connHandle, & params).

Sur le côté central, il n'y a rien à faire. Après avoir reçu la demande, il lancera la mise à jour des paramètres un peu plus tard.

À votre santé,

David

0
davhoo