hiro99ma blog

ble: gattlib (6)

2025/05/18

はじめに

前回続きで gattlib で BLE central 操作を行うことを検討している。

現在の問題点は、gattlib のサンプルアプリで接続が1回で成功しないことが多いというところである。

gattlib は Bluez を使っているので、Bluez でうまくいくなら gattlib でうまくいってもおかしくはない。
それがうまくいかないのだから gattlib の使い方がおかしいか、gattlib が Bluez の使い方でうまくいっていないところがあるかのどちらかのはずだ。

ble_scan を別アプリにしたのは、オリジナルだと見つかったデバイスに手当たり次第に接続しようとして、 切断しないまま終わったりするからだ。 自分のデバイスならまだしも、よそ様のデバイスを接続したまま放置してしまうことになると申し訳ない。

bluetoothctl でも発生した

あ、bluetoothctl でも “le-connection-abort-by-local” が何度か発生した。
発生頻度が低い? 単に起きやすいときや起きにくい時がある??

遅い?

接続に失敗しないときも、bluetoothctl で接続するときに比べると遅いように思う。 接続するとデバイス側で LED を点灯させているのだが、接続開始のログから点灯までの時間が長い。

ログに途中経過が出てくるわけでもないので、何をしているのかよくわからないのだ。 ちゃんとやるなら無線のログを取ると良いのだろうが、無線区間で時間がかかるようなことはしないと思うのだよ。
この辺に失敗しやすい理由があるんだろうか? でもそれなら bluetoothctl には影響がないはずだからなあ。

別のUSBドングルで試す

Bluetooth ドングルがあったので、そちらで試そう。
もし違いがあれば、ハードウェアかデバイスドライバかまでは判断できないだろうがハードウェア寄りの理由があることになるだろう。 それなら bluetoothctl でも発生したことの説明も付く。

ドングルを挿すと hci1 として認識はしたのだが、hciconfig で見ると DOWN している。
sudo hciconfig hci1 up としても “Can’t init device hci1: Operation not possible due to RF-kill (132)” と言われる。
rfkill list で見ると、hci1 は soft block が on になっていた。
rfkill unblock bluetooth で解除できた。個別に設定できないんだろうか。

bluetoothctl を使うとして、hci1 はどうやって指定すると良いのだろう?
hci というサブメニューはあるようだが

hciconfig を見ると両方 RUNNING なのだが、hci0 は PSCAN が付いていた。

$ hciconfig
hci1:   Type: Primary  Bus: USB
        BD Address: xx:xx:xx:xx:xx:xx  ACL MTU: 310:10  SCO MTU: 64:8
        UP RUNNING
        RX bytes:1186 acl:0 sco:0 events:65 errors:0
        TX bytes:1067 acl:0 sco:0 commands:65 errors:0

hci0:   Type: Primary  Bus: UART
        BD Address: xx:xx:xx:xx:xx:xx  ACL MTU: 1021:8  SCO MTU: 64:1
        UP RUNNING PSCAN
        RX bytes:694388 acl:735 sco:0 events:24883 errors:0
        TX bytes:96813 acl:602 sco:0 commands:2229 errors:0

PSCAN だからどうこうということはなさそうだ。

bluetoothctl で使われなければ良いだけなので、ここは無難に sudo hciconfig hci0 down で止めておく。

bluetoothctl で “show” すると hci1 のアドレスが出力されていた。 なのでスキャンもそのデバイスで行うと考えて良かろう。
この状態でちゃんと接続できることを確認できた。

次は ble_scan
引数にデバイス名を指定すれば良いので ./ble_scan hci1 でよい。
結果は・・・接続できた。
何回か繰り返したが、今のところエラーなく 1回で接続できている。
そして、接続が早く終わる。 今まで問題としていた点がすべて解決されてしまった。
よかったよかった、ハードウェアの問題だったのだ。

ではなく

・・・などと終わらせてしまってよい話ではないだろう。

このサイトを信用するならば、Raspberry Pi 4 の Bluetooth アンテナは 基板の端っこの方に印刷してある。

周波数が高いほどアンテナは短くなる、だったと思う。 それはともかく、印刷だしアンテナ自体が悪いということはあまりないだろう。 アンテナを基板からはみ出すようになっているのを見たこともあるが、基板の端っこだから問題ないんだろう。
気になるなら外付けアンテナも売られている。

なお、うちの Raspberry Pi 4 は有線 LAN である。 2.4 GHz の干渉を嫌ったとかではなく、趣味の問題だ。

ならば本体の置き方とか周辺の環境に問題があるのかもしれない。
それについては、あまり自信を持って言えない。。。
あまり部屋は広くないけど常時稼働させているので邪魔にならないところに置くとなると、見晴らしの良い場所には置けないのだ。

image

USB で HDD が 2つ、SSD が 1つ繋がっているが、セルフパワーの USBハブを使っているのでまだ大丈夫だろう。 Bluetooth の USBドングルは USBハブにつなげている。
本体ケースは買わず、CPUファンは CPUクーラーの上に直置き。 斜めな環境に回転する物体を置くのはよろしくないので、そこは気にしている(何か壊したことがあるらしい)。
距離は 1メートルほどで遠くないので、その点は悪くない・・・はずだ。

それ以外は、もう Bluetooth のハードウェアとデバイスドライバくらいしか残っていない。
ハードウェアの相性がまったくないとは思わないけど、Bluetooth でそういうのはあるの~?とは思う。 思うが、仕事でも「この端末だと切断されやすい」みたいなレポートが来たことはあったので否定はできないだろう。

あとは、Raspberry Pi 4 が裏で処理をさせているというところか。
Raspberry Pi 4 の演算能力は高いとはいえ、組み込み機器ではないのでスケジューリングにも限界があると思う。 どのくらいデバイスに意識を割いてくれるのかわからないが、指示がないとデバイスだけではできない処理については遅延する可能性があるのではなかろうか。

常時動かしているのはこの辺である。

と書くとものすごく CPU がぶん回されているように見えるが、トータルで CPU 使用率は 30% くらいとなっている。 そのくらいだったら BLE の接続処理くらい十分まかなえそうだが、瞬間的に処理能力を持って行かれたときにだけ発生しているとか?

どれもこれも推測の域を出ないな。

再起動後

その後、Raspberry Pi を再起動して初回から hci1 で行うと失敗した。
やっぱりダメやん・・・と思うのは早計だった。

再起動すると、hci0 が USBドングル、hci1 が本体Bluetooth に切り替わっていたのだった。 なので、hci1 で失敗するというのは以前と同じことをしたというだけのことだ。

わかりづらいので固定にできないだろうか。
ChatGPT 氏に訊くと、デバイスを認識した順番になるそうだ。 本体の方が先になりそうではあるが、今回はそうではなかったことになるし、今後もどうなるかわからん。

提案としては、固定にするというよりも認識させる順番を制御する、ということだった。
これはちょっと面倒だな。

HCI はソケット

gattlib が hci0 などをオープンする流れを見ていたのだが、数字だけ取り出して socket(AF_BLUETOOTH) でオープンするんだね。 この辺は Bluez のライブラリか何かを使うのかと思っていたので意外だった。


 < Top page


コメント(Google Formへ飛びます)

GitHub

X/Twitter

Homepage