Arduino経由でDendyからPCにジョイスティックを接続する

ダンディで戦車、ニンジャタートル、バトル、ダブルドラゴン、その他数十ものスーパーゲームで何時間も割って過ごした輝かしい時代を覚えている人は多いと思います。 素晴らしい時間でした! ほとんどのゲームは非常に複雑でしたが、失敗の後も失敗しましたが、目標に向かって新たにゲームを開始したため、今日は最後までやり遂げることができました。



私は心と魂を理解したので、私は本当にDendyをプレイしたいと思い、キーボードではなく古き良きジョイスティックでラップトップでプレイしたいと思いました。



以下に、私が遭遇した問題とその解決方法を説明します。



なぜこれが私がプレイしたかったのか、少し説明させてください。 私はまだ接頭辞を持ち、それはうまく動作しますが、カートリッジは数個しか残っていません(残りを友人に配布しました)。 そして、キーボードでダンディゲームをプレイするのは、なんとなく氷ではありません。



Dandyからラップトップにジョイスティックを接続する方法に問題がありました。



少しグーグルで、これは主にLPTポート経由で接続し、既製のドライバーを使用することで解決されることに気付きましたが、ラップトップを持っているので、これは私には合いません。 それから、私はArduino Unoボードを持っていることを思い出し、私は自分のやり方でそれを使用することに決めました。



0.ジョイスティックのピン配列の定義



最初の問題は、ジョイスティックのコネクタが内部にあり、インターネットで見つかったすべてのピン配列の説明が外部コネクタ用であることが判明したことです。





noname dandyの仕様が見つからなかったため、内部ボードを調べて電源とグランドを見つけ、ジョイスティックの5つの接点のどれがそれらに接続しているかを理解し始めました。 私はこれに迅速に対処しました。 それは2つの極端な接触であることが判明しました。





Arduinoに、私はすべてを直接接続しました-電源-5V電源、アース-アース、2、3、4デジタルピンに接続された他の3つの接点。



1.ジョイスティックプロトコルの説明



この情報を見つけるのはそれほど簡単ではないことが判明しました。 いくつかのフォーラムにわずか数投稿。 個人的に、このエントリは私を助けました: code.google.com/p/avrtoys/wiki/joystick 、すなわちこのコード: avrtoys.googlecode.com/svn/trunk/joystick/main.c そして、ここにジャーナルRadioのこのエントリに記載されているメモへのリンクがあります: ftp.radio.ru/pub/arhiv/1996/06-96/46-6-1996.gif 以上のことから、Latchに信号を送信し、Clockに信号を送信するために8回送信する必要があると判断しました。データから値を読み取るたびに、次のジョイスティックボタンに関する情報が含まれます。



2.環境のセットアップ



すべての構成が完了している場合、またはArduino IDEに満足している場合は、3つのポイントに進むことができます。

私はあなたのことは知りませんが、個人的には公式のArduino IDEが私をひどく憂鬱にしているので、お気に入りのIDEの使い方を簡単に説明します。

まず、Arduino IDEのソースをダウンロードして、ファームウェアのコンパイルと更新を担当するコードを見つけました。 少し時間をかけて、そこで使用されるすべてのコマンドを強調表示しました。

#!/bin/bash avr-gcc -c -g -Os -fno-exceptions -ffunction-sections -fdata-sections -mmcu=atmega328p -DF_CPU=16000000UL -I /usr/share/arduino/hardware/arduino/cores/arduino -I /usr/share/arduino/hardware/arduino/variants/standard $filename.cpp -o $filename.o avr-gcc -Os -Wl,--gc-sections -mmcu=atmega328p -o $filename.elf $filename.o libArduino.a -lm avr-objcopy -O ihex -R .eeprom $filename.elf $filename.elf.hex avrdude -V -p m328p -b 115200 -c arduino -P /dev/ttyACM0 -U flash:w:$filename.elf.hex
      
      





上記のコマンドでは、リンク時にライブラリlibArduino.aが使用されます。これは、フォルダーのすべての* .cおよび* .cppファイルをヘッダーでコンパイルし、1つのアーカイブ内のすべてのオブジェクトを収集することによって取得できます。 または、Arduino IDEを起動し、プロジェクトをコンパイルして、ファイル/tmp/build*.tmp/core.aをコピーするだけです。 それは完全に同等です。

これらのコマンドはすべてArduino Unoに関連しています。その他のいくつかのパラメーターは変更する必要があります。



これらのコマンドを使用して、ファームウェアを自動的にコンパイルおよびダウンロードするようにIDEを簡単に構成できます。



3.ファームウェアコードの記述



