Top/Devel/電子工作/Arduino/ゲームコントローラー

ゲームコントローラー の変更点はてなブックマーク


#ref(finish01.jpg,right,around,33%)
&size(30){片手でゲームをしたい!};

~

…でも市販のゲームコントローラーはほぼ両手用。

~

~

ということで、今回はWiiの[[ヌンチャクコントローラー>http://www.amazon.co.jp/exec/obidos/ASIN/B000KF9E6Q/cubic9com-22]]を[[Arduino>../]] Leonardoに接続して、USB接続のゲームコントローラー((ゲームパッド、ジョイパッド、ジョイスティックなど色々な名前で呼ばれますが、ここでは、Windowsの流儀に沿って、ゲームコントローラーと呼びます。))を作ってみます。

Windows PCからは何の変哲もない普通のゲームコントローラーに見えるので、ゲームとの相性問題が出ることもないはず。

~

ヌンチャクを使ったゲームコントローラー(≒ジョイスティック)なので、JoyChuckという名前にしました。

#amazon(B008A36R2Y,left)
#clear

*必要なもの
#amazon(B00DFTFIF0)
#amazon(B014FBU8JW)
#amazon(B000KF9E6Q)
**ハードウェア
|項目|説明|h
|[[Arduino Leonardo>http://www.amazon.co.jp/exec/obidos/ASIN/B008A36R2Y/cubic9com-22]]|比較的小型で安価で簡単に使えるマイコンボード。&br;&br;なお、[[Arduino Uno>http://www.amazon.co.jp/exec/obidos/ASIN/B0044X2E5S/cubic9com-22]]でもUSB接続のHID(human interface device)を作ることはできますが、その場合ATMEGA8U2マイコンのファームウェアを書き換える必要があります。&br;難しそうなので、今回は素直にLeonardoを使用することにしました。|
|[[ヌンチャクコントローラー>http://www.amazon.co.jp/exec/obidos/ASIN/B000KF9E6Q/cubic9com-22]]|通常はWiiリモコンに接続して使うヌンチャクコントローラー。|
|[[WiiChuck>http://www.amazon.co.jp/exec/obidos/ASIN/B00DFTFIF0/cubic9com-22]]|Arduinoにヌンチャクコントローラーを接続しやすくする基板。&br;なくても頑張れば接続できるでしょう。|
|[[WiiChuck>http://www.amazon.co.jp/exec/obidos/ASIN/B014FBU8JW/cubic9com-22]]|Arduinoにヌンチャクコントローラーを接続しやすくする基板。&br;なくても頑張れば接続できるでしょう。|
|ピンヘッダ(4P)|何でも良いです。今回は [[秋月電子通商で購入しました>http://akizukidenshi.com/catalog/g/gC-03950/]]。|

**ソフトウェア
|項目|説明|h
|chuck_funcs.h|ヌンチャクコントローラーの情報をArduinoで取得するための関数が定義されたヘッダファイル。&br;[[todbotさんのgithub>https://github.com/todbot/wiichuck_adapter/blob/master/firmware/WiichuckDemo/nunchuck_funcs.h]]からダウンロードしてください。&br;(「Raw」を右クリックして名前をつけて保存。)|
|USBAPI.h|USB機器用ヘッダファイル。&br;[[Imaginary Industries>http://www.imaginaryindustries.com/blog/?p=80]]からダウンロードしてください。&br;または、&ref(USBAPI.h.diff,,USBAPI.hのパッチ);をお手持ちの環境のUSBAPI.hに当ててください。|
|HID.cpp|HID用プログラム。&br;[[Imaginary Industries>http://www.imaginaryindustries.com/blog/?p=80]]からダウンロードしてください。&br;または、&ref(HID.cpp.diff,,HID.cppのパッチ);をお手持ちの環境のHID.cppに当ててください。|
|leoJoy.ino|テスト用ランダム入力スケッチ。&br;[[Imaginary Industries>http://www.imaginaryindustries.com/blog/?p=80]]からダウンロードしてください。|
|JoyChuck.ino|ヌンチャクコントローラをゲームパッドにするスケッチ。&br;下記からダウンロードしてください。|
#clear

*手順
**ソフトウェアの準備(Arduino Leonardoをゲームコントローラーとして認識させる)
+arduinoの開発環境をインストールしたディレクトリの配下のhardware\arduino\cores\arduinoを開く。~
(私の場合は、「C:\Program Files (x86)\Arduino\hardware\arduino\cores\arduino」でした)
+上記で示したUSBAPI.hとHID.cppをコピーする。
+USBケーブルを挿す。
+leoJoy.inoを開き、Arduino Leonardoに書き込む。

**ソフトウェアの動作確認
#ref(device_manager.jpg,right,around,50%)
+[コントロールパネル]>[デバイス マネージャー]>[ヒューマン インターフェース デバイス]を開く。
+「HID 準拠ゲーム コントローラー」が表示されていることを確認する。
#clear
#ref(device_and_printer.jpg,right,around,50%)
+[コントロールパネル]>[デバイスとプリンター]を開く。
+「デバイス」欄に「Arduino Leonardo」が表示されていることを確認する。
+右クリックし、「ゲームコントローラーの設定」をクリックする。
+「プロパティ」ボタンをクリックする。
#clear
#ref(game_controller_property.jpg,right,around,50%)
+右のようなウィンドウが表示され、「軸」「ボタン」「ハットスイッチ」がランダムに入力されていることを確認する。~
(leoJoy.inoはランダムな入力を発生させるスケッチです)
#clear

**ハードウェアの準備
#ref(joychuck.jpg,right,around,25%)
+WiiChuckにピンヘッダを半田付けする。(labs.thingm.comと書いてある側からピンヘッダの短い方を差込み、逆側から半田付けする。)
+ArduinoのGNDピンに-、3.3Vピンに+、D2ピン((SDAピンでも可。))にd、D3ピン((SCLピンでも可。))にcを接続する。
+WiiChuckにヌンチャクコントローラを挿す。(ヌンチャクの金属端子の凹みがある方が上になるように挿す。)
#clear

**ソフトウェアの準備(ヌンチャクコントローラーをゲームコントローラーとして使えるようにする)
+JoyChuck.inoとchuck_funcs.hをJoyChuckというフォルダに格納する。
+nunchuck_funcs.hの25行目〜34行目は次のようにコメントアウトする。((Uno用の関数のため。))
#code(C,nonumber,nooutline){{
// Uses port C (analog in) pins as power & ground for Nunchuck
static void nunchuck_setpowerpins()
{
/*
#define pwrpin PORTC3
#define gndpin PORTC2
    DDRC |= _BV(pwrpin) | _BV(gndpin);
    PORTC &=~ _BV(gndpin);
    PORTC |=  _BV(pwrpin);
    delay(100);  // wait for things to stabilize        
*/
}
}}
+JoyChuck.inoを開き、Arduino Leonardoに書き込む。

**最終動作確認
+[コントロールパネル]>[デバイスとプリンター]を開く。
+「デバイス」欄に「Arduino Leonardo」が表示されていることを確認する。
+右クリックし、「ゲームコントローラーの設定」をクリックする。
+「プロパティ」ボタンをクリックする。
+ヌンチャクコントローラーのジョイスティックの操作が、軸欄に反映されることを確認する。
+ヌンチャクコントローラーのCボタンの操作が、ボタン欄の1に反映されることを確認する。
+ヌンチャクコントローラーのZボタンの操作が、ボタン欄の2に反映されることを確認する。


~

以上で終了です。お疲れ様でした :)

~

#ref(joychuck02.jpg,right,around,33%)
Arduinoの基板がむき出しだとトラブルの元なので、
[[ALTOIDSミントサイズ缶>http://www.switch-science.com/catalog/922/]]に穴を空けて線を通し、穴部分の切り口で線が切れないようにスポンジ(激落ちくんなどでも可)で保護するとスマートです。
#clear


*スケッチ
#code(C,nonumber,nooutline,JoyChuck.ino)


*設定について
-DEBUG定数を1にすると、シリアルモニタにヌンチャクのセンサの現在の値が表示されます。

*JoyState_tのメンバ変数とゲームコントローラーの関係
|xAxis, yAxis|左スティックに対応。0-255の範囲で指定。|
|zAxis, rudder|右スティックに対応。0-255の範囲で指定。|
|JoyState_tのメンバ|説明|h
|buttons|ボタンのオンオフをビットで指定。&br;1番目のボタンは1/0でオンオフを表現、2番目のボタンは2/0でオンオフを表現、3番目のボタンは4/0でオンオフを表現…という感じ。&br;各ボタンの同時押し込みは加算で表現する。|
|hatSw1|POVキーに対応。上方向を0として、時計回りに0〜7で指定。|

*デバイスとプリンターに表示される名称を変更したい
USBCore.cppのSTRING_IPRODUCTとSTRING_IMANIFACTUREを修正してください。


*【発展】ボタンを増やす
#ref(ctrlpad03.jpg,right,around,25%)
ヌンチャクコントローラーのボタン数は2個。これではちょっと少ない。

そこで発展系としてボタンを増やしてみます。

Arduinoではマイコン内にプルアップ抵抗を持っていて、設定で使用できるため、スイッチのみ用意すればボタンを簡単に増やすことが出来ます。([[参考>http://mag.switch-science.com/2013/05/23/input_pullup/]])

右の写真は十字キーを増設してヌンチャクコントローラーと合体させたものです。
#clear

**必要なもの
#amazon(B008382SYM)
|項目|説明|h
|[[タクトスイッチ>http://www.amazon.co.jp/exec/obidos/ASIN/B008382SYM/cubic9com-22]]||
|[[ユニバーサル基板>http://www.amazon.co.jp/exec/obidos/ASIN/B001TRRLN2/cubic9com-22]] または [[ブレッドボード>http://www.amazon.co.jp/exec/obidos/ASIN/B009ALRR9M/cubic9com-22]]||
#clear

**あるとよいもの
#amazon(B0069U9DBC)
|項目|説明|h
|[[DS LiteやPSPの保守パーツ>http://www.amazon.co.jp/exec/obidos/ASIN/B0069U9DBC/cubic9com-22]]|十字キーやボタンの外装とラバードームを利用します。&br;秋葉原なら三月兎などで買えます。|
|[[Y字ドライバ>http://www.amazon.co.jp/exec/obidos/ASIN/B0052VY6DO/cubic9com-22]]|ヌンチャクコントローラーには特殊なネジが使われています。&br;頑張ればマイナスドライバでもネジを破壊しつつ開けられますが、安全に開けるにはこれが必要です。&br;秋葉原なら三月兎などで買えます。|
#clear

**手順
+ユニバーサル基板にタクトスイッチを挿す。
+タクトスイッチの =□= となっている4本の足のうち、=の1本ずつをGNDとデジタル端子に接続する。(下記ではデジタル10番ピンを使用)~
複数のスイッチを設けたいときはGNDは共有しても大丈夫です。
+スケッチのinclude文の下辺りに下記を追加する。
#code(C,nonumber,nooutline){{
#define PIN_SWITCH1 10

byte switch1;
}}
+スケッチのsetup()の中に下記を追加する。
#code(C,nonumber,nooutline){{
pinMode(PIN_SWITCH1, INPUT_PULLUP);
}}
+スケッチのloop()の中に下記を追加する。(下記はタクトスイッチが押されると、POVキー上が入力されるようになる)
#code(C,nonumber,nooutline){{
switch1 = digitalRead(PIN_SWITCH1);
Serial.print(" SWITCH1:"); Serial.print(switch1);
if (switch1 == LOW) {
    joySt.hatSw1 = 0;
}
}}
+DEBUG定数を1にしてArduinoに書き込むと、シリアルモニタに"SWITCH1:1"と表示され続け、スイッチを押すと"SWITCH1:0"に表示が変わるはずです。~
#clear
#ref(ctrlpad02.jpg,right,around,25%)
+あとはお好みでラバードームと外装を両面テープで貼ってください。
#clear
#ref(ctrlpad03.jpg,right,around,25%)
+また、ヌンチャクコントローラと合体させたい場合は、Y字ドライバでコントローラを開けた後、外装を適当に切断し、埋め込んでください。
#clear

*関連
[[../楽器]]

*参考
-[[スイッチサイエンス - WiiChuckアダプタ>http://www.switch-science.com/catalog/221/]]
-[[“WiiChuck” Wii Nunchuck Adapter Available » todbot blog>http://todbot.com/blog/2008/02/18/wiichuck-wii-nunchuck-adapter-available/]]
-[[Turning an Arduino Leonardo into a joystick. | Imaginary Industries>http://www.imaginaryindustries.com/blog/?p=80]]
-[[意外と知られていない?INPUT_PULLUP | スイッチサイエンス マガジン>http://mag.switch-science.com/2013/05/23/input_pullup/]]

*Amazon
#amazon(B008A36R2Y,left)
#amazon(B000KF9E6Q,left)
#amazon(B014FBU8JW,left)
#amazon(4800711460,left)
#amazon(4873117895,left)
差分 一覧