コグノスケ


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

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

2024年3月8日

JavaとM5Stamp C3とBluetooth LE - BluetoothデバイスとServiceの列挙

目次: Arduino

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

今回はbluez-dbusを使ってBluetoothデバイスの列挙、GATTのServiceの列挙を行います。

アダプタとデバイスの列挙

DeviceManagerというクラスとDeviceManagerクラスのスタティックメソッドが、bluez-dbusを使うときの根っこになります。

DeviceManagerのインスタンスを作成するため最初にcreateInstance()を呼ぶ必要があります。1回で良いです。これ以降はDeviceManager.getInstance()でDeviceManagerのインスタンスが取得できます。引数はfalseならシステム全体用のバスインタフェース、trueなら現在のログインセッション用のバスインタフェースに接続します。Bluetoothの仕組みとは関係なくて、Bluezが依存しているD-Busの仕組みが透けて見えています。たぶんfalseで良いはず。

bluez-dbusの初期化、createInstance()の呼び出し

//一番最初に1回呼ぶ
DeviceManager.createInstance(false);

//以降はgetInstance()でDeviceManagerオブジェクトを取得できる
DeviceManager.getInstance();

システムに存在するBluetoothアダプターの一覧を得る方法はこんな感じです。お手軽です。

Bluetoothアダプタの列挙

DeviceManager deviceManager = DeviceManager.getInstance();

List<BluetoothAdapter> adapters = deviceManager.getAdapters();

Bluetoothアダプターを1つ選んだら、Bluetoothデバイスを探して(Discovery)、ある程度時間を置いて見つかったデバイスの一覧を取得します。

Bluetoothデバイスの列挙

BluetoothAdapter adapter;

adapter.startDiscovery();
try {
    Thread.sleep(3000);
} catch (InterruptedException ex) {
    //ignore
}
adapter.stopDiscovery();

List<BluetoothDevice> devices = deviceManager.getDevices(true);

注意点としてはstartDiscovery()とstopDiscovery()の間はある程度の時間を開けないとデバイスが1個も見つかりません。

Serviceの列挙

Bluetoothデバイス特にBLE(Bluetooth Low Energy)デバイスとはGATTプロファイルを使って通信します。BluetoothにはATTプロトコル(Attribute Protocol)という属性をやり取りするプロトコルがあります。GATTはATTプロトコルの上で汎用的(Generic)にデータを通信するための取り決め(プロファイル)になります。

GATTというかATTはクライアント・サーバー方式のプロトコルでして、BLEデバイスはサーバーになります。サーバーはService(=提供する機能)を1つもしくは複数持っています。1つのService内にはCharacteristicが並んでおり、CharacteristicにはValueとDescriptorが並んでいます。こんな感じです。

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

通信に使うのはCharacteristicですが、いきなりCharacteristicを列挙することはできません。上位側にあるServiceから列挙します。Serviceを探すにはconnect()してgetGattServices()を呼びます。connect()とdisconnect()は数秒レベルで時間がかかります。

今回はM5Stamp C3に対してペアリングなしで接続しています。ペアリングなし=通信路の盗聴や乗っ取りをされる可能性があります。今回は特に困らないのでこのまま話を進めますが、盗聴や乗っ取りをされると困る場合はペアリングをする必要があります。ペアリングの方法もご紹介したいですが、今はやり方がわかりません。わかったらまた別の日記にでも書きます。

Serviceの列挙
BluetoothDevice device;
device.connect();
device.refreshGattServices();

List<BluetoothGattService> gattServices = device.getGattServices();

device.disconnect();

GATTのService内のCharacteristicを探すにはgetGattCharacteristics()を呼びます。

Characteristicの列挙

BluetoothGattService srv;
srv.refreshGattCharacteristics();

List<BluetoothGattCharacteristic> gattCharacteristics = srv.getGattCharacteristics();

