M5Stackでファミコンコントローラーを動かしてみる


昨年M5Stackのハッカソンで、ファミコンのコントローラーを繋いでみたので、忘れないように記録を残しておきます。

ちなみに、ハッカソンで作ったのははこちら

https://protopedia.net/prototype/1849

## 繋ぐ機器
使うのは、みんなの家に1個はあるハドソンのジョイコン。ファミコンの前の部分に刺さるさつです。

![ジョイコン](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189829/65b92daa-cb42-5622-b089-58e956a4be33.png)

ファミコン本体のコントローラーを切っても使えると思うけど、このジョイコンならD-SUB 15ピン(２列タイプ)がそのまま刺さるのでかなり便利。
<img width="50%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189829/a77a33ae-671a-216d-8195-d2c63f57356e.png"><img width="50%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189829/7b0f3ebe-25be-3d10-eabe-7b75a9241eb6.png">

## コネクタの作成

D-SUB 15ピン（２列タイプ）のオス端子を用意します。安いのなら100円ちょっとで買えます。

![コネクタ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189829/99ae363c-4d55-0efd-80aa-06ba9e404b7b.png)


このD-SUBコネクタに、以下の配線をおこないます。

* GND (1pin)
* STROBE (12pin)
* DATA (13pin)
* CLK (14pin)
* VCC (15pin)

使うのはこの５本だけ。

裏面（ケーブルの半田付けする方）から見ると、こんな感じ。
_※表面（コンローラーが刺さる方）は、この画像の左右が逆転するので注意してください。_
![pin](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189829/f20917a3-b0f6-bc59-9b5c-e70c2df7eb58.png)

この図に合わせて苦手な半田付け。
そのままだとよく切れたので熱収縮チューブで補強して、ケースにも入れてみる（ケーブル細くてあまり意味ないけど）
<img width="50%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189829/19c91121-b01a-73df-8793-b07fbdef1933.png"><img width="50%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189829/f38d2117-58ec-9c53-d506-55bfb582f3d4.png">


## 配線

M5Stack Core2の以下のポートにジャンパーケーブルを接続します。
※M5Stackで使用する機能に応じて、利用できるポートが変わるので、使いたい内容に合わせて変更ください

今回はこちらを使用。

* 黒のケーブル(1pin)：GND
* 黄のケーブル(15pin)：3.3V
* 橙のケーブル(14pin)：G27
* 赤のケーブル(13pin)：G19
* 焦茶のケーブル(12pin)：G18

![配線](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189829/a9c4b1c9-d2d9-27ed-0c6d-d0da9cc56727.png)
![配線２](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189829/ae053ff4-f34c-d09f-6677-94375f5c1dae.png)

## ソフト

簡単なライブラリがあります。ありがとうございます。

https://github.com/joshmarinacci/nespad-arduino

今回は、上記のサンプル（[NESPad_serial](https://github.com/joshmarinacci/nespad-arduino/blob/master/examples/NESpad_serial/NESpad_serial.pde)）で動作確認を行なっています。

GPIOのポート番号を、配線に合わせて修正
引数は、strobe / clock / data


```c:NESpad_serial.pde
NESpad nintendo = NESpad(18 ,27, 19);
```

buttonsで、各ボタンの状態が取得されます。

```c:NESpad_serial.pde
byte state = nintendo.buttons();
```

ボタンが押されてる場所のbitが立ちます。
詳細はこちら。

```c:NESpad.h
#define NES_A       B00000001
#define NES_B       B00000010
#define NES_SELECT  B00000100
#define NES_START   B00001000
#define NES_UP      B00010000
#define NES_DOWN    B00100000
#define NES_LEFT    B01000000
#define NES_RIGHT   B10000000
```
動かすと、Serialで各bitの状態が出力されます。
※サンプルは、bitが反転されているので、１が未入力、０が入力です。
![出力](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189829/a270e53f-71fd-823c-aade-30e53e30ede8.png)

ちなみに、結果に対してbit演算行うことで、ボタンの情報を取得することができます。

```c
if( state & NES_A)      Serial.println("NES_A");
if( state & NES_B)      Serial.println("NES_B");
if( state & NES_SELECT) Serial.println("NES_SELECT");
if( state & NES_START)  Serial.println("NES_START");
if( state & NES_UP)     Serial.println("NES_UP");
if( state & NES_DOWN)   Serial.println("NES_DOWN");
if( state & NES_LEFT)   Serial.println("NES_LEFT");
if( state & NES_RIGHT)  Serial.println("NES_RIGHT");
```

## まとめ
今回はハドソンのジョイコンでのみ動作確認をしています。

ちなみに、ファミリーマットはボタンの数が8個以上あるので、多分動作しません。
もし他のジョイスティックで動作してたら教えてもらいたいです。