USB HIDジョイスティックでPS3をコントロールする

USBマウス&キーボードのサンプル USBMouse を改良して作ったジョイスティックでPS3をコントロールするプログラムです。

http://farm6.static.flickr.com/5128/5356824895_d5d4200cd5_m.jpg

概要

PS3ではUSB HID (Human Interface Device) のキーボードやマウス、ジョイスティックを使うことができます。

mbedにはUSB通信用のポートが専用に用意されているため、USBコネクタorケーブルをそのままつなげれば、PS3で使えるUSBジョイスティックを簡単に作ることができます。

mbedの高い外部接続性を活かせば、PS3用のオリジナルコントローラやコマンド自動入力装置の作成、ネットワークからのコントロールなどが可能になります。もちろんPCでも使えますよ!

HIDリポートディスクリプタ

HIDの入出力フォーマットを定義するHIDリポートディスクリプタをジョイスティック用に作らないといけないのですが、一から作るのは大変だったため、JC-PS101USVというPS2用のコントローラーをUSB接続に変換するアダプタのものから、下記のように必要な部分だけ拝借しました。これをバイナリ表現したデータをプログラム中で作成します。

Usage Page    (Generic Desktop)
Usage (Joystick)
    Collection (Application)
      Usage (Pointer)
          Collection (Physical)
            Usage Page    (Button)
            Usage Minimum...........    (1)
            Usage Maximum...........    (12)
            Logical Minimum.........    (0)
            Logical Maximum.........    (1)
            Physical Minimum........    (0)
            Physical Maximum........    (1)
            Report Size.............    (1)
            Report Count............    (12)
            Input...................   (Data, Variable, Absolute, No Wrap, Linear, Preferred State, No Null Position, Bitfield)
            Usage Page    (Generic Desktop)
            Usage (Hat Switch)
            Logical Minimum.........    (0)
            Logical Maximum.........    (7)
            Physical Minimum........    (0)
            Physical Maximum........    (315)
            Unit....................    (20)
            Report Size.............    (4)
            Report Count............    (1)
            Input...................   (Data, Variable, Absolute, No Wrap, Linear, Preferred State, Null State, Bitfield)
            Usage Page    (Generic Desktop)
            Usage (X)
            Usage (Y)
            Usage (Z)
            Usage (Rz)
            Logical Minimum.........    (0)
            Logical Maximum.........    (255)
            Physical Minimum........    (0)
            Physical Maximum........    (255)
            Unit....................    (0)
            Report Size.............    (8)
            Report Count............    (4)
            Input...................   (Data, Variable, Absolute, No Wrap, Linear, Preferred State, No Null Position, Bitfield)
          End Collection
    End Collection

送信データのフォーマット

このHIDリポートディスクリプタによって定義される送信データのフォーマットは以下になります。B番号 はボタン番号を表します。

プログラム内で、この6バイト分のデータを入力状況に応じて作成し、定期的にUSBホストに転送しています。

|     |bit7|bit6|bit5|bit4|bit3|bit2|bit1|bit0|
|byte0|B08 |B07 |B06 |B05 |B04 |B03 |B02 |B01 |
|byte1|Hatswitch(0-7,0xf) |B12 |B11 |B10 |B09 |
|byte2|X (-128:0x00 ... 0:0x80 ... +127:0xff) |
|byte3|Y (-128:0x00 ... 0:0x80 ... +127:0xff) |
|byte4|Z (-128:0x00 ... 0:0x80 ... +127:0xff) |
|byte5|Rz(-128:0x00 ... 0:0x80 ... +127:0xff) |

接続

mbedUSBコネクタジョイスティック
VIN1: Vbus
USB D-2: D-
USB D+3: D+
GND4: GND可変抵抗のGND
VOUTスイッチや可変抵抗のVCC
P5-P16ボタン用スイッチ
P17-P20アナログスティック用可変抵抗
P21-P24十字キー用スイッチ

アサイン

mbedPCPS3
P5ボタン1
P6ボタン2
P7ボタン3×
P8ボタン4
P9ボタン5L1
P10ボタン6R1
P11ボタン7L2
P12ボタン8R2
P13ボタン9SELECT
P14ボタン10START
P15ボタン11L3
P16ボタン12R3
P17X軸左アナログスティックX軸
P18Y軸左アナログスティックY軸
P19Z軸右アナログスティックX軸
P20Z回転軸右アナログスティックY軸
P21ハットスイッチ上十字キー上
P22ハットスイッチ下十字キー下
P23ハットスイッチ左十字キー左
P24ハットスイッチ右十字キー右

プログラム

[Not found]

#include "mbed.h"
#include "usbhid.h"

DigitalOut led(LED1);

BusIn buttons(
    p5, p6, p7, p8,      // PS3: Square, x, o, Triangle
    p9, p10, p11, p12,   // PS3: L1, R1, L2, R2 
    p13, p14, p15, p16   // PS3: SELECT, START, L3, R3
);

AnalogIn analog_x(p17);  // PS3: Left Analog Stick X-axis
AnalogIn analog_y(p18);  // PS3: Left Analog Stick Y-axis
AnalogIn analog_z(p19);  // PS3: Right Analog Stick X-axis
AnalogIn analog_rz(p20); // PS3: Right Analog Stick Y-axis

BusIn stick(
    p21, p22, p23, p24   // PS3: Up, Down, Left, Right
);

USBJoystick joystick;

int main() {
    while(1) {
        signed char x = (analog_x.read_u16() >> 8) - 0x80;
        signed char y = (analog_y.read_u16() >> 8) - 0x80;
        signed char z = (analog_z.read_u16() >> 8) - 0x80;
        signed char rz = (analog_rz.read_u16() >> 8) - 0x80;
        
        joystick.joystick(stick.read(), buttons.read(), x, y, z, rz);
        
        led = (buttons > 0 || stick > 0) ? 1 : 0;
        
        wait(0.01);
    }
}

USBMouse に含まれる usbhid クラスは今回の目的には継承しづらい形で実装されているため、やっつけで usbhid.husbhid.cpp に追記する形で実装しました…。どなたかもう少しきれいに実装しなおしてもらえるとうれしいです。

課題

このジョイスティックを使ってPS3でPS2のゲームを遊ぼうとすると、PSボタンがないために操作不能になります。PS3でPSボタンを押したときと同じ動作をするにはどうすればよいか調査中です。ボタンの数を増やしてもだめでした。どなたかご存知でしたら教えて下さい。


8 comments on USB HIDジョイスティックでPS3をコントロールする:

30 Jan 2011

Hello Shiniciro-san.

Does this program make me able to connect to PlayStation 3 with external components? So the mbed's USB port connect directly to PS3?

Regards, Lerche

31 Jan 2011

Christian Lerche wrote:

So the mbed's USB port connect directly to PS3?

No. Please use mbed's USB D+/- pins (p31/p32), GND pin, and VIN pin with another USB cable or connecter.

31 Jan 2011

Of course, but the mbed will act as a joystick?

Lerche

01 Feb 2011

Yes!

This program makes you able to use all buttons, 2 analog sticks, and D-Pad(hatswitch) except PS button and motion sensors on PS3.

01 Feb 2011

What is the problem with the PS button? Is it not able to send through USB?

01 Feb 2011

Hello again, I've tried your code, but couldn't get my PS3 to recognize the mbed as a controller.. Do you think it could be, becourse I've updated the PS3?

Regards, Lerche

09 Feb 2011

Hmmm, please check recognizing on your PC.

17 May 2011

do you know how to modify the HID descriptor, to be a BASIC HID Device, the same as the PIC18f2550 / PIC18f4550 Basic HID ?

I have tried repeatedly to get this to work, but cannot seem to achieve it :(

Regards Ceri

Please log in to post comments.