DUALSHOCK4について

SIXAXISのときもやりましたが、DUALSHOCK4でもハードの仕様と取得されるデータ構造をまとめておきましょう。

仕様

まずは基本的な仕様を確認してみます。

品名 DUALSHOCK 4
接続 Bluetooth Ver2.1+EDR準拠
USB(Micro B)
ボタン数 18ボタン
方向キー(POV)、アクションボタン(○×△□)、L1/R1/L2/R2ボタン、左スティック/L3ボタン、右スティック/R3ボタン、SHAREボタン、OPTIONSボタン、PSボタン、パッドボタン
アナログ入力 L2/R2ボタン、左スティック/L3ボタン、右スティック/R3ボタン
タッチパッド 2点検出式タッチパッド、クリック機構、静電容量方式
解像度:1920×900
モーションセンサー 6軸検出システム(3軸ジャイロ、3軸加速度)
振動機能 あり
端子 拡張端子
ステレオヘッドホン/マイク端子
その他 ライトバー、振動機能、スピーカー(モノラル)内蔵
メーカー ソニー・コンピュータエンタテインメント(SCE)
定価 6,458円(税込)

価格.comでも5000円。Wiiリモコンプラスの最安値2551円(希望小売価格 3619円)と比較するとやっぱり高いですね。まあSONYだし仕方ない。

今回はPCに繋ぐだけで、BluetoothでもUSBでも簡単に普通のゲームコントローラとして認識するようになりました。ドライバのインストールは不要です。 SIXAXISの頃は、入れ方間違えると悲惨なことになるドライバがあったり、配布元がよく分からなかったりいろいろありましたねー。ドライバ不要は本当にありがたいです。
PCで使用するとL2/R2から第5,6軸のアナログ値が取得できます。(アナログ値と同時にボタンが押される特殊仕様。実はこの仕様がちょっと困る。)
さらにPSボタンとタッチパッド押下の2ボタンが使用できるので、通常のゲームコントローラより多くの値が取得できます。 アナログ第1~6軸が取得できるのは、他にフライトシミュレーション用のコントローラぐらいだと思います。 こういう実装が将来PC用コントローラのスタンダードになっていったりするんでしょうか。
このように通常のゲームコントローラよりも多くの値が取得できるすぐれもの。これを活かしたゲームとか作りたいですね。

Windows標準ドライバで動作するのですが、振動に対応しません。しかし標準で使えることは地味に重要だと思います。
私のつたない経験上、ドライバが違うとプログラムでの取得値の場所がバラバラで困った経験があります。今回はドライバ無しの状態が示されているので 振動対応のドライバが出てもフォーマットが変わらないんじゃないかと期待しています。

さて、機能追加ばかりでなく逆に機能削減されたものもあります。
DUALSHOCK3まで搭載されていた、全ボタンの圧力による256段階のアナログ判定がなくなりました。残ったのはL2/R2ボタンのアナログ入力だけとなります。

解剖調査結果を検証してみた

すでに解剖結果のレポートが上がっているので、詳細はこちらをご覧ください。

Kako's Home page:http://www.kako.com/
PLAYSTATION4用DualShock4を調べてみる

SIXAXISに続き、今回もこちらのサイトのお世話になりました。写真が大きいので助かります。

モーションセンサーの位置がわかりにくいですが、左手側の基板の裏側、下の方にチップがついています。
Bosch社のBMI055と言われているそうです。

センサーの方向を見てどの向きが正負か調べてみたのですが、どうにも私の頭が悪いために理解できませんでした。 カタログ見てもZが上向き正の図になってるのに、重力加速度(下方向)がプラスって意味不明です。よくわからないので取り敢えず実測して正負を調べることにしました。

データ構造

USB接続状態で、通常のHIDとして取得すると簡単にデータが取得出来ました。
ベンダーID:0x054C
プロダクトID:0x05C4
全64byte

情報がなかったので、全て手探りで調べました。
私の環境でしか確認していないので、もしかすると環境によって異なるかもしれません。その点はご了承ください。
それにしてもタッチパッドが12bitなのが悩ましいですね。どう処理すればよいのやら…。

(追記:2021/06/14)
 久しぶりにDUALSHOCK4使ってみたら、長く使ってなかったせいでバッテリーが死んでました。充電が出来ない。Bluetooth接続ができない。_(:3」∠)_

 もう7年が経とうとしていますが、再調査してみました。DUALSHOCK4をPCに接続し、自作アプリの数値変化を見ながら手作業で確認したものです。 内容についての保証はできないのでご了承ください。

 なお、調査の際はこちらのサイトも参考にしました。全く同じ結果ではなかったのが謎です。
Eleccelerator Wiki
http://eleccelerator.com/wiki/index.php?title=DualShock_4

Bytebit 7bit 6bit 5bit 4bit 3bit 2bit 1bit 0
0ReportID(0x01) HID報告のためのレポートID
1Left stick X(0~255) 0=Left
2Left stick Y(0~255) 0=Up
3Right stick X(0~255) 0=Left
4Right stick Y(0~255) 0=Up
5 △ Triangle
Button Flag
○ Circle
Button Flag
× Cross
Button Flag
□ Square
Button Flag
POV(8=未入力, 0=N, 1=NE, 2=E, 3=SE, 4=S, 5=SW, 6=W, 7=NW)
6 Right stick
Button Flag
Left stick
Button Flag
OPTION
Button Flag
SHARE
Button Flag
R2 Button
Flag
L2 Button
Flag
R1 Button
Flag
L1 Button
Flag
7 カウンタ(レポートごとに1カウントアップ)? (0~63) タッチパッド
Button Flag
PS
Button Flag
8L2 Analog (0~255)
9R2 Analog (0~255)
10タイムスタンプ?(0~65535)
11
12バッテリー (0~255)
13角速度 XR ピッチ(下位ビット)
14角速度 XR ピッチ(上位ビット)
15角速度 ZR ヨー(下位ビット)
16角速度 ZR ヨー(上位ビット)
17角速度 YR ロール(下位ビット)
18角速度 YR ロール(上位ビット)
19加速度 X(下位ビット)
20加速度 X(上位ビット)
21加速度 Z(下位ビット)
22加速度 Z(上位ビット)
23加速度 Y(下位ビット)
24加速度 Y(上位ビット)
25dummy(0x00)
26dummy(0x00)
27dummy(0x00)
28dummy(0x00)
29dummy(0x00)
30 0x00 Phone ?
接続 Flag
mic ?
接続 Flag
USB ?
接続 Flag
バッテリーレベル(0~15)
31dummy(0x00)
32dummy(0x00)
33タッチパッド?(0~2?)
34タッチパッド?(0~255)
35 タッチパッド
ID1
非接触 Flag
タッチパッド
ID1 タップカウント (0~127)
36タッチパッド ID1 X
37タッチパッド ID1 Y(下位ビット)タッチパッド ID1 X(上位ビット)
38タッチパッド ID1 Y
39 タッチパッド
ID2
非接触 Flag
タッチパッド
ID2 タップカウント (0~127)
40タッチパッド ID2 X
41タッチパッド ID2 Yタッチパッド ID2 X
42タッチパッド ID2 Y
43Unknown 0x00(タッチパッドを触ると変化することがある)
44Unknown 0x80(タッチパッドを触ると変化することがある)
45Unknown 0x00(タッチパッドを触ると変化することがある)
46Unknown 0x00(タッチパッドを触ると変化することがある)
47Unknown 0x00(タッチパッドを触ると変化することがある)
48Unknown 0x80(タッチパッドを触ると変化することがある)
49Unknown 0x00(タッチパッドを触ると変化することがある)
50Unknown 0x00(タッチパッドを触ると変化することがある)
51Unknown 0x00(タッチパッドを触ると変化することがある)
52dummy 0x00
53dummy 0x80
54dummy 0x00
55dummy 0x00
56dummy 0x00
57dummy 0x80
58dummy 0x00
59dummy 0x00
60dummy 0x00
61dummy 0x00
62dummy 0x80
63dummy 0x00

 表だけではよくわからないので補足説明。

