コグノスケ


link 未来から過去へ表示(*)  link 過去から未来へ表示

link もっと前
2024年3月14日 >>> 2024年3月14日
link もっと後

2024年3月14日

JavaとM5Stamp C3とBluetooth LE - Bluetoothデバイスとの通信

目次: Arduino

M5Stamp C3をBluetooth LEデバイスにして、Linux PCもしくはRaspberry PiなどのLinux SBCとお話する取り組みの続編です。

今回はbluez-dbusを使ってBluetoothデバイスと通信します。

データ通信の仕組み

前回の話と少し重複しますが、Bluetoothデバイス特にBLEデバイスとはGATTプロファイルを使って通信します。BLEデバイスはサーバーになります。サーバーはService(=提供する機能)を1つもしくは複数持っていて、Service、Characteristic、ValueとDescriptorが入れ子の構造になっています。

GATTサーバー(BLEデバイス)
Service
Characteristic
  • Value
  • Descriptor
  • Descriptor
  • ...

GATTのデータ送受信はCharacteristicのValueを読み書きすることで実現します。まずは簡単な送信側(Write)からご紹介します。

送信の方法、クライアント→サーバー(BLEデバイス)

private BluetoothGattCharacteristic GattTx;

byte[] dat = new byte[len];

//送信するデータを用意する
//...

GattTx.writeValue(bpart, null);

バイト配列を用意してwriteValue()を呼びます。書き換え属性を持っているCharacteristicでないと書き込みが失敗します。

次は受信側(Read)です。writeValue()と同様にreadValue()も用意されていて、最後にReadした値を読み出せます。しかし一度読んだ値なのか新しい値なのか区別が付きません、つまり値の更新の有無がわかりません。

最新の値を読む方法、サーバー(BLEデバイス)→クライアント

BluetoothGattCharacteristic GattRx;

byte[] dat = GattRx.readValue(null);

ではこの方法はダメなのか?というとそんなことはありません。一定時間ごとに現在値を見たい場合、例えば「温度計の値を1分ごとに読み出す」といった用途で役立ちます。

一方でストリームデータを扱う場合、新しい値がきたときだけ読み出したいので更新を検出する必要があります。検出には少しややこしい処理が必要です。bluez-dbusは何かの状態変化が起きるとPropertiesChangedというイベントで知らせてくることを利用します。使い方は、

  • AbstractPropertiesChangedHandlerを継承したハンドラクラスを作成
  • ハンドラクラスのインスタンスをDeviceManagerに登録
  • BluetoothGattCharacteristicのstartNotify()を呼ぶ(BLEデバイスからのNotifyを検知できるようになる)

コードで書くと下記のようになります。

状態変化イベントのハンドラ登録

public class PropertiesChangedHandler extends AbstractPropertiesChangedHandler {
    @Override
    public void handle(Properties.PropertiesChanged props) {
    }
}

BluetoothGattCharacteristic GattRx;

DeviceManager deviceManager = DeviceManager.getInstance();
PropertiesChangedHandler handler = new PropertiesChangedHandler(...);
deviceManager.registerPropertyHandler(handler);

GattRx.startNotify();

PropertiesChangedハンドラはCharacteristicsの値の更新も、別の関係ないイベントも何でも受け取るので、何のイベントが発生したか判定する必要があります。bluez-dbusのBluetoothGattCharacteristicクラスと、PropertiesChangedクラスはいずれもD-Busのパス(/org/bluez/hci0/dev_xx_xx_xx_xx_xx_xx/service0028/char0029のような文字列)を返すメソッドを持っていますので、D-Busのパスが一致するかどうかで確かめます。

変化した値と名前のMapをgetPropertiesChanged()で取得できるので、全要素を調べて名前がValueであり、バイト配列を保持していればCharacteristicの値の変化を通知するイベントのはずです。

イベントの種類の判別(簡易版)

BluetoothGattCharacteristic GattRx;

Map<String, Variant<?>> mapProp = props.getPropertiesChanged();

if (GattRx.getDbusPath().equalsIgnoreCase(props.getPath())) {
    for (Map.Entry<String, Variant<?>> e : mapProp.entrySet()) {
        if (e.getValue().getValue() instanceof byte[]) {
            dat = (byte[])e.getValue().getValue();
        }
    }
}

自分でBLEデバイス側の実装をしているなら、意図しないイベントが混ざることはありません。上記のコードのように簡素なチェック(例えば単にバイト配列かどうかだけチェック)でも動作するはずです。

編集者:すずき(2024/03/16 23:03)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



link もっと前
2024年3月14日 >>> 2024年3月14日
link もっと後

管理用メニュー

link 記事を新規作成

<2024>
<<<03>>>
-----12
3456789
10111213141516
17181920212223
24252627282930
31------

最近のコメント5件

  • link 14年6月13日
    2048player...さん (09/26 01:04)
    「最後に、この式を出すのに紙4枚(A4)も...」
  • link 14年6月13日
    2048playerさん (09/26 01:00)
    「今のところ最も簡略化した式です。\n--...」
  • link 14年6月13日
    2048playerさん (09/16 01:00)
    「返信ありがとうございます。\nコメントが...」
  • link 14年6月13日
    すずきさん (09/12 21:19)
    「コメントありがとうございます。同じ結果に...」
  • link 14年6月13日
    2048playerさん (09/08 17:30)
    「私も2048の最高スコアを求めたのですが...」

最近の記事3件

  • link 24年9月14日
    すずき (09/22 11:23)
    「[OpenSBIを調べる - scratch領域の詳細] 目次: Linux今回はOpenSBIのコード内に頻出するscrat...」
  • link 21年8月11日
    すずき (09/22 00:15)
    「[Kindle - まとめリンク] 目次: Kindle初代Kindle Fire HDの話。Kindle Fire HDのカ...」
  • link 24年8月11日
    すずき (09/22 00:14)
    「[Amazonマイリストへの問い合わせの返事がきた] 目次: Kindle先日(2024年8月4日の日記参照)Amazonへ問...」
link もっとみる

こんてんつ

open/close wiki
open/close Linux JM
open/close Java API

過去の日記

open/close 2002年
open/close 2003年
open/close 2004年
open/close 2005年
open/close 2006年
open/close 2007年
open/close 2008年
open/close 2009年
open/close 2010年
open/close 2011年
open/close 2012年
open/close 2013年
open/close 2014年
open/close 2015年
open/close 2016年
open/close 2017年
open/close 2018年
open/close 2019年
open/close 2020年
open/close 2021年
open/close 2022年
open/close 2023年
open/close 2024年
open/close 過去日記について

その他の情報

open/close アクセス統計
open/close サーバ一覧
open/close サイトの情報

合計:  counter total
本日:  counter today

link About www2.katsuster.net
RDFファイル RSS 1.0

最終更新: 09/26 01:04