スポンサーリンク

本物ファミコンのコントローラをUSBゲームパッドに簡単改造

FullSizeRender
エミュレータでファミコンを遊ぶ時、本物のコントローラーで遊べたらいいのになと思っていたら、簡単にUSB接続のゲームパッドが作れたのでご紹介します。

コントローラの改造
用意するもの
FullSizeRender

  • ファミコンのコントローラー(Iコン)
  • ATmega32U4 Pro micro Arduino互換ボード
  • USBケーブル
これだけです。ファミコンのコントローラはハードオフのジャンクを買って取り外します。「ATmega32U4 Pro micro Arduino互換ボード」はいろいろな種類の互換ボードが販売されているので、なるべく小さいのを選んでください。
Pro Micro 5V/16MHz
スイッチサイエンス


分解
FullSizeRender
コントローラーの背面のネジを6か所外すと、裏蓋が外れ、基板が分離できます。Arduinoの基板はこんな感じに収めようと思います。

配線
FullSizeRender
まずは基板の裏についているファミコン本体につながる配線を、取り外します。
次にarduinoと基板とを配線していきます。基板の右上の先ほど抜いた配線の穴と、ICのピンに配線します。
IMG_3547

  • 基板の右上のピン  ->  ArduinoのVCC
  • 基板の右上から4つ目のピン  ->  ArduinoのGND
  • ICの1番ピン(ICの足の一番右下)  ->  arduinoのIO9
  • ICの4番ピン(右下から左へ4つめ)  ->  arduinoのIO2
  • ICの5番ピン  ->  arduinoのIO3
  • ICの6番ピン  ->  arduinoのIO5
  • ICの7番ピン  ->  arduinoのIO4
  • ICの13番ピン(ICの足の右上から左へ4つめ)  ->  arduinoのIO7
  • ICの14番ピン  ->  arduinoのIO6
  • ICの15番ピン  ->  arduinoのIO8
配線はこれだけです。

収納
USBケーブルの、持ち手の部分の厚みが邪魔で、蓋が閉まらないので、できるだけ薄くします。
FullSizeRender
ニッパで外装をむしり取りました。
FullSizeRender
arduinoを両面テープでコントローラに貼り付けし、マイコンボードと接する基板の部分にはショートを防ぐために、カプトンテープを貼っておきます。
FullSizeRender
基板が収まることを確認して蓋をしてネジを閉めれば、コントローラの改造は終了。
FullSizeRender
USBケーブルが、kazzoのキットにも使っている、余り物で水色なのがちょっといまいちですが、皆さんは黒いケーブルをお勧めします。
これ↓に付属のUSBケーブルです。
kazzosale
USBケーブル水色でしょ…

プログラム
ArduinoJoystickLibrary
ATmega32U4 Pro micro Arduino互換ボードを、パソコンからジョイスティックとして認識できるようにします。そのためにArduinoJoystickLibraryを使用します。
ArduinoJoystickLibraryのGitHubより、zipファイルをダウンロードして、展開します。「Joystick」というフォルダができるので、そのフォルダをArduinoのライブラリのフォルダに入れます。
macですと「書類」→「Arduino」→「libraries」の中へ入れるだけです。

arduinoの設定
leonald
ボードを設定します。「ツール」→「ボード」→「Arduino Leonardo」を選択します。
USBをパソコンに接続してください。

arduinoserial

書き込むためのシリアルポートを設定します。「ツール」→「シリアルポート」に先ほど接続した「Arduino Leonardo」があるので、それを選択してください。
これでセットアップは終了です。

ジョイスティックのスケッチ
こちらのスケッチを丸ごとコピペしてください。

#include <Joystick.h>
Joystick_ Joystick(JOYSTICK_DEFAULT_REPORT_ID,JOYSTICK_TYPE_GAMEPAD,
 4, 0,                  // Button Count, Hat Switch Count
 true, true, false,     // X and Y, but no Z Axis
 false, false, false,   // No Rx, Ry, or Rz
 false, false,          // No rudder or throttle
 false, false, false);  // No accelerator, brake, or steering
