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

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

新規登録して質問してみよう
ただいま回答率
85.48%
Bluetooth

Bluetoothとは短距離の間でデータを交換するための無線通信規格である。固定・モバイル両方のデバイスから、短波の電波送信を行うことで、高いセキュリティをもつパーソナルエリアネットワーク(PAN)を構築する。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

Raspberry Pi

Raspberry Piは、ラズベリーパイ財団が開発した、名刺サイズのLinuxコンピュータです。 学校で基本的なコンピュータ科学の教育を促進することを意図しています。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

368閲覧

Android端末 BLE受信 同じ値を受信し続けてしまう問題[java]

AGLAAGLA

総合スコア54

Bluetooth

Bluetoothとは短距離の間でデータを交換するための無線通信規格である。固定・モバイル両方のデバイスから、短波の電波送信を行うことで、高いセキュリティをもつパーソナルエリアネットワーク(PAN)を構築する。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

Raspberry Pi

Raspberry Piは、ラズベリーパイ財団が開発した、名刺サイズのLinuxコンピュータです。 学校で基本的なコンピュータ科学の教育を促進することを意図しています。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2023/05/26 08:18

編集2023/05/26 10:38

ご覧いただきありがとうございます。
ラズパイ3からandroid(google pixel 6)に数値を10秒おきに増加させ、10秒おきにその数値を送るシステムを作っています。
同じ数値は一度のみしか送りません。
しかし、現在android側の受信で、同じ数字が10秒の間に何度も受信が確認できています。
10秒後、数字は1個増加しますが、また次の数字も10秒間に何度も受信しています。

現在原因分からず、質問させていただきます。
送信側はコメントに掲載しています。

現時点で、一度もonCharacteristicChangedが実行できていないのが問題なのかなと
個人的に考えています...

前提条件

セントラル: Android(google Pixel 6)
ペリフェラル: ラズパイ3

ラズパイ側のプログラムは字数制限で掲載できておりません。
また、java側のプログラムも長文のため、importは省略しております。

java

1public class MainActivity extends Activity { 2 private final static String TAG = MainActivity.class.getSimpleName(); 3 private static final int REQUEST_PERMISSION_CODE = 2; 4 5 private BluetoothAdapter mBluetoothAdapter; 6 private BluetoothLeScanner mBluetoothLeScanner; 7 private BluetoothGatt mBluetoothGatt; 8 private boolean mScanning; 9 10 private static final UUID MY_SERVICE_UUID = UUID.fromString("00001111-0000-1000-8000-00805F9B34FB"); 11 private static final UUID MY_CHARACTERISTIC_UUID = UUID.fromString("00002211-0000-1000-8000-00805F9B34FB"); 12 13 @Override 14 protected void onCreate(Bundle savedInstanceState) { 15 super.onCreate(savedInstanceState); 16 17 // BluetoothManagerを取得し、アダプターを取得する。 18 final BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE); 19 mBluetoothAdapter = bluetoothManager.getAdapter(); 20 Log.d(TAG, "111"); 21 // BLEがサポートされているか確認する。 22 if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) { 23 finish(); 24 } 25 26 mBluetoothLeScanner = mBluetoothAdapter.getBluetoothLeScanner(); 27 requestPermissions(); 28 29 } 30 31 private void requestPermissions() { 32 List<String> permissionsNeeded = new ArrayList<>(); 33 if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { 34 permissionsNeeded.add(Manifest.permission.ACCESS_FINE_LOCATION); 35 } 36 if (ContextCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_SCAN) != PackageManager.PERMISSION_GRANTED) { 37 permissionsNeeded.add(Manifest.permission.BLUETOOTH_SCAN); 38 } 39 if (ContextCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) { 40 permissionsNeeded.add(Manifest.permission.BLUETOOTH_CONNECT); 41 } 42 43 if (!permissionsNeeded.isEmpty()) { 44 ActivityCompat.requestPermissions(this, permissionsNeeded.toArray(new String[0]), REQUEST_PERMISSION_CODE); 45 } else { 46 scanLeDevice(true); 47 } 48 } 49 50 51 private void scanLeDevice(final boolean enable) { 52 if (enable) { 53 54 if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.BLUETOOTH_SCAN) != PackageManager.PERMISSION_GRANTED) { 55 56 return; 57 } 58 Log.d(TAG, "222"); 59 mBluetoothLeScanner.startScan(mLeScanCallback); 60 mScanning = true; 61 } else { 62 mBluetoothLeScanner.stopScan(mLeScanCallback); 63 mScanning = false; 64 } 65 } 66 67 // スキャンのコールバック。 68 private ScanCallback mLeScanCallback = new ScanCallback() { 69 @Override 70 public void onScanResult(int callbackType, ScanResult result) { 71 super.onScanResult(callbackType, result); 72 // スキャン結果から、デバイスを取得し、Gattサーバーへ接続する。 73 BluetoothDevice device = result.getDevice(); 74 if (String.valueOf(device).equals("B8:27:EB:F1:9C:71")) { // 指定されたMACアドレスと比較 研究室用 75 //if (String.valueOf(device).equals("B8:27:EB:98:26:06")) { // 指定されたMACアドレスと比較 家用 76 if (ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) { 77 return; 78 } 79 Log.d(TAG, device.getName()); 80 Log.d(TAG, "find!!!"); 81 if (ActivityCompat.checkSelfPermission(MainActivity.this, android.Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) { 82 Log.d(TAG, "許可がないよ1"); 83 return; 84 } 85 Log.d(TAG, "333"); 86 mBluetoothGatt = device.connectGatt(MainActivity.this, false, mGattCallback); 87 } 88 } 89 }; 90 91 // Gattコールバック。 92 private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { 93 @Override 94 public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) { 95 Log.d(TAG, "444"); 96 if (status == BluetoothGatt.GATT_SUCCESS && newState == BluetoothGatt.STATE_CONNECTED) { 97 Log.d(TAG, "555"); 98 // GATTサーバーに接続成功。サービスを探索する。 99 if (ActivityCompat.checkSelfPermission(MainActivity.this, android.Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) { 100 return; 101 } 102 103 gatt.discoverServices(); 104 Log.d(TAG, "666"); 105 } else { 106 // GATTサーバーへの接続が切断または失敗。スキャンを再開する。 107 Log.d(TAG,"切れちゃった"); 108 scanLeDevice(true); 109 } 110 111 } 112 113 @Override 114 public void onServicesDiscovered(BluetoothGatt gatt, int status) { 115 Log.d(TAG, "1111111"); 116 // 対象のサービスとキャラクタリスティックを見つけ、Notificationをセットする。 117 if (status == BluetoothGatt.GATT_SUCCESS) { 118 Log.d(TAG, "777"); 119 BluetoothGattService service = gatt.getService(MY_SERVICE_UUID); 120 Log.d(TAG, "888"); 121 if (service != null) { 122 BluetoothGattCharacteristic characteristic = service.getCharacteristic(MY_CHARACTERISTIC_UUID); 123 Log.d(TAG, "999"); 124 if (characteristic != null) { 125 // Characteristicのプロパティを確認し、必要な処理を実装する 126 int properties = characteristic.getProperties(); 127 if ((properties & BluetoothGattCharacteristic.PROPERTY_READ) != 0) { 128 if (ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) { 129 return; 130 } 131 gatt.readCharacteristic(characteristic); 132 } 133 if ((properties & BluetoothGattCharacteristic.PROPERTY_NOTIFY) != 0) { 134 gatt.setCharacteristicNotification(characteristic, true); 135 BluetoothGattDescriptor descriptor = characteristic.getDescriptor(UUID.fromString("00002902-0000-1000-8000-00805f9b34fb")); 136 descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE); 137 gatt.writeDescriptor(descriptor); 138 139 } 140 } 141 } 142 } 143 } 144 145 @Override 146 public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) { 147 Log.d(TAG, "101010"); 148 Log.d(TAG, String.valueOf(characteristic.getUuid())); 149 if (status == BluetoothGatt.GATT_SUCCESS) { 150 // キャラクタリスティックが読まれた場合、データを取得する。 151 byte[] data = characteristic.getValue(); 152 if (data != null && data.length > 0) { 153 String textData = new String(data, Charset.forName("UTF-8")); 154 Log.i(TAG, "Received data: " + textData); 155 } 156 gatt.readCharacteristic(characteristic); 157 158 } 159 }; 160@Override 161public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) { 162 Log.d(TAG, "Characteristic Changed: " + characteristic.getUuid().toString()); 163 byte[] data = characteristic.getValue(); 164 if (data != null && data.length > 0) { 165 String textData = new String(data, Charset.forName("UTF-8")); 166 Log.i(TAG, "Received data: " + textData); 167 } 168 } 169 }; 170} 171 172

上記のコードを実行すると、以下のようなログが出ます。

Received data: 0 Received data: 0 Received data: 0 Received data: 0 Received data: 0 Received data: 0 Received data: 0 Received data: 0 Received data: 0 Received data: 0 Received data: 0 Received data: 0 Received data: 1 Received data: 1 Received data: 1 Received data: 1 Received data: 1 Received data: 1 Received data: 1 Received data: 1 Received data: 1 Received data: 1 Received data: 1 Received data: 1

気になる質問をクリップする

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

AGLAAGLA

2023/05/26 10:37 編集

送信側(ラズパイ)は文字オーバで入りきらなかったので、以下に示します。 ``` from pybleno import * import time bleno = Bleno() # サービスとキャラクタリスティックのためのUUID APPROACH_SERVICE_UUID = '00001101-0000-1000-8000-00805F9B34FB' APPROACH_CHARACTERISTIC_UUID = '00002201-0000-1000-8000-00805f9b34fb' counter = 0 # グローバル変数として初期化 class ApproachCharacteristic(Characteristic): def __init__(self): Characteristic.__init__(self, { 'uuid': APPROACH_CHARACTERISTIC_UUID, 'properties': ['read', 'notify'], 'value': None }) self._value = str(0).encode() self._updateValueCallback = None def onReadRequest(self, offset, callback): print('ApproachCharacteristic - onReadRequest') callback(result=Characteristic.RESULT_SUCCESS, data=self._value) def onSubscribe(self, maxValueSize, updateValueCallback): print('ApproachCharacteristic - onSubscribe') self._updateValueCallback = updateValueCallback def onUnsubscribe(self): print('ApproachCharacteristic - onUnsubscribe') self._updateValueCallback = None def onStateChange(state): print('on -> stateChange: ' + state) if state == 'poweredOn': bleno.startAdvertising(name='Approach', service_uuids=[APPROACH_SERVICE_UUID]) else: bleno.stopAdvertising() bleno.on('stateChange', onStateChange) approachCharacteristic = ApproachCharacteristic() def onAdvertisingStart(error): print('on -> advertisingStart: ' + ('error ' + error if error else 'success')) if not error: bleno.setServices([ BlenoPrimaryService({ 'uuid': APPROACH_SERVICE_UUID, 'characteristics': [ approachCharacteristic ] }) ]) bleno.on('advertisingStart', onAdvertisingStart) bleno.start() def task(): global counter counter = counter + 1 approachCharacteristic._value = str(counter).encode() if approachCharacteristic._updateValueCallback: print('Sending notification with value: ' + str(approachCharacteristic._value)) approachCharacteristic._updateValueCallback(data=approachCharacteristic._value) print(counter) # 各反復でカウンターの値を表示します while True: task() time.sleep(10) ```
guest

回答1

0

自己解決

自己解決しました。
キャラスタリスティックを有効化し、
ディスクリプタを書き込んだらいけました。

投稿2023/05/26 18:37

AGLAAGLA

総合スコア54

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問