質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.69%

GenuinoとAndroidのBLE通信時の、Android側での複数Characteristicデータの常時表示

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,159

tmn

score 11

前提・実現したいこと

現在、AndroidアプリとGenuino101をBLEで繋ぎ、Characteristicの値を変更することで、データの送受信を行っています。
Androidアプリ側で、Genuinoから送信された複数のCharacteristicの値を同時に常時表示したいと考えています。
複数が難しければ2つの値を常時表示でも構いませんので、回答よろしくお願いいたします。

問題点

1つの値を常時表示することには成功しています。
配布されているアプリ(nRFConnect)でGenuinoの情報を見るとGenuino側の設定は間違っていないようです。

Genuino側から複数のデータを送信しても、1つのCharacteristicの値しか表示されません。

常時表示したいCharacteristicの情報をmBluetoothGattに結び付ける必要があると思い、descriptorを複数セットしたものの、最初に宣言したもの(今回の場合はDetectionData)のみ有効になり、1つの値しか表示されません。

該当のソースコード

public class BluetoothLeService extends Service {
/* 該当しそうな部分の抜粋です */
    private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
        @Override
        public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
            String intentAction;
            if (newState == BluetoothProfile.STATE_CONNECTED) {
                intentAction = ACTION_GATT_CONNECTED;
                broadcastUpdate(intentAction);
                Log.e(TAG, "Connected to GATT server.");
                Log.e(TAG, "Attempting to start service discovery:" + mBluetoothGatt.discoverServices());

            } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
                intentAction = ACTION_GATT_DISCONNECTED;
                Log.e(TAG, "Disconnected from GATT server.");
                broadcastUpdate(intentAction);
            }
        }

        @Override
        public void onServicesDiscovered(BluetoothGatt gatt, int status) {
            if (status == BluetoothGatt.GATT_SUCCESS) {
                broadcastUpdate(ACTION_GATT_SERVICES_DISCOVERED);
                BluetoothGattService myService = mBluetoothGatt.getService(UUID.fromString(Genuino_UUID));

                BluetoothGattCharacteristic characteristic = myService.getCharacteristic(UUID.fromString(Reception_DetectionData));
                mBluetoothGatt.setCharacteristicNotification(characteristic, true);
                BluetoothGattDescriptor descriptor = characteristic.getDescriptor(UUID.fromString(CLIENT_CHARACTERISTIC_CONFIG));
                descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
                /* 追加部分 */
                BluetoothGattCharacteristic characteristic2 = myService.getCharacteristic(UUID.fromString(Reception_UsonicData));
                mBluetoothGatt.setCharacteristicNotification(characteristic2, true);
                BluetoothGattDescriptor descriptor2 = characteristic2.getDescriptor(UUID.fromString(CLIENT_CHARACTERISTIC_CONFIG));
                descriptor2.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);

                mBluetoothGatt.writeDescriptor(descriptor);
                mBluetoothGatt.writeDescriptor(descriptor2);

            } else {
                Log.e(TAG, "onServicesDiscovered received: " + status);
            }
        }

        @Override
        public void onCharacteristicRead(BluetoothGatt gatt,
                                         BluetoothGattCharacteristic characteristic,
                                         int status) {
            if (status == BluetoothGatt.GATT_SUCCESS) {
                broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
            }
        }

        @Override
        public void onCharacteristicChanged(BluetoothGatt gatt,
                                            BluetoothGattCharacteristic characteristic) {
            broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
        }
    };

    private void broadcastUpdate(final String action) {
        final Intent intent = new Intent(action);
        sendBroadcast(intent);
    }

    private void broadcastUpdate(final String action,
                                 final BluetoothGattCharacteristic characteristic) {
        final Intent intent = new Intent(action);
        final byte[] data = characteristic.getValue();
        if (data != null && data.length > 0) {
            intent.putExtra(EXTRA_DATA, data);
        }
        sendBroadcast(intent);
    }
public class DeviceControlActivity extends Activity {
    public final BroadcastReceiver mGattUpdateReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            final String action = intent.getAction();
            if (BluetoothLeService.ACTION_GATT_CONNECTED.equals(action)) {
                ConnectionStateText.setText("Connected");
                mConnected = true;
                invalidateOptionsMenu();
            } else if (BluetoothLeService.ACTION_GATT_DISCONNECTED.equals(action)) {
                ConnectionStateText.setText("Disconnected");
                mConnected = false;
                invalidateOptionsMenu();
            } else if (BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED.equals(action)) {

            } else if (BluetoothLeService.ACTION_DATA_AVAILABLE.equals(action)) {
                /* 受信データ表示 */
                byte[] rsvData = intent.getByteArrayExtra(BluetoothLeService.EXTRA_DATA);
                if (rsvData != null) {
                    int sensorValue = convByteToInt(rsvData[0]);
                    CheckState.setText("[" + String.valueOf(sensorValue) + "]");
                }
            }
        }
    };

