シェルスクリプトでジョイスティックを使う

最終更新日

Comments: 0

シェル芸

ふと思い立って調べてみたので、備忘用に書いておきます。利用ハードウェアはエレコムのJC-U2312FSV。12ボタン、十字キー、アナログ2軸のゲームコントローラーです。

# 検証方法(信号を16進数8バイトずつ表示)
cat /dev/input/js0 | od -tx1 -Ax -w8

js0デバイスを開くと、必ず以下のようなバイナリが流れて停止します。

000000 bc e7 8f 00 00 00 81 00
000008 bc e7 8f 00 00 00 81 01
000010 bc e7 8f 00 00 00 81 02
000018 bc e7 8f 00 00 00 81 03
000020 bc e7 8f 00 00 00 81 04
000028 bc e7 8f 00 00 00 81 05
000030 bc e7 8f 00 00 00 81 06
000038 bc e7 8f 00 00 00 81 07
000040 bc e7 8f 00 00 00 81 08
000048 bc e7 8f 00 00 00 81 09
000050 bc e7 8f 00 00 00 81 0a
000058 bc e7 8f 00 00 00 81 0b
000060 bc e7 8f 00 00 00 82 00
000068 bc e7 8f 00 00 00 82 01
000070 bc e7 8f 00 00 00 82 02
000078 bc e7 8f 00 00 00 82 03
000080 bc e7 8f 00 00 00 82 04
000088 bc e7 8f 00 00 00 82 05

このヘッダ信号は、有効なボタン/軸情報の申告かな。最初の4バイトが全て同じ値なので、メーカーまたは型番番号or以下に続くキーイベントのカウンタと区別するものかもしれない。

続けて、0番、1番ボタンを順に押下すると

000090 30 b1 91 00 01 00 01 00 ← 0番ボタン押下
000098 a0 b1 91 00 00 00 01 00 ← 0番ボタン離す
0000a0 70 b6 91 00 01 00 01 01 ← 1番ボタン押下
0000a8 e0 b6 91 00 00 00 01 01 ← 1番ボタン離す

と分かりやすい結果が出てきました。さらにいくつか押下してみると、以下の事が分かりました。

  • キーイベントは8バイト構成
  • それぞれの内容は以下のとおり
バイト順内容
1~4バイト目同期用カウンタ?初期値不明。
5~6バイト目ボタン(押=1/離=0) or 方向(座標情報)
7バイト目ボタンイベント時=1/方向イベント時=2
8バイト目ボタン番号(0~c) or 軸情報(LX=0/LY=1/RX=2/RY=3/CX=4/CY=5)

※ 複数バイト値はリトルエディアン

7バイト目がフラグになっており、このイベントが通常ボタン押下なのか方向操作なのかを通知しているようです。

7バイト目が1、つまり通常ボタン押下の場合、5~6バイト目が unsigned short で押した(1)か離した(0)かの情報、8バイト目が char でキー番号(0~c)となります。

また、7バイト目が2、つまり方向操作の場合、5~6バイト目が signed short のずれ量(アナログスティック時)、8バイト目が軸情報となる。十字ボタンの5~6バイト目は以下のとおり。

キー方向情報軸情報
80014
7fff4
80015
7fff5

※リトルエディアンなので、下位8ビットが5バイト目にあたります。

十字ボタンの値は、固定値のようだ。また、十字ボタンが離された際には、5~6バイト目はヌル(0)となります。

1~4バイト目は、キューが混乱した場合にちゃんとソート出来るようにした目印カウンタかな。

歴史的背景のあるキーボードの信号より、すごくシンプルで分かりやすいと思いました。きっと似たようなフォーマットで軸や強度、モーター情報を拵えて js0 に write してやると、振動してくれそうだー。

これを元に、ジョイスティックキー検知を行うシェルスクリプト関数を書きたいと思います。

※ 2020/07/02 度重なるブログ移転・ブログシステムのアップデートにより崩れた記事を校正。

佐世保のシステムエンジニアです。詳しいプロフィールやこのブログについてはこちらをご覧ください。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

コメントする

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください