SnapCrab_NoName_2016-1-8_18-23-3_No-00

Arduino LeonardoでINFINITAS用の変換器を作る


この記事に書いてある内容を実践するにはほんの少しの電子工作スキルとプログラミング(C言語やその派生)の基礎知識が必要になります。

beatmania IIDX INFINITASがサービス開始して1ヶ月経ちますが、未だにキーボード入力にしか対応しておらず、ゲームパッドとして認識するPS2のコントローラーをUSBに変換する変換器の多くが直接使えません(ゲームパッドとして認識するUSB接続対応の専コンも)。
そこで、専用コントローラーでプレーしたい方はJoyToKeyやJoyAdapter等のフリーソフトで変換器などからの入力をキーボード入力に変換してプレーしてることと思います。追記:JoyAdapterと違ってJoyToKeyはシェアウェアです。まあ半分カンパウェアっぽいとこもあるけど・・・。自分もそろそろ買おうと思ってたところだけど、実際のところどれくらいの人が買ってるんだろうね?2016/01/08 23:14
しかし、これには欠点があって、変換する過程で遅延が発生するとされ、その遅延にバラつき(俗にいう「判定のブレ」に繋がる)があることも報告されています。

この記事は、「そういうことならHIDキーボードとして認識する変換器を作っちゃいましょう」、というモノになります。どっかにボソっとArduino Leonardoで変換器を作ったとか書いたことがあったっけ。

作った結果を先に書いてしまうと、Realforceよりも低遅延で、7つ以上の同時押しにも対応することができました。

1.USBデバイスってどうやって作るの?

速度や柔軟性は置いといて、安価(1台作った時のコスト)で少ない勉強で少ないコーディングで目的を達成できるものというとArduino Leonardoが頭に浮かびます。Unoの方が使いやすくて情報も多いことから良く目立ちますが、LeonardoにはUSBシリアル以外の様々なUSBデバイスになれるという目玉機能があります(Unoでもできなくは無いけど、できるだけ低遅延にするため今回は無視)。

USBデバイスというとなんだが難しい感じがしますが、キーボードやマウスなどの一般的なデバイスを作るのはとても簡単です。標準のライブラリや誰かが作成したライブラリを使うことで少ない量のコードで実現できます。

2.必要なもの

品名 価格 備考
Arduino Leonardoかその互換品 数百円~3千円 同じATmega32u4を搭載したArduino Microでもできるはずです。AliExpressを覗くと「Pro Micro」と書かれたマイコンボードが数百円程度で売られていて、これもコントローラー用の3.3Vの電源を別に用意すれば多分使えると思います(注文したので届いたら試すつもり)。今回はこれを使いました。
プレステのコントローラー端子 数百円 端子単体で売られてることはほぼ無いので、ハードオフのジャンクコーナーに大量にあるプレステか、変換器をバラして入手するのがベターです。
リード線 数百円 余っているものがあればそれで。
ピンヘッダ(10ピン以上) 数十円 Arduinoに刺して使います。

場合によっては他にも必要な物があるかも。
3.3V電源のない互換ボードで制作する場合はダイオードをいくつか挟むなどして5Vから3.3Vくらいの電圧を得るのが良さそうです。

3.ハードウェアの制作

部品が揃ったら制作に移りましょう。作業の流れとしては、リード線にピンヘッダをハンダ付けし、コントローラー端子にそのリード線をハンダ付けする、といった感じです。シールドを自作するというのも一つの手ですが、別の基板に移植したりする時に不便なので、今回は空中配線で行きます。

コネクタのピンアサイン

SnapCrab_NoName_2016-1-8_15-42-45_No-00

次のように配線を施していきます

コントローラー側のピン Arduino側のピン
1 DATA 7
2 COMMAND 6
4 GND GND
5 3.3V 3.3V(無い場合は5Vを降圧して使う)
6 ATTENTION 5
7 CLOCK 4

※うまく動かない場合は次のようにDATAピンとCOMMANDピンにプルアップ抵抗を付けてみてください。

SnapCrab_NoName_2016-1-8_16-7-39_No-00

4.プログラミング

Arduino IDEにスケッチ(プログラム)を打ち込み、マイコンボードに書き込みます。

ライブラリとしてPSX LibraryArduino HID Projectが必要になるので、インストールしておいてください。ライブラリのインストールの仕方は「Arduino ライブラリ 入れ方」とかで検索すれば出ると思います。

Arduino用PS2インターフェース・ライブラリもとても使いやすくて素晴らしいライブラリなのですが、ボタンの取得に10ミリ秒ほどの時間を要することと、5鍵のコントローラー(とその基板を流用したコントローラー)との相性が良くないという理由で今回は使いませんでした。

PCにキーボード操作を送信することは標準のKeyboard.hでもできますが、同時押しを6つまでしか送信できない上に、Arduino HID ProjectのNKRO Keyboardに比べると処理時間がかかります。

#include "HID-Project.h"
#include <Psx.h>

#define dataPin 7
#define cmndPin 6
#define attPin 5
#define clockPin 4

//キー割り当てです。2Pで使う場合は書き換えてください。
//右ShiftはKEY_RIGHT_SHIFT、右CtrlはKEY_RIGHT_CTRLです。
#define SCR1 KEY_LEFT_SHIFT
#define SCR2 KEY_LEFT_CTRL
#define KEY1 'z'
#define KEY2 's'
#define KEY3 'x'
#define KEY4 'd'
#define KEY5 'c'
#define KEY6 'f'
#define KEY7 'v'

Psx Psx;
unsigned int data;