CharacteristicのDescriptorも取得できます(getGattDescriptors()メソッドを使います)が、今回は特に必要ありませんので列挙するためのコードは割愛します。

送受信の方法はまた今度。

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

コメント一覧

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



2024年3月9日

車のバッテリー完全に死亡で交換かと思いきや

目次:

またまた車のバッテリーが干上がって死にました。写真は撮っていませんが2Vくらいになっていたように思います。

しかし今日はディーラーでの半年点検の日でディーラーに行かなければならないので、ジャンプスタートしてエンジンをかけてディーラーまで行きました。去年買った(2023年4月22日の日記参照)KashimuraのジャンプスターターKD-238が大活躍です。活躍しないほうが本当は良いけど。

ディーラーに辿り着いて車を預けたら、ディーラーの駐車場から動かそうとしたらバッテリーが上がってて動かせなかった、ジャンプスタートしたと言われました。ごめんね……。

ディーラーからの意外な提案

またバッテリー交換で財布が軽くなるな〜と思っていたら、整備士さんからは意外な提案が返ってきました。

  • 一時的にディーラー所有のバッテリーに交換して車を返す
  • 上がった方のバッテリーは1週間掛けて充電してみる
  • バッテリーが充電できたら連絡するからまた来てほしい

とのこと。

バッテリー交換以外の新たなパターンに出会いました。交換して1年、走行距離も1000km程度、バッテリーはこんなに劣化しないはず?と判断したみたいです。たぶん安く何とかしてみたい、というご提案だと理解して素直に承諾しました。

バッテリー復活なるか?いつもと違うので楽しみですね。

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

コメント一覧

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



2024年3月10日

誕生日

早いもので41歳になりました。昨年の日記(2023年3月10日の日記参照)を見ると、コロナの流行を心配していました。

コロナの流行は相変わらずのように思いますが、世の人々はもう対策に疲れたのか、感染リスクを無視して暮らすスタイルが定着したようです。個人的には感染しないに越したことはないので、これからもマスクなど予防は心がけたいと思います。花粉症にもなりたくないし……。

働き方はリモート10割から、リモート:出社=7:3〜5:5くらいの割合に落ち着きつつあります。特にオフィスに用事がなければ行かないなんて、昔では考えられない通勤スタイルですね。

この働き方の利点は「遠隔地に居る人」が気にならなくなることです。オフィスに集まる場合を除けば、家も沖縄も北海道も大して変わらないのです。実際、東京から離れて住んでいる人もいるようですね。

編集者:すずき(2024/03/15 03:34)

コメント一覧

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



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 この記事にコメントする



2024年3月18日

画面のブランクを無効にする

目次: Linux

ROCK 3 model CのDebian bullseyeイメージは10分ほど?放置していると画面が消えてロック画面に戻る設定になっています。これはこれでありがたい動作ですが実験用に使っていてキーボードを繋いでいないことがあるので、ロック画面への移行と、画面が消える動作を無効化する方法をメモしておきます。

ロック画面の設定

ロック画面を無効化するには、Xfce4の[アプリケーション] - [設定] - [スクリーンセーバー](xfce4-screensaver-preferences)の、


xfce4-screensaver-preferences

タブ[ロック画面] - [ロック画面を有効にする]をOFFにすれば良いみたいです。再起動後も設定を覚えてくれています。

画面が消える(DPMS)設定

画面が消える機能はDPMS(Display Power Management Signaling)といって、Xfce4の設定パネルからだと[アプリケーション] - [設定] - [電源管理](xfce4-power-manager-settings)の、


xfce4-power-manager-settings

タブ[ディスプレイ] - [ブランク画面にするまでの時間]などから設定できます。しかしロック画面と違って設定を覚えてくれない?みたいで、再起動すると元に戻ってしまいます。理由が良くわからない……困った。

xsetとXDGで起動時にDPMSを設定