Genuino側では下記のようにCharacteristicを設定し、detectionData、UsonicDataのCharacteristiの値をAndroid側に送信しています。

BLEService ledService("19B10000-E8F2-537E-4F6C-D104768A1214"); // BLE LED Service
BLEUnsignedCharCharacteristic send_detectionData("19B10001-E8F2-537E-4F6C-D104768A1214", BLERead|BLENotify);
BLEUnsignedLongCharacteristic send_UsonicData("19B10002-E8F2-537E-4F6C-D104768A1214", BLERead|BLENotify);
BLEUnsignedLongCharacteristic read_selectFunction("19B10003-E8F2-537E-4F6C-D104768A1214", BLEWrite);
BLEUnsignedLongCharacteristic read_threshold("19B10004-E8F2-537E-4F6C-D104768A1214", BLEWrite);
BLEUnsignedLongCharacteristic read_instruction("19B10005-E8F2-537E-4F6C-D104768A1214", BLEWrite);
#include <CurieBLE.h>

BLEService ledService("19B10000-E8F2-537E-4F6C-D104768A1214"); // BLE LED Service

BLEUnsignedLongCharacteristic send_detectionData("19B10001-E8F2-537E-4F6C-D104768A1214", BLERead|BLENotify);
BLEUnsignedLongCharacteristic send_UsonicData("19B10002-E8F2-537E-4F6C-D104768A1214", BLERead|BLENotify);
BLEUnsignedLongCharacteristic read_selectFunction("19B10002-E8F2-537E-4F6C-D104768A1214", BLEWrite);
BLEUnsignedLongCharacteristic read_threshold("19B10003-E8F2-537E-4F6C-D104768A1214", BLEWrite);
BLEUnsignedLongCharacteristic read_instruction("19B10004-E8F2-537E-4F6C-D104768A1214", BLEWrite);

void setup() {
  Serial.begin(9600);

  BLE.begin();
  BLE.setLocalName("BLETest");

  BLE.setAdvertisedService(ledService);
  ledService.addCharacteristic(send_detectionData);
 ledService.addCharacteristic(send_UsonicData);
  ledService.addCharacteristic(read_selectFunction);
  ledService.addCharacteristic(read_threshold);
  ledService.addCharacteristic(read_instruction);
  BLE.addService(ledService);
  BLE.advertise();

  Serial.println("BLE LED Peripheral");
}

void loop() {
  BLEDevice central = BLE.central();

  if (central) {
    Serial.print("Connected to central: ");
    Serial.println(central.address());

    while (central.connected()) {
      send_detectionData.setValue(1);      
      delay(100);
      send_UsonicData.setValue(2);      
      delay(100);
    }

    Serial.print(F("Disconnected from central: "));
    Serial.println(central.address());
  }
}
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

check解決した方法

0

Genuino側からのCharacteristicの値を、Android側で複数表示する必要がなくなったため、今まで通りGenuinoからの送信は一つのみで実行したいと思います

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

Genuinoは純粋なarduinoとは違うものとの認識を当方ではしています。
絶対にGenuinoを使用になるのであれば、それは両者の違いを熟知する必要があると考えます。
貴殿の対象となる処理では通信(シリアル)を伴っていると予測します。

多くに方がシリアル通信(USB含む)で表記法がArduinoと異なると記載されているようです。

まず確実に目標を達成するには、単体とPCでのシリアル通信からかと考えます。
また質問においてPC(Java)側の記載はまあまあですが、Genuino側についてはトピックに見えます。

まずは主処理の動きをまとめられる事を希望します。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/01/23 17:05

    回答ありがとうございます。

    Genuino側では、ArduinoIDEのサンプルCurieBLE⇒Peripheral⇒LEDに変更を加えたものを利用しています。主な変更点はUUID、Characteristic等、LED点灯部分を送信用Characteristicの書き換えに変えている点です。何も難しい動作をしていないので記載が不要かと思い、省略してしまいました。
    Android側では、AndroidStudioのサンプルBluetoothLeGattを改変したものを利用しており、主処理の大きな変更はなく、Characteristicの値を分かりやすく表示するようにしているだけです。

    念のためGenuino側のコードも上げて置きます。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.69%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる