BLEでペリフェラルを操作する

とりあえずAndroid DeveloperにあるBLEのサンプル(BluetoothLeGatt | Android Developers)をいじって、ペリフェラルのスキャン => 接続 => Characteristic の取得 => HRPで心拍数を取得する処理の流れはひととおりわかった(気がする)。

HRPは心拍数が変わったら通知するだけの単純なプロファイルらしく、あんまり応用がない。


というわけで Characteristic で read/writeしたいのだが、下記のサイトが参考になった。


BLEの拡張プロファイルについては下記が参考になりそう。


【BLEを使う】GATT(Generic Attribute Profile)概要 - 叶鋼は午前1時に計算をする



Android と BLESerial をつなげた例。サンプルコードあり。


浅草ギ研 ArduinoとAndroid端末をBLEでつないでみる

任意のcharacteristicのnotificationをenable/disableする疑似コード

    BluetoothGattCharacteristic characteristic; // 任意のcharacteristic
    boolean enable;
    
    int charaProp = characteristic.getProperties();
    if ((charaProp | BluetoothGattCharacteristic.PROPERTY_READ) > 0) {
        // このcharacteristicは read に対応している
        enable = false;

        mBluetoothGatt.setCharacteristicNotification(characteristic, enabled);

        mBluetoothGatt.readCharacteristic(characteristic);
        // このcharacteristicに対してreadのリクエストを送る
        // 非同期に BluetoothGattCallback#onCharacteristicRead(BluetoothGatt, BluetoothGattCharacteristic, int) がコールバックされる
    }

    if ((charaProp | BluetoothGattCharacteristic.PROPERTY_NOTIFY) > 0) {
        // このcharacteristicは notification に対応している
        enable = true;

        mBluetoothGatt.setCharacteristicNotification(characteristic, enabled);

        BluetoothGattDescriptor descriptor = characteristic.getDescriptor(
            UUID.fromString("00002902-0000-1000-8000-00805f9b34fb"));
        descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
        // characteristicの設定を行うときに指定するUUIDは "00002902-0000-1000-8000-00805f9b34fb" の固定値
        // 対向の BLE peripheral の notification 機能を有効化するため、この characteristic の descriptor に対して BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE を設定する

        mBluetoothGatt.writeDescriptor(descriptor);
        // 設定した descriptor を書き込む
        // 非同期に BluetoothGattCallback#onCharacteristicChanged(BluetoothGatt, BluetoothGattCharacteristic) がコールバックされる
    }

使っているAPI:

  • boolean BluetoothGatt#setCharacteristicNotification(BluetoothGattCharacteristic characteristic, boolean enable)
  • BluetoothGattDescriptor BluetoothGattCharacteristic#getDescriptor(UUID uuid)
    • characteristicの設定を行うときに指定するUUIDは "00002902-0000-1000-8000-00805f9b34fb" の固定値
  • BluetoothGattDescriptor#setValue(byte[] bytes)
    • BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE を設定
  • BluetoothGatt#writeDescriptor(BluetoothGattDescriptor descriptor)

BLE peripheral へバイト列を書き込む模擬コード

    byte[] bytes = { … }; // 書き込むバイト列
    
    BluetoothGattService myService = mBluetoothGatt.getService(UUID.fromString("<Service UUID>"));
    BluetoothGattCharacteristic characteristic = myService.getCharacteristic(UUID.fromString("<Characteristic UUID>"));
    characteristic.setValue(bytes);
    mBluetoothGatt.writeCharacteristic(characteristic);

使っているAPI:

  • BluetoothGattService BluetoothGatt#getService(UUID uuid)
    • 引数は対向 BLE peripheral の Service UUID
  • BluetoothGattCharacteristic BluetoothGattService#getCharacteristic(UUID uuid)
    • 引数は対向 BLE peripheral の Service の Characteristic UUID
  • BluetoothGattCharacteristic#setValue(byte[] bytes);
    • 引数は書き込むバイト列
  • boolean BluetoothGatt#writeCharacteristic(BluetoothGattCharacteristic characteristic)
    • 引数は対向 BLE peripheral へ送信する Characteristic