0:ReportID(0x01) HID報告のためのレポートID
0x01の固定値
1,2:Left stick (0~255)
左スティックの左右、上下の傾きです。0~255の値を取ります0。(0, 0)=左上
3,4:Right stick (0~255)
右スティックの左右、上下の傾きです。0~255の値を取ります0。(0, 0)=左上
5:□,×,○,△ Button Flag
□,×,○,△ を押すと 1 になります。
5:POV (0~8)
POVとかハットスイッチとか十字キーと呼ばれます。何も押していない場合、8を返します。いずれかの方向を押すと 0~7 の値を返します。
0=上, 1=右上, 2=右, 3=右下, 4=下, 5=左下, 6=左, 7=左上
6:L1, R1, L2, R2, SHARE, OPTION, Left stick, Right stick
L1, R1, L2, R2, SHARE, OPTION, Left stick, Right stick を押すと 1 になります。
7:PS
PSボタンを押すと 1 になります。
7:タッチパッドボタン
タッチパッドボタンを押すと 1 になります。
7:カウンタ(レポートごとに1カウントアップ)? (0~63)
何の値かわかりません。常に値が増えていて 63 を超えると 0 に戻ります。 リンク先の説明文でカウンタとなっていました。
Eleccelerator Wiki
http://eleccelerator.com/wiki/index.php?title=DualShock_4
10,11:タイムスタンプ?(0~65535)
何の値かわかりません。常に値が増えていて 65535 を超えると 0 に戻ります。 リンク先の説明文でタイムスタンプとなっていました。
Eleccelerator Wiki
http://eleccelerator.com/wiki/index.php?title=DualShock_4
12:バッテリー (0~255)
おそらくバッテリーであっていると思います。0=0%、255=100% だと思います。手持ちのDUALSHOCK4のバッテリーが死んでて充電出来ないのでいつも10%以下の値しか出ないので数値変化を確認出来ませんでした。
13~18:角速度
signed short int(2バイト)数値範囲は -32768 ~ 32767 、単位は[ ミリrad/s ]のようです。
スマホと一緒にくるくる回して確認しました。
19~24:加速度
signed short int(2バイト)数値範囲は -32768 ~ 32767 、単位はわかりません。数値も9.8とか1とかではなかったので、正確な数値が欲しい場合は、校正する必要があります。3方向もそれぞれ比率が違うようです…手元のDUALSHOCK4だとZだけ少し大きい。
25~29:dummy
0x00 の値のまま変化しません。変化させるような入力をしていないだけかもしれません。位置から推測すると拡張用に開けている領域のような気がします。
30:バッテリーレベル(0~15)?
私の環境だといつ起動しても 11 です。ほとんど充電されていないはずなので、この数値には違和感があります。手元のDUALSHOCK4のバッテリー死んでるので確認できません。リンク先に書いてあるのでとりあえず記載。
Eleccelerator Wiki
http://eleccelerator.com/wiki/index.php?title=DualShock_4
30:USB? 接続 Flag
おそらくUSBケーブルの接続状態を示すフラグだと思います。Bluetooth接続できないので確認できませんでした。USB接続で使用している場合、常に 1 です。
30:mic? 接続 Flag
3.5mmミニジャックの接続状態を示すようです。何もつながっていない状態では 0 です。試しにイヤホンプラグ(3極)を差し込んだら 1 になりました。マイク(3極)を差し込んでも 1 になりました。
0=非接続、1=接続
30:Phone? 接続 Flag
電話…?イヤホンマイクのことかな?手元にないので確認できませんでした。リンク先に書いてあるのでとりあえず記載。
Eleccelerator Wiki
http://eleccelerator.com/wiki/index.php?title=DualShock_4
31~32:dummy
0x00 の値のまま変化しません。変化させるような入力をしていないだけかもしれません。
33:タッチパッド?
何でしょうねこれ?タッチパッドに指を乗せて動かしていると、ほとんど0ですがたまに値が 1 ~ 2 の値になります。
トラックパッドパケットの数?って言われて意味がもわかりません。
34:タッチパッド?
何でしょうねこれ?タッチパッドに指を乗せて動かしている間は値が増えます。255 を超えると 0 に戻ります。
パケットカウンタ?って言われても意味がわかりません。
35,39:タッチパッド ID1,2 非接触 Flag
タッチパッドの接触状態を示すフラグです。ID1は1本目の指、ID2は2本目の指です。
0=タッチパッドに触れていない, 1=タッチパッドに触れている
35,39:タッチパッド ID1,2 タップカウント (0~127)
タッチパッドをタップした回数をカウントしています。タッチパッドボタンを押下した回数ではありません。ID1は1本目の指、ID2は2本目の指です。 タップするとID1,2を判定してそれぞれ数値を更新します。タップされない限り更新されません。 数値の更新はID1,2を判定しますが、更新の結果表示される数値はID1,2の合計数です。 そこまでするならID1,2でそれぞれカウントすればいいのに意味がわかりません。
36~38,40~42:タッチパッド ID1,2 X,Y
タッチパッドをタッチしている座標(0, 0)~(1920, 900)です。ID1は1本目の指、ID2は2本目の指です。
43~51:Unknown 0x00(タッチパッドを触ると変化することがある)
普段は 0x00 または 0x80 ですが、タッチパッドを操作していると瞬間的に数値が変化することがあります。指1本だけだと後半バイトは値が変わっても同じ値っぽいので、ID1,2の判定を含むなにかの値だと思います。
52~63:dummy
0x00 または 0x80 の値のまま変化しません。変化させるような入力をしていないだけかもしれません。

この他、空き領域が沢山あるのでマイク入力や拡張端子からの入力が入ってくるのかもしれません。

座標軸

座標軸
これも手探りで調べました。
図の赤矢印方向が加速度の正方向。
緑の矢印が回転の正方向。
SIXAXISとは随分違うようです。

加速度は右手系なのに、回転は右ネジではありませんでした。謎です。とりあえず本体を緑矢印の方向に回すと正の値が出力されます。
もしかすると私のほうが解釈をなにか間違えているのかもしれません。orz

ともかく方向さえ分かってしまえば、後は好きなように正負反転させるなりして使うことが出来ますね。

確認用のサンプルプログラム

確認用のサンプルプログラム…は前回公開したのがありますので、そちらでご確認ください。