Orange Pi 3 bluetooth シリアル通信

前回のWiFi設定の記事はあたかもサクッと設定したような内容になっていますが現実はなかなかそうは行きませんね。
使い慣れたnetworkingやdhcpcd5をインストールdhcpcd.confから設定したりと試しましたが繋がっても思ったような挙動になりません。NetworkManagerにしてからは記事の通り比較的スムーズに行きましたが当サイトのOrangePi3(ヘッドレス)はすでに稼働しており繋がらないnetworkになった時最低限の状況確認やshutdownが実行できるようもうひとつの通信手段としてbluetoothのシリアル通信を設定していました。

環境

Raspberry Pi 3(2019-04-08)raspbianデスクトップ
Orange Pi 3 armbian(debian stretch)
Raspberry Pi 3からOrange Pi 3へbluetoothシリアル接続するものとします。

Orange Pi 3 bluetooth

OrangePi3にはAP6256(WIFI+BT)が載っているのですが現時点ではまだ動作していないようです。またbluetoothに関しての有効な情報も得ることができませんでした。
bluetooth deviceは手持ちのbluetoothドングルを使用してみました。
ARM(64bit)用のドライバはまだまだ開発途上なのでraspbianなどで正常に認識してもOrangePi3で使えるとは限らないと思います。

$ hciconfig
bluetooth deviceらしきものが表示されていますが稼働していません。
hci1: BD Addressなどなし


hci0: チップはCSR8510 A10
こちらは正常に認識、接続可能

ペアリング

OrangePi3にbluetoothをインストールします。

# apt install bluetooth bluez-firmware

インストールするとサービスは起動しているはずです。

Raspberry Piには独自のpi-bluetoothがインストールされていて大抵の機器はbluetoothマネージャーからペアリング可能ですがOrangePi3とのペアリングについては少し勝手が違うようです。(以下の方法でペアリングできました)

RaspberryPi3から2つターミナルを開いて1つはOrangePi3にssh接続します。
rootから実行したほうが作業しやすいと思います。

左のターミナルがRaspberryPi3 右がOrangePi3
要領としてはbluetoothctlを実行してお互いに相手のBD deviceを認識したらpairを実行します。pairはどちらから実行しても構いません。
Time outやコマンドの実効でエラーが発生したらbluetoothctlをexitで抜けて最初からやり直します。
画像は1回目失敗した例です。Time outで[del] deviceになっています。

OrangePi3にはsshでログインしておきます。

$ sudo -i
# systemctl restart bluetooth
# bluetoothctl -a
[NEW] Controller 00:1A:7D:DA:71:13 orangepi3 [default]
Agent registered

bluetoothctl -aを実行すると自身のBT IDを表示してbluetoothctlのコマンド待ちになります。
RaspberryPi3はbluetoothctl -a実効後bluetoothマネージャーからMake Discoverable,Add Device…でダイアログを開くと必要なコマンドを実行します。(コマンドラインからでも可)
OrangePi3から実行します。

[bluetooth]# discoverable on
[bluetooth]# pairable on
[bluetooth]# scan on

scan onを実行すると1分位でRaspberryPi3を発見します。
RaspberryPi3側もOrangePi3を自動で探し出しますがもし発見していない場合は同様にscan onを実行します。
[NEW] Controller 00:1A:7D:DA:71:13 orangepi3 [default]
[NEW] Device B8:27:EB:24:C9:19 pi3
双方で自身のIDと相手のIDが見つかればpairが実行可能です。
discoverable: noになったら discoverable onを実行しておきます。

[bluetooth]# pair B8:27:EB:24:C9:19


画像はOrangePi3からpairを実行した例です。(RaspberryPi3のIDを指定)
通信を開始 OrangePi3側にはPairing succsessfulが確認できます。
exitで抜けてPairing完了


RaspberryPi3のダイアログからpairを実行するとエラーになります。コマンドラインから実行する必要があります。

シリアル通信

bluetoothによるシリアル通信を行うためRFCOMMを利用します。

OrangePi3の設定


Sap driver関連にエラーがありますが回避方法は以下にあります。もう1箇所エラーが残りますがこちらはbluezのバグのようです。(気にしなくてOK)
またsdptoolを起動できるようオプションを指定(–compat)
raspberry piも同様でどちらのエラーも特に修正を加えなくても接続には問題ないはずです。

https://www.raspberrypi.org/forums/viewtopic.php?t=131999
/lib/systemd/system/bluetooth.service

ExecStart=/usr/lib/bluetooth/bluetoothd --noplugin=sap --compat

https://bugs.launchpad.net/ubuntu/+source/bluez/+bug/1499858

シリアル接続に関してはデフォルト設定(bluetooth.service)で接続は可能(でした)
channelはデフォルトの1になります。

設定を変更したら

# systemctl daemon-reload
# systemctl restart bluetooth

rfcommの起動
rfcommの待受は/etc/rc.localに設定しました。
/etc/rc.local

rfcomm watch 0 1 agetty rfcomm0 115200 orangepi3 -a root &

exit 0
# systemctl daemon-reload
# systemctl restart rc.local

RaspberryPi3の設定

RaspberryPi3から接続するには/dev/rfcomm0を介して通信するのですがこちらも/etc/rc.localから起動します。
/etc/rc.local

rfcomm bind 0 00:1A:7D:DA:71:13

exit 0

rc.local restart

# systemctl daemon-reload
# systemctl restart rc.local

シリアルコンソール

TTY terminal applicationにはscreen picocom ce tioを使ってみました。

# apt install screen picocom cu tio
$ screen /dev/rfcomm0 115200     #End Ctl-a k y/n
$ picocom -b 115200 /dev/rfcomm0 #End Ctl-ax
$ cu -s 115200 -l /dev/rfcomm0   #End ~.
$ tio -b 115200 /dev/rfcomm0     #End Ctrl-t q

いずれも同じように使うことができますがこの中でシリアル接続として一番使いやすかったのはtioでした。
rfcommは調子のいい時はすぐ繋がるのですがなにかの関係で接続まで時間がかかることがあります。
tioは接続が切れた時やTimeoutの際はretryを接続するまで繰り返します。

RaspberryPi3からOrangePi3へ接続してみる

$ tio -b 115200 /dev/rfcomm0


サクッと繋がりました。
シリアル接続はいろいろ制限があります。topなど特殊なコマンドは実行できません。
通常のコマンドは実行可能です。
但しviやnanoなどではファイルの編集は不可です。(ed editorは可だが使いにくい)
あくまで状況確認、正常終了、再起動(設定ファイルのコピー)と考えたほうがいいです。

tioはターミナルからexitすると再度接続を繰り返します。終了するにはCtrl-t q


接続したまま再起動すると接続できるまでretryを繰り返します。

設定が正しくて繋がりにくい要因として上記のとおり接続まで時間がかかる(60秒位の時もある)
また接続する側(RaspberryPi3)のrfcommの状態に起因することが多いと思います。


画像はRaspberryPi3のrfcomm
起動時はclean
接続時はconnexted
正常終了はclose
clean,closeは(再)接続可能です。これ以外のメッセージでは失敗することがあります。
一旦releaseして再bindすることでcleanになります。
稀にRaspberryPi3の再起動が必要なときもある。

TTY terminal applicationは使い方を誤るとすぐ固まります。固まったときは接続する側でkill -9 idしてやればcloseで再接続できます。
bluetoothによるシリアル接続は若干癖がありますが動作自体はかなり信頼性は高いと思っています。
ネットワークの監視、実験用途にはいいですね。