SegaMegaDriveゲームパッドとしてのArduino Leonardo-> USBアダプター

まえがき



最近私はSMDから2つの古い忘れられた古いゲームパッドを発見しました。コンソール自体は長い間失われ、ゲームパッドは常にほこりを集めていましたが、彼らは動作しており、「ライブ」デバイスを何とかして手を上げません。 私はそれらをコンピューターに接続することにしましたが、少なくともいくつかは使用しますが、Arduino Leonardoをアダプターとして使用します。



SMDゲームパッドプロトコル



画像

最も単純な場合、データの取得は次のようになります。



PIN 方向 選択=低 選択=高
1 アップ アップ
2 ダウン ダウン
3 高い
4 高い
5 アウト 5v 5v
6 A B
7 アウト 選択してください 選択してください
8 アウト GND GND
9 開始する C


インジケータは、選択ピンの変更によって異なります。

ご覧のとおり、ここには4つのキーがありません。

それらの取得は少し複雑です:1.1から1.2ミリ秒の間隔でSelect LOW-> HIGHの2つの変更を行う必要があります。その後、ピン1,2,3,4はLOWになり、Select LOW-> HIGHの別の変更でZ値が表示されます。 Y、X、モード、それぞれ。



選択してください ピン1 ピン2 ピン3 ピン4
低い アップ ダウン 低い 低い
高い アップ ダウン
低い アップ ダウン 低い 低い
高い アップ ダウン
低い 低い 低い 低い 低い
高い Z Y X モード
低い 高い 高い 高い 高い
高い アップ ダウン
低い アップ ダウン 低い 低い




図書館



便宜上、ゲームパッドを操作するためのシンプルなライブラリを作成しました。



SMDjoystick.h
#ifndef _SMDJOYSTICK_H_ #define _SMDJOYSTICK_H_ #include <Arduino.h> /** SegaMegaDrive gamepad arduino library by AsGreyWolf **/ enum{ SMD_A=0, SMD_B, SMD_C, SMD_EMPTY_1, SMD_X, SMD_Y, SMD_Z, SMD_MODE, SMD_EMPTY_2, SMD_START, SMD_EMPTY_3, SMD_EMPTY_4, SMD_UP, SMD_DOWN, SMD_LEFT, SMD_RIGHT, SMD_MAX_KEYS }; class SMDjoystick{ public: SMDjoystick(int upPin,int downPin,int leftPin,int rightPin,int aPin,int selectPin,int startPin); bool read(int key); uint16_t read(); private: int up; int down; int left; int right; int a; int select; int start; }; #endif
      
      







