スーパーファミコン コントローラーの無線化プロジェクト:コントローラー状態の読み取り
スーパーファミコンのコントローラーは、本体からP/Sのパルスと、CLKの供給を受けて、そのタイミング事に、ボタンの押している状態を返す。
無線化する際に、本体側のP/Sなりを子機にあたるコントローラー側に無線で飛ばしてやる事も考えられるが、無線の遅延を考えるとあまり得策ではないだろうと考えた。
基本ボタンの状態だけを本体側は受信して、本体クロックにあわせて、本体にDATの信号を返すで動かす。完全に非同期。1秒に60回、16.6msec、本来の入力状態から遅延する事が考えられるが、m秒を争うゲームをする訳でもないので。
コントローラー(ゲームパッド)に向かって、本体からではなく、マイコンで生成したP/SとCLKの偽物データを送りつけて状態を読みとることをテストとして行う。
とは言え、16.6ms間隔でデータを生成したいので、これだけはTimerを使って時間をできるだけ正確にとることにする。
ESP8266TimerInterruptと先人の方々らライブラリーを用意してくれているのありがたく使う。#include "ESP8266TimerInterrupt.h"
#define PS_PIN 4 //D1
#define DAT_PIN 14 //D5
#define CLK_PIN 5 //D2
ESP8266Timer ITimer;
void timertask() {
int status=0b0;
digitalWrite(PS_PIN, HIGH);
delayMicroseconds(12);
digitalWrite(PS_PIN, LOW);
delayMicroseconds(6);
for (int i=0;i<16;i++){
digitalWrite(CLK_PIN, LOW);
if(digitalRead(DAT_PIN)==LOW){
bitWrite(status,15-i,0);
}else{
bitWrite(status,15-i,1);
};
delayMicroseconds(6);
digitalWrite(CLK_PIN, HIGH);
delayMicroseconds(6);
}
Serial.println(status, BIN);
}
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
pinMode(PS_PIN, OUTPUT);
pinMode(CLK_PIN, OUTPUT);
pinMode(DAT_PIN, INPUT);
digitalWrite(PS_PIN, LOW); //normal state of PS pin
digitalWrite(CLK_PIN, HIGH); //nomal state of CLK pin
ITimer.attachInterruptInterval(16666, timertask);
}
void loop() {
}
回路の方は、
電源は現時点ではUSBからの給電。5V系は、ESPのVinから供給。
コントローラー側の5本については
茶色:GND(マイコンのGND)
赤色:DAT(レベルコンバーターを介してマイコンのGPIO15へ)
橙色:P/S(レベルコンバーターを介してマイコンのGPIO4へ)
黄色:CLK(レベルコンバーターを介してマイコンのGPIO5へ)
白色:+5V
それぞれをロジアナで観測してみる
でPSを12usecだけHIGHにしにいくが(真ん中のオレンジのライン)、実際は13.75usとやや長い。これきっちり12usecに調整してもよいが、状態を読めればよいので、このまま。
6usecあけてクロックが立ち下がり、それを16回繰り返す。これも本来12usec周期だが、16.125usecと長い。これも調整してもよいがこのまま。
上の例の場合は、”上”キーを押してキャプチャーした場合。しっかりコントローラー内のICはそのタイミングでLOWレベルにしている。
各状態をLOWになるタイミングで読んで16ビットの整数として記憶する。
シリアルポートに16ビットの整数をBIN形式で出力しているので、ファミコンのコントローラーのボタンを各種押すと状態が遷移しているのが確認できる。下の場合は、上キーを押しているので、そのタイミングだけゼロとちゃんと読んでくる。
次は、この2バイトの整数を無線経由でもう一つのESPに送り込む。16.6msec周期なので、その間に、2バイトなら送り込めるはず・・・
あと、TP4021BPのようなパラシリ変換のICを使っているらしいが、データシート見ると電源電圧が3Vから18Vと記載されているので、今回は5VをICに投入し、レベルコンバーターを利用しているが、全部3.3V系でも動きそう・・・なのでそのチェックはいずれやってみたいと思う。
コメント
コメントを投稿