ここでは、2、3、4ピンのどれがラッチ、クロック、データを担当するかを決定する必要がありました。 私は試行錯誤でこれを決めました。 4がデータであると想定し、Serial.println(digitalRead(4))を実行します。ボタンが押されたときに反応があれば、これがそれです。 残りの2つの連絡先は、ファームウェアが既に書き込まれているときに決定され、すべてが正常に機能する場合は正しいと推測されます-いいえ、場所を入れ替えます。



このコードもavrtoys.googlecode.com/svn/trunk/joystick/main.cに基づいて記述されています

ファームウェアコード
 #include <Arduino.h> const int data = 2; const int latch = 3; const int clock = 4; const int TICK = 2; void init_joystick(int data, int latch, int clock) { pinMode(data, INPUT); pinMode(clock, OUTPUT); pinMode(latch, OUTPUT); digitalWrite(clock, HIGH); } int get_keys_state_joystick(int data, int latch, int clock) { digitalWrite(latch, HIGH); delayMicroseconds(TICK); digitalWrite(latch, LOW); int keys_state = 0; for (int i = 0; i < 8; ++i) { delayMicroseconds(TICK); digitalWrite(clock, LOW); keys_state <<= 1; keys_state += digitalRead(data); delayMicroseconds(TICK); digitalWrite(clock, HIGH); } return keys_state; } void setup() { init_joystick(data, latch, clock); Serial.begin(57600); } void loop() { Serial.write(get_keys_state_joystick(data, latch, clock)); }
      
      







その結果、ジョイスティックの8つのボタンすべてに関する情報を含む1バイトを、それぞれ対応するビットで受け取りました。 次の場所を取得しました:A、B、選択、開始、上、下、左、右。 このバイトがコンピューターに送信された後、「ドライバー」によって受信および処理されます。

2番目のジョイスティックを簡単に接続できることは簡単にわかります。



4.「ドライバー」の作成



ここでは、Arduinoからこのバイトを取り出して、キーボードのキーストロークをエミュレートする必要がありました。 はい、ジョイスティックのクリックは、キーボードのクリックと同様に処理されますが、良くも悪くもなります。

プログラミング言語としてPythonを選びました。 シンプルで効果的で、このタスクにぴったりだったと思います。



ここで発生した唯一の問題は、ジョイスティックの接触の跳ね返りです 。 ボタンの状態を変更した後に発生する時間間隔を導入することで解決しましたが、その間は状態は変更されません。 十分な0.05秒



キーストロークをエミュレートするには、Xautomationバンドルに付属のxteユーティリティを使用しました。 使い方は非常に簡単です。例はxte 'keydown Left'



です。 詳細については、man xteを参照してください。



ドライバーを終了するには、クロス全体が押されたときの状態を使用しました。 番号0xf0はこの状態に対応しています。



ドライバーコード
 #!/usr/bin/python import serial import os import time def bool_to_updown(val): if val: return 'up' else: return 'down' exit_keys = 0xf0 delta_time = 0.05 keys = [['Right', False, 0.0], ['Left', False, 0.0], ['Down', False, 0.0], ['Up', False, 0.0], ['s', False, 0.0], # START ['a', False, 0.0], # SELECT ['x', False, 0.0], # B ['z', False, 0.0]] # A ser = serial.Serial('/dev/ttyACM0', 57600) keys_state = 0 while keys_state != exit_keys: keys_state = ord(ser.read()) for i in range(8): if not bool(keys_state & (1 << i)) != keys[i][1] and time.time() - keys[i][2] > delta_time: os.system("xte 'key{0} {1}'".format(bool_to_updown(keys[i][1]), keys[i][0])) keys[i][1] = not keys[i][1] keys[i][2] = time.time() for i in range(8): os.system("xte 'keyup {0}'".format(keys[i][0])) ser.close() print('Goodbye!')
      
      









5.ほら! プレイ!



それだけです! ダンディエミュレータを構成するためだけに残っています。FCEUXを選択しました。

設定で、ドライバーで指定されているキーを示し、子供時代を思い出します!



おわりに



実際、この状況でArduinoを使用する他の、おそらくより効果的な方法があります。 たとえば、Arduino Leonardoがある場合、キーボードオブジェクトを使用して、キーボードコマンドをコンピューターに直接送信できます。 私が理解しているように、Arduinoを再フラッシュして、ジョイスティック/キーボード/マウスのように表示し、コマンドを直接送信することもできます。 これがチュートリアルです: http : //mitchtech.net/arduino-usb-hid-keyboard/ 。 しかし、私の方法は私に完全に適しており、結果に満足しています。



好むと好まざるとにかかわらず、Arduinoはそのような実験に最適なプラットフォームです。

現在、これらすべてを個別のデバイスとして収集するだけです。



さて、最終ビデオ:




All Articles