#はじめに
すんなり行かなかったので、備忘のためにまとめます。誰かの助けになれば幸いです。
#使ったもの
- Raspberry Pi 3 Model B
- Raspberry Pi OS
- Distributor ID: Raspbian
- Description: Raspbian GNU/Linux 10 (buster)
- Release: 10
- Codename: buster
- Raspberry Pi OS
- PS3 コントローラ (Dualshock3)
- ハードオフで 800円 くらい
- 似たもので sixaxis というのがあるが、Dualshock3 の振動ないバージョンだと思う
#事前準備
もろもろ apt-get でインストールしていくので予め update しておく
$ sudo apt-get update && sudo apt-get upgrade
sixpair のインストール
sixpair はコマンドラインペアリングツールとのこと。通常の Bluetooth デバイスは、デバイスとホストとの間のリンクを一度確立すると、ホストはこの以前に記憶された情報を用いて接続を開始することができますが、今回のケース (PS3 コントローラー) の場合、実際にはプロセスを開始するのはコントローラー側なので、事前にセットアップを行う必要があります。PS3 コントローラと接続する Bluetooth ホスト(今回でいうとラズパイ)を、予め PS3 コントローラーに指示する必要があるらしい。
まず libusb-dev
をインストールする。たぶん後述する sixpair のコンパイルに必要なんだと思う。
libusb-dev は、ユーザ空間の USB プログラミングライブラリ。Linux カーネルの内部に関する知識を必要とせずに、USB アプリケーションをプログラミングするためのライブラリ
$ sudo apt-get install libusb-dev
続いて、ペアリング用ツールである sixpair
をインストールする。
下記のようにしてソースコードをダウンロードし、コンパイルする。
$ wget http://www.pabr.org/sixlinux/sixpair.c
$ gcc -o sixpair sixpair.c -lusb
ここで、PS3 コントローラーをラズパイに USB で有線接続し、sixpair を実行する。
$ sudo ./sixpair
Current Bluetooth master: aa:aa:aa:aa:aa:aa ←PS3 コントローラがホストだと思っている相手のアドレス
Setting master bd_addr to bb:bb:bb:bb:bb:bb ←このコマンドを実行しているラズパイのアドレス
上記のように、アドレスが異なる場合、再度同じコマンド実行
$ sudo ./sixpair
Current Bluetooth master: bb:bb:bb:bb:bb:bb ←PS3 コントローラがホストだと思っている相手がラズパイになった
Setting master bd_addr to bb:bb:bb:bb:bb:bb ←このコマンドを実行しているラズパイのアドレス
これで、有線ペアリングは完了。
#QtSixA のインストール
次に qtsixa をビルド、インストールする。
!QtSixA は、Sixaxis ジョイスティック マネージャーです。PS3 ハードウェア (Sixaxis/!DualShock3 とキーパッド) をLinux 互換マシンに接続できます。現在 Sixaxis ボタン、軸、加速度センサーおよび Led をサポートします。
QtSixA 自体は GUI ツールですが、今回はこれに含まれている sixad
というデーモンを使うことになります。
いくつかライブラリが不足するので(あとからわかるのだが)、先にインストールします。
--- pyuic4 ---
$ sudo apt-get install -y python-qt4 pyqt4-dev-tools qt4-designer
--- jack.h ---
$ sudo apt-get install -y libjack-jackd2-dev
--- bluetooth.h ---
$ sudo apt-get install -y libbluetooth-dev
--- 念の為これも ---
$ sudo apt-get install -y bluez bluez-hcidump joystick
次に、qtsixa
のソースを github からクローンする (wget でもいいかもしれないが)
$ git clone https://github.com/falkTX/qtsixa.git
$ cd qtsixa
$ make
$ sudo make install
...中略...
Installation is Complete!
注意! ここで、python
コマンドが python3 系だと make がうまく通らないようなので、エイリアス修正等で python2 系にしておく。
続いて無線ペアリングに移るが、その前に、bluetooth が起動していなければいけないので、念の為確認する。
$ hciconfig
hci0: Type: Primary Bus: UART
BD Address: B8:27:EB:66:17:67 ACL MTU: 1021:8 SCO MTU: 64:1
DOWN
RX bytes:654 acl:0 sco:0 events:33 errors:0
TX bytes:419 acl:0 sco:0 commands:33 errors:0
上記のように、DOWN
になっている場合、下記のようにして起動する。
注意! piscan
をつけるのがポイント。こうすることで UP RUNNING PSCAN ISCAN
状態になる。UP RUNNING PSCAN ISCAN
なっていないと、無線でペアリングできない(ここでずいぶんハマった)
$ sudo hciconfig hci0 up piscan
$ hciconfig
hci0: Type: Primary Bus: UART
BD Address: B8:27:EB:66:17:67 ACL MTU: 1021:8 SCO MTU: 64:1
UP RUNNING PSCAN ISCAN
RX bytes:1315 acl:0 sco:0 events:67 errors:0
TX bytes:843 acl:0 sco:0 commands:67 errors:0
つづいて、無線でペアリングする。USBケーブルを抜いて、PS3 コントローラを無線状態にし、下記コマンドを実行。
$ sudo sixad -start &
sixad-bin[5850]: started
sixad-bin[5850]: sixad started, press the PS button now
上記のようになったら PS3 コントローラーの PS ボタンを押す。以下のメッセージが出て、PS3 コントローラーがブルブルと震えればペアリング成功。
sixad-sixaxis[6027]: Connected 'PLAYSTATION(R)3 Controller (aa:aa:aa:aa:aa:aa)' [Battery 04]
sixad をとめたい時は
$ /usr/bin/sixad --stop
これで PS3 コントローラの操作をラズパイが解釈できるようになったので、これを使ってラズパイラジコンを作ります!(つづく)
#2 回目以降のラズパイ起動時の設定
起動時に発見可能にする
PSCAN, ISCAN フラグをタイムアウトで落とさないようにするため、main.conf に下記を追記する。
※セキュリティの観点で理想的ではないので、自己責任で
$ vi /etc/bluetooth/main.conf
[General]
DiscoverableTimeout=0
Discoverable=true
~中略~
[Policy]
AutoEnable=true
rc.local に記述しラズパイ起動時に自動実行
bluetooth の起動、sixad の起動を、シェルスクリプトに記述し、rc.local で起動時に自動起動するようにする
$ sudo vi /etc/rc.local
〜中略〜
sudo chmod 755 /usr/lib/bluetooth/bluetoothd
sudo systemctl start bluetooth
sudo sixad -start &
exit 0
※なぜか、bluetoothd の実行権限(x)がラズパイ再起動時に取れてしまう現象が時折発生するので、美しくはないが起動時に毎回 chmod するようにして暫定対処。
※当初、ラズパイで rc.local が実行できなかった。調べると ここ にあるように、raspi-config
で Boot Options で Wait for Network at boot を はい にしておかないと実行できないらしい。ハマりポイント。
**systemctlで起動する方法試みたがうまく行かず挫折。一応残しておく(クリックで開く)**
sixad デーモン自動起動
ラズパイ起動時に sixad デーモンが立ち上がるようにする
$ sudo systemctl enable sixad
自動起動を解除するときは下記のようにする
$ sudo systemctl disable sixad
##ラズパイ起動時に bluetooth を ON にする
$ sudo systemctl enable bluetooth.service
以下は参考。
当初、なぜか systemctl
で bluetooth を ON にしようとすると、下記のようにエラーが出た。
$ sudo systemctl status bluetooth.service
● bluetooth.service - Bluetooth service
Loaded: loaded (/lib/systemd/system/bluetooth.service; enabled; vendor preset: enabled)
Active: failed (Result: exit-code) since Sat 2020-10-03 21:06:02 JST; 25s ago
Docs: man:bluetoothd(8)
Process: 1371 ExecStart=/usr/lib/bluetooth/bluetoothd (code=exited, status=203/EXEC)
Main PID: 1371 (code=exited, status=203/EXEC)
10月 03 21:06:02 raspberrypi systemd[1]: Starting Bluetooth service...
10月 03 21:06:02 raspberrypi systemd[1371]: bluetooth.service: Failed to execute command: Permission denied
10月 03 21:06:02 raspberrypi systemd[1371]: bluetooth.service: Failed at step EXEC spawning /usr/lib/bluetooth/bluetoothd: Permission denied
10月 03 21:06:02 raspberrypi systemd[1]: bluetooth.service: Main process exited, code=exited, status=203/EXEC
10月 03 21:06:02 raspberrypi systemd[1]: bluetooth.service: Failed with result 'exit-code'.
10月 03 21:06:02 raspberrypi systemd[1]: Failed to start Bluetooth service.
よく見ると /usr/lib/bluetooth/bluetoothd
がパーミッションなしで Fail しているようで、確認するとたしかに 644 だったので実行権限がない。何も考えず 777 を与えることで解消。するかと思われた、が、ラズパイを reboot すると上記 bluetoothd の権限が 644 に戻っているではありませんか。。。755 にしてもだめ(そうだろう)。644 に戻っちゃう時と、戻らないとき (755 のまま) の時がある。なぜなのかわからない・・・
sixad と bluetooth.service の起動順番
上述のように、sixad と bluetooth.service を systemctl enable ○○
で起動時から有効にしたが、PS3 コントローラーの PS ボタンを押してもペアリングされない。どうも、bluetooth.service のあとに sixad が起動しないとダメっぽい。サービス Unit の自動起動の順序を確認する
$ sudo systemctl list-dependencies
default.target
● ├─lightdm.service
● ├─raspi-config.service
● ├─rng-tools.service
● ├─sixad.service
● ├─systemd-update-utmp-runlevel.service
● ├─udisks2.service
● └─multi-user.target
● ├─avahi-daemon.service
● ├─console-setup.service
〜以下省略〜
また、下記コマンドでは実際にサービス Unit がどういう順で起動してどれくらい時間がかかったを HTML ファイルで出力できる。
systemd-analyze plot > hoge.html
これによると、たしかに sixad が bluetooth.service よりも先に起動している。よって、起動順を変えたい。
こちらを参考に、サービス定義ファイルに起動順番の依存関係を記述することで設定できそうだが、sixad のサービス定義ファイルが存在しないので、どうすればいいのか悩み中(後日記載予定)。
ー>こちらを参考にし、$ sudo sixad -start &
を実行するシェルスクリプトを作り、sixad_start.service
としてサービス登録してもいいかもしれない
~~~展開ここまで~~~
#その他
##インストール済みパッケージの確認
apt-get でたくさんパッケージをインストールしたので、何をインストールしたかわからなくなった時は、
$ sudo dpkg -l
で確認
##PS3 コントローラーの入力確認
有線または無線で PS3 コントローラーとラズパイがペアリングされていれば、下記のコマンドで、コントローラー操作があれば文字化けした文字がダーっと表示される
$ cat /dev/input/js0
コントローラーが複数ペアリングされているときは、js1, js2, ... と増える
##起動中のデーモン確認
意図したデーモンが起動しているか(今回でいうと sixad
が起動しているか)は下記コマンドで確認
$ service --status-all
たくさん出てくると思うので必要に応じ grep
で
$ service --status-all | grep six
[ ? ] rng-tools
[ + ] sixad
##サービス自動起動設定確認
(例) $ systemctl is-enabled sixad
enabled