SMDjoystick.cpp
 #include "SMDjoystick.h" SMDjoystick::SMDjoystick(int upPin,int downPin,int leftPin,int rightPin,int aPin,int selectPin,int startPin):up(upPin),down(downPin),left(leftPin),right(rightPin),a(aPin),select(selectPin),start(startPin){ pinMode(up,INPUT); pinMode(down,INPUT); pinMode(left,INPUT); pinMode(right,INPUT); pinMode(a,INPUT); pinMode(start,INPUT); pinMode(select,OUTPUT); } uint16_t SMDjoystick::read(){ uint16_t data=0; digitalWrite(select,LOW); data+=!digitalRead(a)<<SMD_A; data+=!digitalRead(start)<<SMD_START; data+=!digitalRead(up)<<SMD_UP; data+=!digitalRead(down)<<SMD_DOWN; delayMicroseconds(1200); digitalWrite(select,HIGH); data+=!digitalRead(left)<<SMD_LEFT; data+=!digitalRead(right)<<SMD_RIGHT; data+=!digitalRead(a)<<SMD_B; data+=!digitalRead(start)<<SMD_C; digitalWrite(select,LOW); delayMicroseconds(1200); digitalWrite(select,HIGH); digitalWrite(select,LOW); digitalWrite(select,HIGH); data+=!digitalRead(up)<<SMD_Z; data+=!digitalRead(down)<<SMD_Y; data+=!digitalRead(left)<<SMD_X; data+=!digitalRead(right)<<SMD_MODE; digitalWrite(select,LOW); digitalWrite(select,HIGH); return data; } bool SMDjoystick::read(int key){ bool val=false; switch(key){ case SMD_UP: val=!digitalRead(up); break; case SMD_DOWN: val=!digitalRead(down); break; case SMD_LEFT: digitalWrite(select,HIGH); val=!digitalRead(left); break; case SMD_RIGHT: digitalWrite(select,HIGH); val=!digitalRead(right); break; case SMD_START: digitalWrite(select,LOW); val=!digitalRead(start); break; case SMD_A: digitalWrite(select,LOW); val=!digitalRead(a); break; case SMD_B: digitalWrite(select,HIGH); val=!digitalRead(a); break; case SMD_C: digitalWrite(select,HIGH); val=!digitalRead(start); break; case SMD_X: digitalWrite(select,LOW); delayMicroseconds(1200); digitalWrite(select,HIGH); digitalWrite(select,LOW); delayMicroseconds(1200); digitalWrite(select,HIGH); digitalWrite(select,LOW); digitalWrite(select,HIGH); val=!digitalRead(left); digitalWrite(select,LOW); digitalWrite(select,HIGH); break; case SMD_Y: digitalWrite(select,LOW); delayMicroseconds(1200); digitalWrite(select,HIGH); digitalWrite(select,LOW); delayMicroseconds(1200); digitalWrite(select,HIGH); digitalWrite(select,LOW); digitalWrite(select,HIGH); val=!digitalRead(down); digitalWrite(select,LOW); digitalWrite(select,HIGH); break; case SMD_Z: digitalWrite(select,LOW); delayMicroseconds(1200); digitalWrite(select,HIGH); digitalWrite(select,LOW); delayMicroseconds(1200); digitalWrite(select,HIGH); digitalWrite(select,LOW); digitalWrite(select,HIGH); val=!digitalRead(up); digitalWrite(select,LOW); digitalWrite(select,HIGH); break; case SMD_MODE: digitalWrite(select,LOW); delayMicroseconds(1200); digitalWrite(select,HIGH); digitalWrite(select,LOW); delayMicroseconds(1200); digitalWrite(select,HIGH); digitalWrite(select,LOW); digitalWrite(select,HIGH); val=!digitalRead(right); digitalWrite(select,LOW); digitalWrite(select,HIGH); break; } return val; }
      
      







SMDjoystick.read(SMD_id)を使用すると、1つのボタンの値を読み取ることができます。

SMDjoystick.read()は、JoyStateに適したすべてのボタンの値とともにuint16_tを返します。





Leonardoに接続します。



ゲームパッドピン Arduinoピン
1 2
2 3
3 4
4 5
5 5v
6 6
7 7
8 GND
9 8




キーボードエミュレーションの例
 #include <SMDjoystick.h> SMDjoystick j(2,3,4,5,6,7,8); uint16_t data=0; void setup() { Keyboard.begin(); } uint16_t lastdata; char keys[]={ 'f', 'r', ' ', 0, KEY_LEFT_SHIFT , KEY_TAB , KEY_BACKSPACE, KEY_ESC, 0, KEY_RETURN, 0, 0, 'w', 's', 'a', 'd' }; void loop() { data=j.read(); for(int i=0;i<SMD_MAX_KEYS;i++){ if(keys[i]==0) continue; bool c=(data>>i)&1; if(c!=((lastdata>>i)&1)){ if(c)Keyboard.press(keys[i]); else Keyboard.release(keys[i]); } } lastdata=data; delay(10); }
      
      







ジョイスティックUSBキーエミュレーションの例
 #include <SMDjoystick.h> SMDjoystick j(2,3,4,5,6,7,8); JoyState_t s; uint16_t data; void setup() { s.xAxis=128; s.yAxis=128; s.zAxis=128; s.xRotAxis=128; s.yRotAxis=128; s.zRotAxis=128; s.throttle=128; s.rudder=128; s.hatSw1=0; s.hatSw2=0; } void loop() { data=j.read(); s.buttons=data; Joystick.setState(&s); }
      
      







以上で、将giのゲームパッドを他のUSBゲームパッドと同様に使用できます。



Githubリポジトリ



ソース:

www.hardwarebook.info/Mega_Drive_Joystick

applause.elfmimi.jp/md6bpad-e.html



UPD:

キーボードのキーストロークのエミュレーションの例を追加しました。

タイマーを削除しました

リポジトリが追加されました



All Articles