0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ゲームパッドJC-U4013SのUSB出力をJAVAで拾う

Posted at

プロポからパッド

自作ドローンのコントローラーを市販のプロポにしていたが、受信側での信号変換が面倒なので、ゲームパッドから無線モジュール経由に変更したいと思っていた。ELECOMのJC-U4013Sをアキバで買った(価格は忘れた)が、はじめはなんとも手が出せなかった。
IMG_4107.JPG
その間、別のUSBデバイスを使う機会があって、そのやり方がそのまま使えることが分かったので、試してみた。

libusbjava を使う

JAVAで操作する。そのため、まず、Windowsでlibusbjavaを使えるようにする。
https://libusb-java.ch/
の指示通りのインストールを行う。少し面倒だが、丁寧に指示をたどって実行する。そして、LibusbJava.jarを自分のプロジェクトに組み込む。

ベンダーIDとプロダクトIDを調べる

Windowsのコントロールパネル→ハードウェアとサウンド→デバイスとプリンターなどを探って、デバイスを表示させ、JC-U4013Sのプロパティを見ていくと「詳細」のところに、
「デバイス HID\VID_056E&PID_200F\7&b070207&0&0000 が構成されました」
などと記述されている。これで、ベンダーIDが0x056E、プロダクトIDが0x200Fであることがわかる。それ以外の記述の意味は知らない。IDは、多分どの環境でも同じような気がするが、確かめてはいない。

デバイス開閉のJAVAのコード

まず、コンテキストオブジェクトを作成し、デバイスオブジェクトを作成する。その際、先に取得した二つのIDを使う。

// デバイスを開くとき
Context useCtx = new Context();
Device usbDev = Device.search(useCtx, 0x056E, 0x200F);
usbDev.open();
// デバイスを閉じるとき
usbDev.releaseInterface(0);
usbDev.close();

エラーなどの細かい処理はここには記載しないが、基本的にtry-catch (LibusbException ex)で成功/失敗がわかる。

ゲームパッド出力の読み取り

こんな感じだが、細かい引数の意味については、先のサイトにあるAPIのページを参考にしていただきたい。

int ret = usbDev.readBulk(0x01, rdata, rdata.length, 2000, true);

ゲームパッドからのデータは、28バイトで、スティック、ボタンの状況がわかるようになっている。ただし、注意しなければならないのは、56バイト、すなわち、2つ分を一度に送ってくるので、それを切り分ける作業が必要である。
データは、すべて0から255の整数値として送られてくる。スティックは連続量だが、ボタン類は、おさないと0、押すと255になる。
また、データは、そのままとると符号付の値となっているので、私の場合は、

int rd = Byte.toUnsignedInt(rdata[i]);

として、符号なしの少数に変換している。そうしないと、スティック一の値が跳んでうまく連続量が処理できなかった。
私の場合は、こんな感じで出力を処理している。jdataというオブジェクトにデータを放り込んでいる。送られたデータのバイト列の何番目が、どのデータであるかも、わかるようにしている。

    /*
データ出力フォーマット 
    スティック
    (0から255の値)中央値127でスティックニュートラル
    4列:左スティック左右、5列:左スティック上下、6列:右スティック左右、7列:右スティック上下
    4つボタン左
    8列:左、9列:右、10列:上、11列:下
    4つボタン右
    12列:右、13列:左、14列:下、15列:上
    フロントボタン
    16列:左上、17列:右上、18列:左下、19列:右下
    */
switch (count) {
  case 4 -> jdata.rtdrive = (double) rd;
  case 5 -> jdata.uddrive = (double) rd;
  case 6 -> jdata.lrdrive = (double) rd;
  case 7 -> jdata.fbdrive = (double) rd;
  case 8 -> jdata.left4r = rd > 100;
  case 9 -> jdata.left4l = rd > 100;
  case 10 -> jdata.left4u = rd > 100;
  case 11 -> jdata.left4d = rd > 100;
  case 12 -> jdata.right4r = rd > 100;
  case 13 -> jdata.right4l = rd > 100;
  case 14 -> jdata.right4d = rd > 100;
  case 15 -> jdata.right4u = rd > 100;
  case 16 -> jdata.fleftu = rd > 100;
  case 17 -> jdata.frightu = rd > 100;
  case 18 -> jdata.fleftd = rd > 100;
  case 19 -> jdata.frightd = rd > 100;
}

パッドの読み取り動画

実際、GUIをJAVAで作って、ゲームパッドの出力データを表示させた動画は、以下でご覧ください。
https://youtu.be/XUuMUdgNt7c

以上です。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?