void setup() {
 // Initialize Button Pins
 pinMode(2, INPUT_PULLUP);
 pinMode(3, INPUT_PULLUP);
 pinMode(4, INPUT_PULLUP);
 pinMode(5, INPUT_PULLUP);
 pinMode(6, INPUT_PULLUP);
 pinMode(7, INPUT_PULLUP);
 pinMode(8, INPUT_PULLUP);
 pinMode(9, INPUT_PULLUP);
 // Initialize Joystick Library
 Joystick.begin();
 Joystick.setXAxisRange(-1, 1);
 Joystick.setYAxisRange(-1, 1);
 Joystick.setYAxis(0);
 Joystick.setXAxis(0);
 Joystick.setButton(0, 0);
 Joystick.setButton(1, 0);
 Joystick.setButton(2, 0);
 Joystick.setButton(3, 0);
}
// Last state of the buttons
int lastButtonState[8] = {0,0,0,0,0,0,0,0};
void loop() {
 // Read pin values
 for (int index = 0; index < 8; index++)
 {
   int currentButtonState = !digitalRead(index + 2);
   if (currentButtonState != lastButtonState[index])
   {
     switch (index) {
       case 0: // UP
         if (currentButtonState == 1) {
           Joystick.setYAxis(-1);
         } else {
           Joystick.setYAxis(0);
         }
         break;
       case 1: // DOWN
         if (currentButtonState == 1) {
           Joystick.setYAxis(1);
         } else {
           Joystick.setYAxis(0);
         }
         break;
       case 2: // RIGHT
         if (currentButtonState == 1) {
           Joystick.setXAxis(1);
         } else {
           Joystick.setXAxis(0);
         }
         break;
       case 3: // LEFT
         if (currentButtonState == 1) {
           Joystick.setXAxis(-1);
         } else {
           Joystick.setXAxis(0);
         }
         break;
       case 4: // FIRE1
         Joystick.setButton(0, currentButtonState);
         break;
       case 5: // FIRE2
         Joystick.setButton(1, currentButtonState);
         break;
       case 6: // FIRE3
         Joystick.setButton(2, currentButtonState);
         break;
       case 7: // FIRE4
         Joystick.setButton(3, currentButtonState);
         break;
     }
     lastButtonState[index] = currentButtonState;
   }
 }
 delay(10);
}
これは、ライブラリに付属するサンプルプログラムのGamepadExampleをちょっといじって、4ボタンに対応させただけのコードです。このプログラムをコンパイルしてArduinoに書き込みます。

完成
FullSizeRender
これでUSB版本物ファミコンコントローラ(ゲームパッド)ができました!!USBケーブルの色が悔やまれます…

早速ファミコンエミュレータで使えるか試してみましょう。
エミュレータにはMac用のOpenEmuという物を使いました。
コントローラの設定画面の「入力」に「Arduino Leonardo」が現れます。
スクリーンショット 2018-09-16 13.43.43のコピー
Arduino Leonardoのマイコンボードがコントローラとして動作してくれています。
ここで各ボタンを設定していきます。ここまでできれば大丈夫!

遊ぶ
FullSizeRender
遅延も感じない良好な操作性です。まさにファミコンで遊んでいる!!っていう感覚です。画面もとても綺麗でとてもいいですね。
同様にIIコンも改造すれば2人で遊ぶとことができるかもしれません。簡単なので後で試してみたいと思います。
2018.9.17追加
IIコンも作っちゃいました↓!!

簡単なので、ファミコンエミュレータで遊ばれている方には、お勧めの改造です。

関連記事

コメント

pocket line hatebu image gallery audio video category tag chat quote googleplus facebook instagram twitter rss search envelope heart star user close search-plus home clock update edit share-square chevron-left chevron-right leaf exclamation-triangle calendar comment thumb-tack link navicon aside angle-double-up angle-double-down angle-up angle-down star-half status