ファミコン世代ではないのですが、最近ESP32などマイコンボードを使ったゲームエミュレーター関連のものを製作していたことから、NES(ファミコン)のゲームをプレイして遊ぶことが多くなりました。
「スーパーマリオブラザーズ」や「ドンキーコング」など今遊んでも当時のゲームは懐かしくて楽しいですよね!
この投稿をInstagramで見る
任天堂のファミリーコンピューターは、Z80という8ビットCPUで動かしていたようです。
・・・ごめんなさい、調べてみると実際には『6502』というCPUが採用されていたみたいですね!
ファミコンでは当時あまり普及していないCPUを採用することで、他社が解析しにくくコピー製品が作りにくいといった配慮がされていたようです。(簡単に書いちゃいましたが調べてみると結構面白いですよ!)
当時のアーケードゲームなどその多くはZ80 CPUが使われていました。
「パックマン」や「ギャラガ」といった当時流行ったアーケードゲームの代表作がありますが、今でもESP32を使い2つのコアを活かしエミュレーターで動かすことによりプレイして楽しむことが出来ます。
この投稿をInstagramで見る
マイコンボードを使いエミュレーターにより動かすことが出来る当時のゲームなんですが、PC用のエミュレーターを使うと大きな画面でより楽しむ事が出来ます。
PC用のエミュレーターを使って遊ぶ場合キーボードでも操作することは出来るのですが、やはりゲームパッドを使うと操作しやすくなります。
USBゲームパッドは様々なものが販売されていますが、私の場合あまりゲームには詳しくなく、そして普段電子工作を趣味として楽しんでいる者としては自作したものを使ってゲームをプレイしたい・・・
そんなことから以前スーパーファミコンのコントローラーの内部基板を自作して、USBゲームパッドに改造しました。
実物のスーファミコントローラーを使っているので、ゲームをプレイする際にテンションも上がります!
スーパーファミコンのコントローラーは十字キー以外に[A][B][X][Y][L][R]キーも使えるので、スーファミのゲーム以外にもファミコンやDSなどにも使えることから結構重宝しています!
この投稿をInstagramで見る
そして同様な手順で実物のファミコンコントローラーをUSBゲームパッドに改造する基板を製作してみることにしました。
その準備段階として、今回はブレッドボードを使ったテストを見ていきたいと思います。
ブレッドボード上にファミコンコントローラーのように配置したタクトスイッチを使いPC用のゲームエミュレーターを操作することが出来るので、これだけでも電子工作としては楽しいと思います!
この投稿をInstagramで見る
目次
ファミコンコントローラーをUSBゲームパッド化!まずはブレッドボードで組んでみる
PCとUSB接続してUSBホストとして機能するチップはいくつかありますが、私はArduinoから電子工作を始めたこともあり何かとAVRチップを使うのが多いので、こちらではArduinoを使って行っていきたいと思います。
ArduinoでHID(Human Interface Device)機能がサポートされているボードは、Arduino LeonardoやPro Microがあります。
USBケーブル経由でマウスやキーボードといったPC操作を行うことが出来ます。
最近登場したArduino Uno R4にはこの機能が標準でサポートされていますね!
こちらでは小さなブレッドボードでUSBゲームパッドのテストが出来るようにPro Microを使っています。
Arduino Leonardoでも同様に動かすことが出来ます。
接続
接続は非常に簡単です!
ファミコンのコントローラーには、[↑][→][↓][←][A][B][SELECT][START]の計8個のキーがあります。
これら配置するボタンのI/O端子の割り当てはこのようにしました。
ボタン | Pro Micro(またはArduino Leonardo) |
↑(UP) | D2 |
→(RIGHT) | D3 |
↓(DOWN) | D4 |
←(LEFT) | D5 |
A | D6 |
B | D7 |
SELECT | D8 |
START | D9 |
スイッチはプルアップして使っているので、各I/O端子とGND間に接続するだけです。
12mmタクトスイッチを使い上記写真のように配置すると操作もしやすいと思います。
大きなタクトスイッチをブレッドボードに並べる場合、少しタクトスイッチを加工すると配置の自由度が上がります。
スケッチの書き込み
接続が完了したらスケッチの書き込みです。
Pro Micro(またはArduino Leonardo)をUSBゲームパッドとして機能するように簡単なスケッチを作ってみました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 | // NES USB GamePad Sketch V1.0 // https://burariweb.info // --------- Switch Pinout --------- // D2(SW1) = UP // D3(SW2) = RIGHT // D4(SW3) = DOWN // D5(SW4) = LEFT // D6(SW5) = Bottan_A // D7(SW6) = Bottan_B // D8(SW7) = Bottan_SELECT // D9(SW8) = Bottan_START // ---------------------------------- #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() { Serial.begin(115200); // Initialize Button Pins for(int i=2; i <= 9; i++) { pinMode(i, INPUT_PULLUP); } // Initialize Joystick Library Joystick.begin(); Joystick.setXAxisRange(-1, 1); Joystick.setYAxisRange(-1, 1); } // 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 <= 7; 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: // RIGHT if (currentButtonState == 1) { Joystick.setXAxis(1); } else { Joystick.setXAxis(0); } break; case 2: // DOWN if (currentButtonState == 1) { Joystick.setYAxis(1); } else { Joystick.setYAxis(0); } break; case 3: // LEFT if (currentButtonState == 1) { Joystick.setXAxis(-1); } else { Joystick.setXAxis(0); } break; case 4: // Bottan_A Joystick.setButton(0, currentButtonState); break; case 5: // Bottan_B Joystick.setButton(1, currentButtonState); break; case 6: // Bottan_Select Joystick.setButton(2, currentButtonState); break; case 7: // Bottan_Start Joystick.setButton(3, currentButtonState); break; } lastButtonState[index] = currentButtonState; } KeyPrint(); } delay(10); } void KeyPrint(){ Serial.print("UP: "); Serial.print(lastButtonState[0]); Serial.print(" RIGHT: "); Serial.print(lastButtonState[1]); Serial.print(" DOWN: "); Serial.print(lastButtonState[2]); Serial.print(" LEFT: "); Serial.print(lastButtonState[3]); Serial.print(" BUTTON A: "); Serial.print(lastButtonState[4]); Serial.print(" BUTTON B: "); Serial.print(lastButtonState[5]); Serial.print(" SELECT: "); Serial.print(lastButtonState[6]); Serial.print(" START: "); Serial.println(lastButtonState[7]); } |
上記スケッチは[ArduinoJoystickLibrary]というライブラリを使っています。
以下GitHubのサイトからライブラリをダウンロードしてArduino IDEにインストールしておく必要があります!
ダウンロードしたライブラリのZIPファイルをArduino IDEにインストールします。
ライブラリのインストールが完了したらスケッチの書き込みです。
Arduino IDEのボード設定は[Arduino Leonardo]にして認識したシリアルポートを選択して、あとは上記スケッチを書き込めば完了です!
今回ボードはPro Microを使っていますが、Arduino Leonardoを使う場合も同様です!
ゲームエミュレーターで使ってみる!
あまりゲームエミュレーターに関しては詳しくないのですが、こちらではMac環境で使えるOpenEmuで使う方法を簡単に見ておきます。
参考 OpenEmu Top PageOpenEmu上記エミュレーターをインストール後、プレイしたいゲームデータを探します。
ゲームROM配布サイトはいろいろとあるようですが、一例としてサイトリンクも貼っておきます。
ダウンロードしたゲームROMデータをOpenEmuにドラッグして格納します。
いくつかゲームROMを入れてみました。
あとはお好みのゲームを立ち上げてプレイします。
ゲームROMを立ち上げ、まず設定項目の中にある[コントローラを編集…]からボタンを割り当てていきます。
[入力]の項目はデフォルトでは[キーボード]になっています。ブレッドボードで組んだPro Micro(またはArduino Leonardo)をPCと接続すると、[Arduino Leonardo]という項目が出てくるのでこれを選択します。
あとは[ゲームプレイボタン]の各ボタン項目で、実際にスイッチを押してキーを割り当てていけばOKです。
無事ブレッドボードで組んだものでファミコンのゲームを操作することが出来ました!
この投稿をInstagramで見る
PCBの製作
ブレッドボードでの簡単なテストですが問題なく動作させることが出来ました。
これだけでも十分ゲームをプレイすることが出来るので、電子工作としては面白いと思います!
ブレッドボードで組んだ回路&スケッチをベースに、実物のファミコンコントローラーに組み込める基板の設計を行っていきます。
Pro MicroやArduino LeonardoはATmega32U4というMCUが使われています。
ATmega32U4を使った回路設計、およびファミコンコントローラー内の基板形状を作る必要があります。
まずFusion360を使い基板形状&ビス穴等をトレースしていきました。
前回スーパーファミコンのコントローラーを使いUSBゲームパッド化する基板を作った事があるので製作手順はほぼ同じなんですが、ファミコンのコントローラーの上蓋・下蓋にはいくつか突起があります。
この突起部分に基板上のパーツが干渉してしまうとケースを閉じることが出来なくなってしまうので、前回は現物合わせでパーツを配置し何度か微調整等を行いました。
パーツ点数はさほど多くないので今回もその方法でもいいのですが、パーツの配置を後々微調整したりと何かと面倒だったので今回は基板表裏に干渉するコントローラーの上蓋・下蓋にある突起部分もFusion360を使い正確にトレースしたものをKiCadにインポートして行いました。
基板発注の際には使用しないUser1/User2・・・といったレイヤーにそれら位置が分かるDXFファイルを読み込ませて基板設計を開始、基板を固定するための窪みやビス穴などは当然基板形状に反映されるEdges.Cutsに読み込ませるのですが、上蓋の突起で干渉する部分をUser1レイヤーに下蓋の突起干渉部分はUser2に取り込むといった感じです。
これで基板設計時に全ての干渉部分がKiCad内で確認できるので非常に便利でした!
何かしら既存製品の内部基板を自作基板に入れ替えて改造する・・・もともとやりたいと思っていたこのようなプロジェクトにも応用出来そうですね!
【追記】USBゲームパッド化基板、完成しました!
ファミコンのコントローラーをUSBゲームパッド化する基板が完成しました。
動作確認も問題なし!
ファミコンのコントローラーを使い当時のファミコンゲームをプレイする、なかなか楽しいものですね!
最後に!
PC用のゲームエミュレーターを動かす際に今回のようにブレッドボードで組んだものでも十分操作することが出来ます。
Pro MicroやArduino Leonardoといったボードがあれば、あとはスイッチの接続のみという簡単な構成で組めるので電子工作で試してみるのも面白いと思います!
また回路構成&簡単なスケッチで動かすことが出来るので、USBゲームパッド化する基板を自作して実物のファミコンコントローラーに組み込めば操作性もアップして、当時のコントローラーでファミコンのゲームをプレイする・・・テンションも上がって楽しいかと思います。
製作したPCBが届き上手く機能した時に、基板設計の話などを含めまた詳しくご紹介できればと思います。
コメントを残す