DIY Arduino USBゲームコントローラー - 高性能ゲームパッドを自作
必要なパーツと用品
| パーツ | 数量 | 備考 |
|---|---|---|
| SparkFun Pro Micro - 5V/16MHz | 1 | |
| Arduino Leonardo | 1 | |
| SparkFun プッシュボタンスイッチ 12mm | 12 | |
| 抵抗 10kΩ | 1 | |
| カスタムエッチングPCB | 1 | |
| UTSOURCE 電子パーツ | 1 |
必要な工具と機械
- 塩化第二鉄粉末 (PCBエッチング用)
- 3Dプリンター (汎用)
- コードレスドリル/ドライバー
使用するアプリとオンラインサービス
- Arduino IDE
- Autodesk Fusion 360
プロジェクト概要
動画
イントロ
今回はElectroPunkz Labsで最近取り組んでいる「DIYゲーミングUSBコントローラー」について紹介します。
アイデアは、ボタンとアナログジョイスティックを備えた安価なATmega32UベースのUSBコントローラーを作り、以下のようなゲームで遊べるようにすることです:
NFS、GTA、Half-Life、Little Fighter 2! など
2つのフォームファクタで製作しました。1つ目はPS1またはSNES配置ベース、もう1つはアナログスティックとボタンを備えた本格的なXbox USBコントローラー(まだ最終版ではない)。

今回はV1としてPS1レイアウトのコントローラーを作ります!
まずプロジェクト動画を見ることをお勧めします。
材料
ハードウェアはシンプルで入手しやすいものばかり(PCBを除く。添付PDFで自作可能)。
- Arduino Leonardo / Pro Micro / ATmega32U
- ボタン (タクトスイッチ)
- カスタムエッチングPCB (ボタンマトリックスPDF添付)
- 10kΩ抵抗
- ジャンパーワイヤー
ありがとうございます UTSOURCE.net がこのプロジェクトの電子部品を提供してくれました! UTSOURCE.netでは、このプロジェクトで使用したようなあらゆる種類の電子部品を扱っています。
製作プロセス (配線、組み立て等)
まず基本セットアップを準備します。これは基本的に12個のプッシュボタンをPro Microとプルダウン構成で接続したものです。
ブレッドボードでテスト後、上記回路図に基づいてPCBを設計しました。

(OrCad Cadenceで) PCB設計後、トップレイヤーのPDFを光沢紙に印刷。
光沢紙をPCB形状にカットし、銅張り基板に置いて熱を加えてインクを転写(基本的なトナートランスファー法。このトピックについての動画を参照)。

PCBが準備できたらエッチング液に浸してエッチング、その後部品用の穴を開け、DIYゲームコントローラーPCB の完成!
回路図に従って部品を実装すれば回路完成。
回路が完成したら、Fusion 360でPCBハウジング/ケースを設計して3Dプリント。

あとはコードをアップロードしてゲームで遊ぶだけ。
コード
添付のコードをPro Microにアップロード。
アドバイス: まずボード/セットアップを徹底的にテストし、PCBパターンの抵抗値と導通をチェックしてください。何か欠けていると大量のキーボードエラーが発生します。欠落したグランドラインがピンに不規則な信号を送り、Pro Microがランダムなキーを押し続けることになり、再プログラミングが非常に困難になります。
テスト
まずメモ帳を開き、コントローラーのキーを押して、割り当てられた正しい文字が表示されるか確認。またはキーボードテストアプリ/Webアプリを使用。
コード通りに動作していれば、任意のゲームを開いてこのDIYゲーミングコンソールでプレイ!
動画を見てね。
今後の改善点
まずこのセットアップにアナログジョイスティックを追加して、マウスでプレイヤーを操作するような本格的なゲーム(Xbox Oneコントローラーのような)に対応させます。
V2ではXbox OneコントローラーレイアウトのプロパーなPCBを作る予定。お楽しみに!
問題があればコメントで教えてください!
コード
CODE
#includeint WPin = 2; // UP int SPin = 3; // DOWN int APin = 4; // LEFT int DPin = 5; // RIGHT int UPLpin = 7; // upper left Q int UPRpin = 9; // upper right int Xpin = 14; // x int Apin = 10; // i int Ypin = 15; // y int Bpin = 16; // b void setup() { pinMode(WPin, INPUT); pinMode(SPin, INPUT); pinMode(APin, INPUT); pinMode(DPin, INPUT); pinMode(UPLpin, INPUT); pinMode(UPRpin, INPUT); pinMode(Xpin, INPUT); pinMode(Apin, INPUT); pinMode(Ypin, INPUT); pinMode(Bpin, INPUT); digitalWrite(WPin, HIGH); digitalWrite(SPin, HIGH); digitalWrite(APin, HIGH); digitalWrite(DPin, HIGH); digitalWrite(UPLpin, HIGH); digitalWrite(UPRpin, HIGH); digitalWrite(Xpin, HIGH); digitalWrite(Apin, HIGH); digitalWrite(Ypin, HIGH); digitalWrite(Bpin, HIGH); Keyboard.begin(); } void loop() { if (digitalRead(WPin) == 0) { Keyboard.write('W'); delayMicroseconds(1); } if (digitalRead(SPin) == 0) { Keyboard.write('S'); delayMicroseconds(1); } if (digitalRead(APin) == 0) { Keyboard.write('A'); delayMicroseconds(1); } if (digitalRead(DPin) == 0) { Keyboard.write('D'); delayMicroseconds(1); } if (digitalRead(UPLpin) == 0) { Keyboard.write('q'); delayMicroseconds(1); } if (digitalRead(UPRpin) == 0) { Keyboard.write('e'); delayMicroseconds(1); } if (digitalRead(Xpin) == 0) { Keyboard.write('x'); delayMicroseconds(1); } if (digitalRead(Apin) == 0) { Keyboard.write('i'); delayMicroseconds(1); } if (digitalRead(Ypin) == 0) { Keyboard.write('y'); delayMicroseconds(1); } if (digitalRead(Bpin) == 0) { Keyboard.write('b'); delayMicroseconds(1); } }
カスタムパーツとエンクロージャ
(Fusion 360ファイル等は別途提供)
回路図
(回路図ファイルは別途提供)
製造プロセス
- Arduino NanoとMPU-6050で作るリアルタイムジャイロスコープゲーム
- Arduinoデジタルダイス: LCD表示の乱数ジェネレーター自作
- 自作16×8 LEDマトリックスでテトリスゲーム:Arduino Nano実装
- スマートArduino水筒:リアルタイム監視とアラート機能付き
- Pixel Chaser: Arduino Nanoで作るワンタップLEDゲーム
- Alexa対応Arduinoホームコントローラー:音声でスマートホーム自動化
- Arduino Nanoで作るNeoPixelマトリックス版Pongゲーム
- スマート手話グローブ:ジェスチャーをテキスト/音声に変換
- Arduino NanoとWS2812 LEDストリップで作る1次元ポンゲーム - 完全DIYガイド
- ESP32-CAMで作るAI顔認識ドアロックシステム:ローカル処理でプライバシー保護
- DIY LEDルーレットゲーム – Arduino Nanoで作る1人用アーケードゲーム