7セグメント


この7セグメントは回路図も難関ですが、スケッチも更に大変です。英語のあらゆるサイトを見て回って問題を解決していきました。
現在は、全てパーフェクトに動作しています。
難しいものに挑戦するおもしろさも体験することが出来ます。なんといっても実施にX-Planeを操縦しながら数値が自在に回って表示されるという快感はたまりません。
7セグメントで表示する数値はX-Planeから取得しています。

ここではMAX7219を使用しています。これは多少値段が高いのですがピン数を減らすことができますし8桁まで表示することが出来ます。もし7セグでやるのでした必需品だと思います。
3桁の7セグを使用して、VS と ALT は3桁を2つずつ使用して6桁にしています。不要な桁がでますが、その分は表示しないように設定しました。
B747-400 7セグメント:SPD(Teensyのピンを3つ使用、どれでも可)
X-Plane画面のSELスイッチでノットとマッハを切り替えると、エンコーダもそれに合わせて数値を変化させることができます。
#include <LedControl.h>
const int lc2_DIN_Pin = 31; //7セグ、teensyピン位置
const int lc2_CLK_Pin = 32;
const int lc2_LOAD_Pin = 33;
//入力:DINピン、CLK端子、LOAD端子、チップ数(MAX7219の数)
LedControl lc2 = LedControl(lc2_DIN_Pin, lc2_CLK_Pin, lc2_LOAD_Pin, 1);
FlightSimInteger AirSpeed_KnotMach_change; //ノットとマッハの切り替え用
FlightSimInteger AirSpeed_knot; //7セグ用
FlightSimFloat AirSpeed_mach_float; //小数点以下のデータを取得、7セグ用
float mach_FloatValue; //小数点の数値を一時格納
int mach_IntValue; //小数点を整数に変換した数値を入れる
void setup() {
lc2.shutdown(0, false); // ディスプレイをオンに(0が最初のチップ)
lc2.setIntensity(0, 15); // 15 = brightest
lc2.clearDisplay(0);// 画面クリア(これ外しても同じ動作、意味不明)
//mydisplay.setScanLimit(0, 3); // 表示する桁数の指定(最初は行数、2番めが桁数、0が1桁、1が2桁…)
pinMode(lc2_DIN_Pin, OUTPUT);
pinMode(lc2_CLK_Pin, OUTPUT);
pinMode(lc2_LOAD_Pin, OUTPUT);
AirSpeed_KnotMach_change = XPlaneRef("sim/cockpit/autopilot/airspeed_is_mach");
AirSpeed_knot = XPlaneRef("sim/cockpit/autopilot/airspeed"); //7セグ用
AirSpeed_mach_float = XPlaneRef("sim/cockpit/autopilot/airspeed"); //X-Planeから浮動小数点の数値を取得
}
// setup end
void loop() {
FlightSim.update();
if (AirSpeed_KnotMach_change == 0) {
int spd_act_keta1 = AirSpeed_knot % 10; //例えば123の数字の場合、123÷10=12.3で小数点以下の3が1桁の数字として表示
int spd_act_keta2 = AirSpeed_knot / 10 % 10 ; //例えば123の数字の場合、、÷10=12.3、さらに10で割って、1.23で小数点以下の2が表示
int spd_act_keta3 = AirSpeed_knot / 100; //例えば123の数字の場合、123÷100=1.23で1の整数が3桁目の数字として表示
lc2.setDigit(0, 0, spd_act_keta1, false); //1桁目の値を表示
lc2.setDigit(0, 1, spd_act_keta2, false); //2桁目の値を表示
lc2.setDigit(0, 2, spd_act_keta3, false); //3桁目の値を表示
}
if (AirSpeed_KnotMach_change == 1) {
//剰余の場合は浮動小数点が使えないので
float mach_FloatValue = AirSpeed_mach_float *100; //所得した小数点を整数の位置にもっていく(0.12を12.00)
mach_IntValue = (int) mach_FloatValue; //12.00にした分を完全な整数に変換(12にする)
int alt_act_keta1 = mach_IntValue % 10; //例えば123の数字の場合、123÷10=12.3で小数点以下の3が1桁の数字として表示
int alt_act_keta2 = mach_IntValue / 10 % 10 ; //例えば123の数字の場合、、÷10=12.3、さらに10で割って、1.23で小数点以下の2が表示
lc2.setDigit(0, 0, alt_act_keta1, false); //1桁目の値を表示
lc2.setDigit(0, 1, alt_act_keta2, false); //2桁目の値を表示
lc2.setDigit(0, 2, 0, true); //3桁目の値を表示
}
}
//loop end
B747-400 7セグメント:HDG(Teensyのピンを3つ使用、どれでも可)
#include <LedControl.h>
const int lc3_DIN_Pin = 34; //7セグ、teensyピン位置
const int lc3_CLK_Pin = 35;
const int lc3_LOAD_Pin = 36;
//入力:DINピン、CLK端子、LOAD端子、チップ数(MAX7219の数)
LedControl lc3 = LedControl(lc3_DIN_Pin, lc3_CLK_Pin, lc3_LOAD_Pin, 1);
const int HDGEnc_R_Pin = 9;
const int HDGEnc_L_Pin = 10;
short HdgEncPrev = 0;
FlightSimInteger headingBugLed; //7セグ用
void setup() {
lc3.shutdown(0, false); // ディスプレイをオンに(0が最初のチップ)
lc3.setIntensity(0, 15); // 15 = brightest
//mydisplay.setScanLimit(0, 3); // 表示する桁数の指定(最初は行数、2番めが桁数、0が1桁、1が2桁…)
pinMode(lc3_DIN_Pin, OUTPUT);
pinMode(lc3_CLK_Pin, OUTPUT);
pinMode(lc3_LOAD_Pin, OUTPUT);
pinMode(HDGEnc_R_Pin, INPUT_PULLUP);
pinMode(HDGEnc_L_Pin, INPUT_PULLUP);
headingBugLed = XPlaneRef("sim/cockpit/autopilot/heading_mag");
headingBugLed.onChange(update_hdg_act_lcd);
}
void loop() {
FlightSim.update();
}
void update_hdg_act_lcd(long value) { //value これで高度の数字を読み込む
int hdg_act_keta1 = value % 10; //例えば123の数字の場合、123÷10=12.3で小数点以下の3が1桁の数字として表示
int hdg_act_keta2 = value / 10 % 10 ; //例えば123の数字の場合、、÷10=12.3、さらに10で割って、1.23で小数点以下の2が表示
int hdg_act_keta3 = value / 100; //例えば123の数字の場合、123÷100=1.23で1の整数が3桁目の数字として表示
lc3.setDigit(0, 0, hdg_act_keta1, false); //1桁目の値を表示
lc3.setDigit(0, 1, hdg_act_keta2, false); //2桁目の値を表示
lc3.setDigit(0, 2, hdg_act_keta3, false); //3桁目の値を表示
}
B747-400 7セグメント:V/S(Teensyのピンを3つ使用、どれでも可)
#include <LedControl.h>
const int lc4_DIN_Pin = 37; //7セグ、teensyピン位置
const int lc4_CLK_Pin = 38;
const int lc4_LOAD_Pin = 39;
//入力:DINピン、CLK端子、LOAD端子、チップ数(MAX7219の数)
LedControl lc4 = LedControl(lc4_DIN_Pin, lc4_CLK_Pin, lc4_LOAD_Pin, 1);
FlightSimInteger VSpeedLed;
FlightSimInteger VsFpsReferenceSwLED; //7セグとは関係ないが関連するのでここでは必要
void setup() {
lc4.shutdown(0, false); // ディスプレイをオンに(0が最初のチップ)
//lc3.setScanLimit(0, 3); // 表示する桁数の指定(最初は行数、2番めが桁数、0が1桁、1が2桁…)
pinMode(lc4_DIN_Pin, OUTPUT);
pinMode(lc4_CLK_Pin, OUTPUT);
pinMode(lc4_LOAD_Pin, OUTPUT);
VSpeedLed = XPlaneRef("sim/cockpit/autopilot/vertical_velocity"); //これを設定する意味が不明だが、これにより7セグがうまく動作する
VSpeedLed.onChange(update_vs_act_lcd); // X-Planeが更新されたらLCDを更新する(上と3つセットになる)
}
void loop() {
FlightSim.update();
}
void update_vs_act_lcd(long value) { //value これで高度の数字を読み込む
//プラスの値の処理
int vs_act_keta1 = value % 10; //例えば123の数字の場合、123÷10=12.3で小数点以下の3が1桁の数字として表示
int vs_act_keta2 = value / 10 % 10 ; //例えば123の数字の場合、、÷10=12.3、さらに10で割って、1.23で小数点以下の2が表示
int vs_act_keta3 = value / 100 % 10; //例えば123の数字の場合、123÷100=1.23で1の整数が3桁目の数字として表示
int vs_act_keta4 = value / 1000 % 10;
//マイナスの値の処理
int vs_act_ketaMinus1 = - value % 10; //例えば123の数字の場合、123÷10=12.3で小数点以下の3が1桁の数字として表示
int vs_act_ketaMinus2 = - value / 10 % 10 ; //例えば123の数字の場合、、÷10=12.3、さらに10で割って、1.23で小数点以下の2が表示
int vs_act_ketaMinus3 = - value / 100 % 10; //例えば123の数字の場合、123÷100=1.23で1の整数が3桁目の数字として表示
int vs_act_ketaMinus4 = - value / 1000 % 10;
//プラスの値の処理
lc4.setDigit(0, 0, vs_act_keta1, false); //1桁目の値を表示
lc4.setDigit(0, 1, vs_act_keta2, false); //2桁目の値を表示
lc4.setDigit(0, 2, vs_act_keta3, false); //3桁目の値を表示
lc4.setDigit(0, 3, vs_act_keta4, false); //4桁目の値を表示
//マイナスの値の処理
lc4.setDigit(0, 0, vs_act_ketaMinus1, false); //-の1桁目の値を表示
lc4.setDigit(0, 1, vs_act_ketaMinus2, false); //-の2桁目の値を表示
lc4.setDigit(0, 2, vs_act_ketaMinus3, false); //-の3桁目の値を表示
lc4.setDigit(0, 3, vs_act_ketaMinus4, false); //-の4桁目の値を表示
int polomini=-1; //-1の宣言
int polomax=0; //0の宣言
//表示する桁数を変更する設定
if(value == 0 ){ //もし、0と同じなら以下を実行
lc4.setScanLimit(0, 3); // 4桁表示にする。(最初は行数、2番めが桁数、0が1桁、1が2桁…)
//lc4.setIntensity(0, 2); // 15 = brightest 明るさを桁数に合わせて個別に指定
}
else if(value >= 1 && value <= 99){ //もし、1~99の範囲なら以下を実行
lc4.setScanLimit(0, 3); // 2桁表示にする。(最初は行数、2番めが桁数、0が1桁、1が2桁…)
}
else if(value >= 100 && value <= 999){ //もし、999より小さいなら以下を実行
lc4.setScanLimit(0, 3); // 4桁表示にする。(最初は行数、2番めが桁数、0が1桁、1が2桁…)
lc4.setIntensity(0, 5); // 15 = brightest
}
else if(value >= 1000 && value <= 9999){ //もし、999より小さいなら以下を実行
lc4.setScanLimit(0, 3); // 4桁表示にする。(最初は行数、2番めが桁数、0が1桁、1が2桁…)
}
else {
lc4.setScanLimit(0, 5); //そうでないなら、5桁表示にする
}
if(value >= -99 && value <= -10){ //もし、Valueが-99〜より下で-10より上なら-以下を実行
lc4.setScanLimit(0, 2); //3桁表示
lc4.setChar(0,2,'-',false); //3桁目に-を表示(2は3桁目)
}
if(value >= -999 && value <= -100){ //もし、-999より下で-100より上なら以下を実行
//lc4.setChar(0,4,' ',false); //5桁目に表示している-が残るので消して下の4桁芽の-を表示
lc4.setChar(0,4,'-',false); //5桁目に-を表示
lc4.setIntensity(0, 10); // 15 = brightest
}
if(value >= -9999 && value <= -1000){ //もし、-9999より下で-1000より上なら-以下を実行
lc4.setChar(0,4,'-',false); //5桁目に-を表示
}
}
B747-400 7セグメント:ALT(Teensyのピンを3つ使用、どれでも可)
#include <LedControl.h>
const int lc5_DIN_Pin = 40; //7セグ、teensyピン位置
const int lc5_CLK_Pin = 41;
const int lc5_LOAD_Pin = 42;
//入力:DINピン、CLK端子、LOAD端子、チップ数(MAX7219の数)
LedControl lc5 = LedControl(lc5_DIN_Pin, lc5_CLK_Pin, lc5_LOAD_Pin, 1);
const int ALTEnc_R_Pin = 4;
const int ALTEnc_L_Pin = 5;
FlightSimInteger AltitudeLed;
void setup() {
lc5.shutdown(0, false); // ディスプレイをオンに(0が最初のチップ)
lc5.setIntensity(0, 15); // 15 = brightest
//mydisplay.setScanLimit(0, 3); // 表示する桁数の指定(最初は行数、2番めが桁数、0が1桁、1が2桁…)
pinMode(lc5_DIN_Pin, OUTPUT);
pinMode(lc5_CLK_Pin, OUTPUT);
pinMode(lc5_LOAD_Pin, OUTPUT);
AltitudeLed = XPlaneRef("sim/cockpit/autopilot/altitude"); //これを設定する意味が不明だが、これにより7セグがうまく動作する
AltitudeLed.onChange(update_alt_act_lcd); // X-Planeが更新されたらlc4Dを更新する(上と3つセットになる)
}
void loop() {
FlightSim.update();
}
void update_alt_act_lcd(long value) { //value これで高度の数字を読み込む
int alt_act_keta1 = value % 10; //例えば123の数字の場合、123÷10=12.3で小数点以下の3が1桁の数字として表示
int alt_act_keta2 = value / 10 % 10 ; //例えば123の数字の場合、、÷10=12.3、さらに10で割って、1.23で小数点以下の2が表示
int alt_act_keta3 = value / 100 % 10; //例えば123の数字の場合、123÷100=1.23で1の整数が3桁目の数字として表示
int alt_act_keta4 = value / 1000 % 10;
int alt_act_keta5 = value / 10000 % 10;
lc5.setDigit(0, 0, 0, false); //1桁目の値はvalueからではなかく、強制的に0(3つめの0がそれ)で表示
lc5.setDigit(0, 1, 0, false); //2桁目の値はvalueからではなかく、強制的に0(3つめの0がそれ)で表示
lc5.setDigit(0, 2, alt_act_keta3, false); //3桁目の値を表示
lc5.setDigit(0, 3, alt_act_keta4, false); //4桁目の値を表示
lc5.setDigit(0, 4, alt_act_keta5, false); //5桁目の値を表示
}