まえがき
最近私は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:
キーボードのキーストロークのエミュレーションの例を追加しました。
タイマーを削除しました
リポジトリが追加されました