Xfce4は良くわからないので降参して、X Windowに頑張ってもらうことにします。DPMSの状態の設定と取得にはxsetを使います。リモートから実行するなら他のX Window Systemのアプリと同様にDISPLAY=:0などのように、どのディスプレイか指定する必要があります。

DPMSのStandby, Suspend, Offを一気に無効にするにはdpms 0 0 0と指定すれば良いです。DPMSの設定は最後の方に表示されます。

DPMSの状態の設定と取得
$ xset dpms 0 0 0

$ xset -q

Keyboard Control:
  auto repeat:  on    key click percent:  0    LED mask:  00000000
  XKB indicators:
    00: Caps Lock:   off    01: Num Lock:    off    02: Scroll Lock: off
    03: Compose:     off    04: Kana:        off    05: Sleep:       off
    06: Suspend:     off    07: Mute:        off    08: Misc:        off
    09: Mail:        off    10: Charging:    off    11: Shift Lock:  off
    12: Group 2:     off    13: Mouse Keys:  off
  auto repeat delay:  500    repeat rate:  20
  auto repeating keys:  00ffffffdffffbbf
                        fadfffefffedffff
                        9fffffffffffffff
                        fff7ffffffffffff
  bell percent:  50    bell pitch:  400    bell duration:  100
Pointer Control:
  acceleration:  2/1    threshold:  4
Screen Saver:
  prefer blanking:  no    allow exposures:  no
  timeout:  0    cycle:  300
Colors:
  default colormap:  0x20    BlackPixel:  0x0    WhitePixel:  0xffffff
Font Path:
  /usr/share/fonts/X11/misc,/usr/share/fonts/X11/100dpi/:unscaled,/usr/share/fonts/X11/75dpi/:unscaled,/usr/share/fonts/X11/Type1,/usr/share/fonts/X11/100dpi,/usr/share/fonts/X11/75dpi,built-ins
DPMS (Energy Star):
  Standby: 0    Suspend: 0    Off: 0
  DPMS is Disabled

これだけだと再起動すると元に戻ってしまいますから、XDG autostartで毎回起動時に勝手に設定する仕掛けにします。システム全体ならば/etc/xdg/autostart/に、ユーザーごとに設定したいなら.config/autostart/に設定ファイルを作成します。ファイル名は何でも良いですが、今回はxset.desktopという名前にしました。

DPMSを起動時に設定する、xset.desktop
[Desktop Entry]
Name=xset
Comment=Disable DPM
Type=Application
Exec=/usr/bin/xset dpms 0 0 0
X-GNOME-Autostart-Phase=Initialization

ファイルを作成したら再起動して、DPMSが望み通りの設定に変わるか確かめます。

Xfce4の設定パネルからだと[アプリケーション] - [設定] - [セッションと起動](xfce4-session-settings)からも作成&設定できるはずです。たぶん。

編集者:すずき(2024/03/19 11:47)

コメント一覧

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



2024年3月19日

モジュラージャックの規格

目次: Arduino

古くは電話線で、今だとEthernetで良く見かけるモジュラージャックというコネクタとレセプタクルがあります。モジュラージャックの種別はRJなんとか(RJ11など)という名前で呼ばれます。数字が違うと何か違うのは知っていましたが、今まで気にしていませんでした。

最近、趣味で早打ちターゲットを作っていて電子回路&基板を書いているんですが、部品の1つにRJ14(6極4芯)を使っていて、そのときRJ11〜18までRJなんとかシリーズがたくさんあることを知りました。電子回路作成ツールのKiCadの部品リストによれば、下記の種類があるそうです。

  • RJ11: 6P2C(6極2線)
  • RJ12: 6P6C(6極6線)
  • RJ13, RJ14: 6P4C(6極4線)

どの規格で定められているのか?RJなんとかとは何か?RJ13とRJ14は何が違う?と気になったので規格に当たってみました。

1976年の規格、RJなんとか=USOCのこと