void setup()
{
 NKROKeyboard.begin();
 Psx.setupPins(dataPin, cmndPin, attPin, clockPin, 1);
}

void loop()
{
 data = Psx.read();
 if(data&psxDown)NKROKeyboard.add(SCR1);else NKROKeyboard.remove(SCR1);
 if(data&psxUp)NKROKeyboard.add(SCR2);else NKROKeyboard.remove(SCR2);

 if(data&psxSqu)NKROKeyboard.add(KEY1);else NKROKeyboard.remove(KEY1);
 if(data&psxL1)NKROKeyboard.add(KEY2);else NKROKeyboard.remove(KEY2);
 if(data&psxX)NKROKeyboard.add(KEY3);else NKROKeyboard.remove(KEY3);
 if(data&psxR1)NKROKeyboard.add(KEY4);else NKROKeyboard.remove(KEY4);
 if(data&psxO)NKROKeyboard.add(KEY5);else NKROKeyboard.remove(KEY5);
 if(data&psxL2)NKROKeyboard.add(KEY6);else NKROKeyboard.remove(KEY6);
 if(data&psxLeft)NKROKeyboard.add(KEY7);else NKROKeyboard.remove(KEY7);
 
 NKROKeyboard.send();
}

このプログラムは1P用です。10行目あたりを書き換えることで2P用にできます。スタートボタン、セレクトボタンは必要であればライブラリのドキュメントを見ながら自分で書き足して作ってみてください。

書き込みに失敗する場合はシリアルポートの番号が合っていることを確認し、それでもダメならArduinoのリセットボタンを押しながら「マイコンボードに書き込む」をクリックし、「マイコンボードに書き込んでいます」と表示された直後にリセットボタンを離してみてください。

5.使ってみる

CWvLIxLUYAACIkA

どのPCでもUSBに挿すだけ。面倒なキー割り当て設定も不要。外部ツールを起動する必要もなし。

判定のブレはわかりませんが、遅延はうちにあるどのキーボードよりも少なくなりました。それでもPS2版よりは音が出るのが若干遅れている印象。アーケードももしかしたらこれくらいかも?おうち補正、ゲーセン補正、環境の違いがありすぎてよくわかりませんが。

6.さいごに

ここに書いたプログラムは簡易的なものでしかなく、遅延を増やさないことだけに注力したものです。1P2P両方で使いまわせるようにしたもの、INFINITAS以外のゲームでも使えるものなど工夫次第でもっと便利な変換器に仕上がると思います。設定をスイッチやシリアルコンソールで変更できるようにする、なんていうのも良さそうですね。
プレステのコントローラーの信号を読取るのにミリ秒単位の時間がかかっているので、コントローラーのボタンをArduinoに直接繋ぐことでさらに低遅延になるはずです。

今回はWebの情報を斜め読みした程度でも問題なく使えて、書き込み装置を必要としないという理由でArduinoを使いました。難易度は上がりますが、ArduinoにこだわらなければUSB内蔵PICでもできると思います。使ったことはありませんが、USB内蔵PICにはDIPパッケージのものもあり、値段も安いので、とにかく安く作りたい!という時にいいかもしれません(書き込み装置は必要になるけど)。

正式サービスを開始したにも関わらず問題は山積みなINFINITAS、曲数がPS2版と比べて少ないため、飽き(≒自分の実力の限界)が来るのも早いです。そんなもんだから、問題を自力で解決(本来ならユーザーがすることではない?)しようと、原因を探るためにクソみたいなスペックのPCで動かしたり、Windows XPで動かしたりしました。気分転換にタルコンガでプレーしたりもしました。結局、何も解決はしませんでしたが。

「このゲームはクソみたいな環境にインストールしたり、電子工作のネタにする以外することがないのか?」みたいなことがどこかに書かれていたましたが、ごもっともだと思います。

PS2版と同じくらいには快適に遊べるようになってほしいです。変換器を自作しないと専用コントローラーで快適に遊べないという状況はよくないので、ゲームパッド対応か新型専コンはよ!

USB接続の新型専コンが発売されたら、それはキーボードとして認識するのか、ゲームパッドとして認識するのか気になっている方も多いと思います。しかし、INFINITASでのみ使えればいいのであればキーボードやゲームパッドのようなHIDデバイスである必要が無いので、汎用性のない特殊なデバイスとして出してくる可能性だってあります。余談ですが、アーケードのIIDXのIO基板にFPGAが使われているらしく、その正体がEZ-USBではないかとも言われています。

あ、あと揚げ足を取るようで悪いけど、DirectInputは必ずしもゲームパッド用のAPIではなく、キーボードの取得にも使われるAPIで、現にINFINITASはキーボード入力の取得にDirectInputを用いてるので、ゲームパッド系のデバイスに対応してほしいという意味で「DirectInputに対応して欲しい」と言うのは変だと思うの。なんでDirectInputを使ってるってわかるかって?スクリーンキーボードを作ろうとした時に上手く動かなかったからだよ。

Arduino LeonardoでINFINITAS用の変換器を作る」への3件のフィードバック

  1. 通りすがり

    >JoyToKeyやJoyAdapter等のフリーソフト

    JoyToKeyはシェアウェアです。この文章は訂正された方がよろしいかと思われます。

    返信
  2. mato

    こちらのブログ記事を見て同じものを作りました。
    本当にわかりやすくて劇的に判定のブレがなくなり、私のどこかへ行った判定も日本に帰ってきました(笑)
    参考にさせていただき誠にありがとうございました。

    返信

コメントを残す

メールアドレスが公開されることはありません。