web-dev-qa-db-ja.com

Android、iOS、Win8用のBluetooth低エネルギー接続パラメーター

私は、これら3つのオペレーティングプラットフォームすべてで機能する必要なBluetooth接続パラメーターをあちこちで探してきました。このプロジェクトでは、HOGP(Bluetooth over HID GATT)プロファイルを使用しています。

私のプロジェクトは、接続用の次のパラメーターを制御できるBLEモジュールを使用して自分で作成した組み込みシステムです。

  1. 接続間隔最小
  2. 最大接続間隔
  3. スレーブレイテンシ
  4. 監視タイムアウト
  5. 広告間隔最小
  6. 最大広告間隔

接続するターゲットデバイスは、Android> = 4.3、iOS7、および> = Win8.1との接続を満たすことです。

Appleは親切にも、以下のリンクの22ページに適切なパラメータを含むドキュメントを提供してくれました。 AndroidおよびWin 8に関する情報を見つけることができませんでした。

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

フリーウェアlightBlueとの双方向通信で完全にテストされたiOS7の現在の作業設定は次のとおりです。 iOS7用の埋め込みコードとホストソフトウェアは機能します。

  1. 接続間隔最小30ms
  2. 接続間隔最大56.25ms
  3. スレーブレイテンシー3
  4. 監視タイムアウト5000ms

別のスタックオーバーフローページから、Androidは次のリンクから7.5msの接続間隔で動作すると言われています。

  1. Android BLE接続時間間隔
  2. http://processors.wiki.ti.com/index.php/Bluetooth_SensorTag?DCMP=lprf-stdroid&HQS=lprf-stdroid-pr-wiki1#Supported_Android_devices

残念ながら、Apple iOS仕様の2番目の要件は、「間隔最小≥20ミリ秒」です。

私はこれらの範囲またはそれらがどのように解釈されるのか理解していませんか? Android=の間隔の最小値を7.5msに設定すると、リンゴの要件は無効になりますか?可能であれば、両方のシステムとWin8をどのように満たすことができますか?

私の理解では、スレーブデバイスは最小値と最大値の間に推奨設定を提供し、マスター(スマートフォン)はその範囲で実際に選択された値をユーザーに警告します。

この問題についての助けに感謝し、この投稿がBLEのかなり新しく不完全な知識ベースを検討している他の人に役立つことを願っています。

前もって感謝します!

15
bassplayer142

まず、接続間隔は、両方のデバイスが同じ周波数を使用してデータを転送する時間枠を定義します。合計37のデータチャネルがあり、接続されたデバイスは接続間隔ごとにそれらをホップします。

したがって、両方のデバイスは、同期する、つまり接続するために、最初からこれらのパラメータの正確な値について合意する必要があります。

次に、接続が確立されると、マスター(またはCentral)がサポートする接続パラメーターを送信します。他のデバイス(または周辺機器)は、盲目的にそれらを取得します。 iOSは、デフォルトで接続間隔を30ミリ秒に設定します。接続が確立された後、周辺機器は、ガイドラインに従って最小値と最大値を定義することにより、接続パラメータの更新を要求できますAppleが提供します。受信部分、この場合はiOSを読んでください。 [min; max]の間で最適なものをすべて選択し、選択した正確な値で応答を返します。値がガイドラインに準拠していない場合は、要求を拒否することもできます。

最後に、7.5msは、Bluetooth仕様で定義されている接続間隔の最小の長さです。最大値は4秒です。低いほど帯域幅は広くなりますが、消費電力は高くなります。そして、より高い値では反対です。最適な値は、特定のアプリケーションによって異なります。 HIDプロファイルを使用していることを考えると、レイテンシーは重要だと思います。

iOSは、20msまでの接続間隔をサポートしていると述べています(ただし、これを実現するのは難しい場合もありました)が、あなたのケース(HIDプロファイル)では、11.25 msも許可しています。

お役に立てば幸いです。

13
ildarM

Android(CentralからPeripheralへのリクエスト)のパラメーターを変更するには、次のようにします。

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;
}

Android 5台のデバイスを周辺機器と中央機器の両方として使用しても機能しなかったと言わなければなりません。これは、Generic Acces Service(0x1800)が私のデバイスで優先接続パラメーターの特性0x2a04を提供していないためです。 。0x2a00(デバイス名)と0x2a01(外観)のみを提供しています。参照:

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

この特性は、セントラルデバイスに情報を提供することのみを目的としていると思います。それが一般的に読み取り専用である理由です(私にとって、そしてcxphong)。ビンゲンの答えは普遍的に機能するわけではなく、そのように機能することを意図しているのかどうかはわかりません。実際に誰かが特定のデバイスで動作するようにしましたか?

AndroidおよびiOSはこの読み取り専用特性の情報を参照しないため、非常に有用であるかどうかは不明です。

サイプレス周辺機器とAndroid中央。同様のアプローチが他のデバイスでも機能するはずです。

  1. ペリフェラルでは、CYBLE_GAP_CONN_UPDATE_PARAM_T構造体「params」で優先接続パラメーターを定義します。
  2. GATT接続後、CYBLE_EVT_GATT_CONNECT_INDイベントハンドラー(たとえば)で、CyBle_L2capLeConnectionParamUpdateRequest(connHandle、&params)を呼び出します。

中央側では、何もすることはありません。リクエストを受信すると、少し遅れてパラメータの更新を開始します。

乾杯、

デビッド

0
davhoo