X-Plane コクピットの自作に挑戦!
X-Plane 回転動作を粗いと微細で設定 & 3つのモードの切り替え
2つのロータリーエンコーダを使用して、回転の動きを粗いと微細で切り替える。さらに、針路バグ、エレベータトリムそしてNavのOBSを制御。

X-Plane 10.31r3
この3つの動きを粗いと微細に切り替えてコントロールします。



今回の実際のレイアウトと配線図です。


iPhoto-1
ロータリーエンコーダのスイッチで、上の赤色LEDを切り替えて、どれを選択したか分かるようにします。
下の2つのボタンは1つだけを使用しています。


粗い微動3モード切り替え図面2.ai @ 200% (CMYK_プレビュー)

ロータリーエンコーダ2つ、プッシュボタン1つ、リード3つの構成。

針路バグ、エレベータトリムとNavOBS&粗い、微細動作のスケッチ
これは、スケッチを公開しているこのサイトから頂きました。
ピンの位置を少し変更しています。これでTeensy 2.0は動作しました。
X-Plane_Coarse_Fine.ino

#include <Encoder.h>
#include <Bounce.h>
 
enum pins {
  CoarseEnc_A = 10,
  CoarseEnc_B = 9,
  FineEnc_A = 7, // wired this one in backwards. Instead of playing
  FineEnc_B = 8,  // with the wires, let's just swap the order here!
  ModeSwitchPin = 20,
  HdgModeLED = 15,
  Nav1OBSLED = 13,
  ElevTrimLED = 14
};
 
// Encoder things
Encoder coarseEnc(CoarseEnc_A, CoarseEnc_B);
short coarseEncPrev = 0;
 
Encoder fineEnc(FineEnc_A, FineEnc_B);
short fineEncPrev = 0;
 
const int CoarseToFineRatio = 20;
 
// Mode things
Bounce modeSwitch = Bounce (ModeSwitchPin, 5);
enum Modes {
  Mode_Heading, // automatically = 0
  Mode_Nav1OBS, // let's just add this in here
  Mode_ElevTrim, // automatically now equal to 2 since we put Nav1OBS in front
  Mode_Count // automagically = 3, and we have 3 modes!
};
int mode = 0;
 
// Heading mode things
FlightSimFloat headingBug;
float headingBugScalar = 0.25;
 
// Nav1 OBS things
FlightSimFloat nav1OBS;
float nav1OBSScalar = 0.25;
 
// Elev trim mode things
FlightSimFloat elevTrim;
FlightSimFloat elevMin;
FlightSimFloat elevMax;
float elevTrimScalar = 0.005;
 
void setup() {
  pinMode(ModeSwitchPin, INPUT_PULLUP);
  pinMode(HdgModeLED, OUTPUT);
  pinMode(Nav1OBSLED, OUTPUT);
  pinMode(ElevTrimLED, OUTPUT);
 
  headingBug = XPlaneRef("sim/cockpit2/autopilot/heading_dial_deg_mag_pilot");
 
  nav1OBS = XPlaneRef("sim/cockpit2/radios/actuators/nav1_obs_deg_mag_pilot");
 
  elevTrim = XPlaneRef("sim/cockpit2/controls/elevator_trim");
  elevMin = XPlaneRef("sim/aircraft/controls/acf_min_trim_elev");
  elevMax = XPlaneRef("sim/aircraft/controls/acf_max_trim_elev");
}
 
void loop() {
  FlightSim.update();
  modeSwitch.update();
 
  // change mode when switch pressed
  if(modeSwitch.fallingEdge()) {
    ++mode;
    if(mode >= Mode_Count)
      mode = 0;
  }
 
  // light status LEDs
  digitalWrite(HdgModeLED, (mode == Mode_Heading));
  digitalWrite(Nav1OBSLED, (mode == Mode_Nav1OBS));
  digitalWrite(ElevTrimLED, (mode == Mode_ElevTrim));
 
  // find encoder movement
  short coarseEncDiff = (coarseEnc.read() - coarseEncPrev) / 4;
  short fineEncDiff = (fineEnc.read() - fineEncPrev) / 4;
 
  // reset encoders after they move
  if (coarseEncDiff) {
    coarseEncPrev = 0;
    coarseEnc.write(0);
  }
  if (fineEncDiff) {
    fineEncPrev = 0;
    fineEnc.write(0);
  }
 
  // combine coarseEncDiff with fineEncDiff
  int encDiff = (CoarseToFineRatio * coarseEncDiff) + fineEncDiff;
 
  if (encDiff) {
    if (mode == Mode_Heading) {
      float tmp = headingBug;
      tmp += encDiff * headingBugScalar;
      while (tmp < 0.0) tmp += 360.0;
      while (tmp >= 360.0) tmp -= 360.0;
      headingBug = tmp;
    }
 
    if (mode == Mode_Nav1OBS) {
      float tmp = nav1OBS;
      tmp += encDiff * nav1OBSScalar;
      while (tmp < 0.0) tmp += 360.0;
      while (tmp >= 360.0) tmp -= 360.0;
      nav1OBS = tmp;
    }
 
    if (mode == Mode_ElevTrim) {
      float tmp = elevTrim;
      tmp += encDiff * elevTrimScalar;
      while (tmp < -elevMin) tmp = -elevMin;
      while (tmp > elevMax) tmp = elevMax;
      elevTrim = tmp;
    }
  } //if encDiff
} // loop
512行目が繋ぐピンの位置です。

CoarseEnc_A = 10,
CoarseEnc_B = 9,
FineEnc_A = 7,
FineEnc_B = 8,
ModeSwitchPin = 20,
HdgModeLED = 15,
Nav1OBSLED = 13,
ElevTrimLED = 14

comments powered by Disqus
Contents