最初のどの規格で定められているのか?ですが、RJなんとかは41 FR 28699, July 12, 1976(PDFへのリンク)にて定義されています。古そうだなとは思いましたが、まさか50年前の規格だったとは……。

FR(Federal Register)は連邦官報のことです。FRはPDF形式で配布されていますが、PDF形式と言いつつ中身はスキャン画像の羅列でした。古い文書だと仕方ないですね。ところがOCRを掛けてくれているらしく文字列検索ができます。大変ありがたい。アメリカ政府ありがとう。

次にRJなんとかとは何か?ですが、この記号はUniversal Service Order Code(USOC)です。§68.502の説明を見ると、

§68.502のUSOCの説明
These USOCs are generic telephone company service ordering codes. If a telephone 
subscriber wishes to have the telephone company install a standard jack other 
than the one depicted in § 68.502(a)(1) below, he shall specify the appropriate 
USOC when requesting the installations.

(適当訳)
これらUSOCは一般的な電話会社のサービス注文コードです。電話加入者が電話会社に対し、下記の§68.502(a)(1)に
記載されているジャック以外の標準ジャックの設置を希望する場合は、設置を要求するときに適切なUSOCを指定するものとします。

とあります。§68.502(a)(1)というのはRJ11のことを指しています。RJなんとかは電話会社に設置を頼むときの注文番号だったんですね。へー……。

RJ14は書いてあるがRJ13は見当たらない

次はRJ13とRJ14の違いを調べます。FRからRJ14Cの規格を見つけました、こんな定義です。手書きの図が良い味出してますね。


RJ14の定義

しかしRJ13は載っていませんでした。後で追加された規格なのか?残念ながらRJ13とRJ14の違いはわからないままです……。

Code of Federal Regulationsのほうが見やすいかも

黄ばんだ画像のFR 28699, July 12, 1976より、CFR(Code of Federal Regulations)のTitle 47 Vol.3 1996年(PDFへのリンク)の方が見やすいかもしれません。

日本語だとFR(Federal Register)は連邦官報、CFR(Code of Federal Regulations)は連邦規則集という名前だそうで、CFRはアメリカ政府が発行している規則集です。法律に準ずるものらしいですが、法律の専門家ではないので詳しいことはわかりません。

Title 47はTelecommunicationの話題で、Vol.1からVol.5まであります。Vol.3の一部しか見てないですけど……。

編集者:すずき(2024/04/16 00:07)

コメント一覧

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



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

管理用メニュー

link 記事を新規作成

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

最近のコメント5件

  • link 24年10月1日
    すずきさん (10/06 03:41)
    「xrdpで十分動作しているので、Wayl...」
  • link 24年10月1日
    hdkさん (10/03 19:05)
    「GNOMEをお使いでしたら今はWayla...」
  • link 24年10月1日
    すずきさん (10/03 10:12)
    「私は逆にVNCサーバーに繋ぐ使い方をした...」
  • link 24年10月1日
    hdkさん (10/03 08:30)
    「おー、面白いですね。xrdpはすでに立ち...」
  • link 14年6月13日
    2048player...さん (09/26 01:04)
    「最後に、この式を出すのに紙4枚(A4)も...」

最近の記事3件

  • link 24年10月28日
    すずき (10/30 23:49)
    「[Linuxからリモートデスクトップ] 目次: Linux開発用のLinuxマシンの画面を見るにはいろいろな手段がありますが、...」
  • link 23年4月10日
    すずき (10/30 23:46)
    「[Linux - まとめリンク] 目次: Linux関係の深いまとめリンク。目次: RISC-V目次: ROCK64/ROCK...」
  • link 24年10月24日
    すずき (10/25 02:35)
    「[ONKYOからM-AUDIOのUSB DACへ] 目次: PCかれこれ10年以上(2013年3月16日の日記参照)活躍してく...」
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 www.katsuster.net
RDFファイル RSS 1.0

最終更新: 10/30 23:49