ESP32でPSコントローラーを読むには
ESP32-devkitcというマイコン開発ボードでプレステのコントローラをファミコンで使うアダプタを作って遊んでいた。
弾を撃つと不意にポーズがかかったりして、出来はいまいちなんだが、開発メモを書いておく。
利用できるライブラリ
ぐぐるといくつか出てくる。
これはPSコントローラを認識できなかった。
そのまま使うと動かない。
ライブラリのソースコードGPSX.cの、GPIOピン番号を適切に変更する。
#define DAT_PIN 27 // CTL1 Data #define CMD_PIN 13 // CTL2 Command #define AT1_PIN 26 // CTL6 Attention (PAD1) #define CLK_PIN 14 // CTL7 Clock
ここでは左の番号がESP32のGPIO、右のCTLxがPSコントローラのピン番号。
どのGPIOピンでも動くが、17〜22ピンは使ってはいけない。(内部で使っている)
また、12ピンはDATピンにはできない。DATにはプルアップ(PSピンとESP32ピンの間に10kΩの抵抗を入れ、Vcc(5V)につなぐ)が必要だが、ESP32は12ピンをプルアップするとBASICが起動してしまう!
digitalWriteを開く
digitalWriteは遅いのでポートレジスタを直接叩いてやる高速化メソッドがある。
これをESP32でやる場合、単純にポートレジスタのアドレスにand,orしてもうまくいかなかった。
fにはHIGH/LOWにあたる1/0が入るとして、
// digitalWrite(PIN_OUT, f); // 相当のコード if (f) { GPIO.out_w1ts |= ((uint32_t)1<<PIN_OUT); } else { GPIO.out_w1tc |= ((uint32_t)1<<PIN_OUT); }
IO32〜39ピンなら以下のようになる。
// digitalWrite(pin, f); // 相当のコード(PIN=32..39) if (f) { GPIO.out1_w1ts.val = ((uint32_t)1<<(pin - 32)); } else { GPIO.out1_w1tc.val = ((uint32_t)1<<(pin - 32)); }
esp32-hal-gpio.cの_digitalWriteに全部書いてある。
ファミコンコントローラ信号
GitHub - GOROman/NESBot-mini
ファミコンのコントローラー信号をソフトウェアで作るサンプルを見たのでESP32を使ってみたが、よくよく見るとここではVSyncのタイミングを得るためファミコンのCPUからNMIを取り出している。
PS,CLKピンの割り込みだけでもそこそこ動いたが、先に述べたようにゲームにならない。
結局本物のコントローラーと同じ4021のロジックで信号作るのだったら、PSコンの読み取りはArduinoで済んじゃう。
とするとESP32を用意した意味あんまりなかったが…まあここまで遊べたので良い。
また何かの役に立つ日も来るかも。