SyntaxHighlighter

2015年5月30日土曜日

Arduino Leonardで、JRプロポのトレーナー信号をUSBジョイスティックに変換するアダプタ作った。(ついでにFMS Interface互換の出力付き)

Arduino Leonardで、JRプロポのトレーナー信号をUSBジョイスティックに変換するアダプタ作った。

(ついでにFMS Interface互換の出力付き)


作り方を以下に紹介しますが。注意事項。
警告:ここでは、プロポの本来の使いからから逸脱したものを紹介しています。
    一応安全に気を付け、問題のないように紹介を行っているつもりですが、
    結果として、プロポの破損・発煙・炎上・データ破壊・ノーコンなどが発生する恐れがあります。
    また、ここで作成した回路をPCPCなどに差し込んだ際、
    PCなどが破損・発煙・炎上・データ破壊し、最悪の場合、身体の損傷や火災などを招く危険性があります。
    これらリスクを理解もしくは同意のどちらか、もしくはその両方ができない場合は、行わないでください。
    筆者は、生じた事故・損害・損傷・データ等に対する賠償・謝罪等の責任を一切負いません。

0. Arduino Leonardを購入します。(いわゆる32U4系ボードやAVRでも可)

1. 以下を参考に、Arduino LeonardでUSBジョイスティック扱いの操作ができるようにします。

 Arduino LeonardをUSBジョイスティックにする
 http://gpsnmeajp.blogspot.jp/2015/05/arduino-leonardusb.html


2.以下の回路を組み立てます。(ブレッドボードで十分だが、組み込むなら小さめに)

 ただし、この回路はJRプロポの出力用なので、他のものを使う場合は
 別途回路を組み替えてください。(100k抵抗をGNDに落とす程度)

 コンデンサはなくても動きますし、最悪トランジスタ無しで直結した上で
 プログラム上の論理を反転すれば動く気がしますが、
 JRプロポは最低1万円位すると思うので、万が一のことを考え、おすすめしません。

 100kの抵抗は、200kでも多分動きます。
 トランジスタはNPNであれば何でも良いと思います。
 私は1815を使ってますが、2001でも問題はないかと。
 コンデンサも、大きすぎたり小さすぎたりしなければ問題ないと思います。
 ブレッドボードで組むとこんな感じ。
 

3.Arduino Leonardに繋ぎます。

4.以下のプログラムを書き込みます。
JoyState_t joySt;

void setup()
{
  Serial.begin(19200);
  pinMode(7,INPUT_PULLUP);
  pinMode(13,OUTPUT);

  joySt.xAxis = 0;joySt.yAxis = 0;joySt.zAxis = 0;joySt.xRotAxis = 0;joySt.yRotAxis = 0;
  joySt.zRotAxis = 0;joySt.throttle = 0;joySt.rudder = 0;joySt.hatSw1 = 0;
  joySt.hatSw2 = 0;joySt.buttons = 0;
}

void loop()
{
  static int ch=0;
  unsigned long cnt = pulseIn(7,LOW,3000);
  if(cnt == 0){
    interrupts(); //USB通信許可
    Joystick.setState(&joySt);
    delay(2); //通信時間確保

    ch=0;
    Serial.write((byte)0xFF);
    
    while(digitalRead(7) == LOW); //次のリーダーパルスまで待つ
    noInterrupts(); //通信禁止
  }else{
    switch(ch)
    {
      case 0:joySt.throttle = map(cnt,700,1500,0,255);break;
      case 1:joySt.xAxis = map(cnt,700,1500,0,255);break;
      case 2:joySt.yAxis = map(cnt,700,1500,0,255);break;
      case 3:joySt.rudder = map(cnt,700,1500,0,255);break;
      case 4:joySt.xRotAxis = map(cnt,700,1500,0,255);break;
      case 5:joySt.zAxis = map(cnt,700,1500,0,255); break;
    }    
    
    ch++;
    Serial.write((byte)map(cnt,700,1500,0,254));
  }
}

5. USBポートに繋げば完成です。
 ジョイスティックとしても動作しますし、FMSのシリアルインターフェースとしても動作するので
 どちらでも構いません。

Arduino Unoしか持ってない、USBジョイスティックとしての機能はいらないから、
FMSで動けばいい、という方はこちら。
少々バタつきはあるかもしれませんが、動くと思います。
void setup()
{
  Serial.begin(19200);
  pinMode(7,INPUT_PULLUP);
}

void loop()
{
  static int ch=0;
  unsigned long cnt = pulseIn(7,LOW,3000);
  if(cnt == 0){
    ch=0;
    Serial.write((byte)0xFF);
    
    while(digitalRead(7) == LOW); //次のリーダーパルスまで待つ
  }else{
    ch++;
    Serial.write((byte)map(cnt,700,1500,0,254));
  }
}


ついでに、パルス幅を観測したい人向け。ターミナルで開けば数字で出ます。
void setup()
{
  Serial.begin(19200);
  pinMode(7,INPUT_PULLUP);
}

void loop()
{
  static int ch=0;
  unsigned long cnt = pulseIn(7,LOW,3000);
  if(cnt == 0){
    ch=0;
    Serial.write((byte)0xFF);
    
    while(digitalRead(7) == LOW); //次のリーダーパルスまで待つ
  }else{
    ch++;
    Serial.print(ch);
    Serial.print(':');
    Serial.println(cnt);
  }
}

Q.なんでLeonard限定なの?
A.USB通信機能を使っているからです。
  USB通信機能がないと、まずジョイスティックとして認識させられないというのがひとつ。
  もう一つは、超高速な仮想シリアル通信が使えるからです。

Q.ジョイスティックが6chしか反応しないんだけど?
A.私の持ってるプロポが6chだからです。ご自分でプログラムを改造すればすぐ解決します。
 多分1,2行程度。ただし、ジョイスティックの入力の数には限界があるので、
 8chが限界でしょう。

0 件のコメント:

コメントを投稿