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

この3つの動きを粗いと微細に切り替えてコントロールします。
今回の実際のレイアウトと配線図です。

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

ロータリーエンコーダ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
5〜12行目が繋ぐピンの位置です。
CoarseEnc_A = 10,
CoarseEnc_B = 9,
FineEnc_A = 7,
FineEnc_B = 8,
ModeSwitchPin = 20,
HdgModeLED = 15,
Nav1OBSLED = 13,
ElevTrimLED = 14