diff --git a/A320-main.xml b/A320-main.xml
index 3e897829..fceba4fa 100644
--- a/A320-main.xml
+++ b/A320-main.xml
@@ -568,6 +568,10 @@
false
0
+
+ 0
+ 0
+
0
0
@@ -767,6 +771,10 @@
0
+
+ 2000
+ 0
+
0
@@ -972,7 +980,7 @@
true
- 3
+ 1
Sounds/tcas/female/
@@ -1563,6 +1571,9 @@
Aircraft/IDG-A32X/Nasal/acp.nas
+
+ Aircraft/IDG-A32X/Nasal/atc.nas
+
diff --git a/AircraftConfig/acconfig.nas b/AircraftConfig/acconfig.nas
index e02cd7c5..a332d690 100644
--- a/AircraftConfig/acconfig.nas
+++ b/AircraftConfig/acconfig.nas
@@ -266,6 +266,8 @@ var colddark = func {
setprop("/controls/lighting/taxi-light-switch", 0.0);
setprop("/controls/switches/landing-lights-l", 0.0);
setprop("/controls/switches/landing-lights-r", 0.0);
+ setprop("/controls/atc/mode-knob", 0);
+ atc.transponderPanel.modeSwitch(1);
libraries.systemsInit();
failReset();
if (getprop("/engines/engine[1]/n2-actual") < 2) {
@@ -447,6 +449,8 @@ var taxi_b = func {
setprop("/controls/radio/rmp[0]/on", 1);
setprop("/controls/radio/rmp[1]/on", 1);
setprop("/controls/radio/rmp[2]/on", 1);
+ setprop("/controls/atc/mode-knob", 2);
+ atc.transponderPanel.modeSwitch(3);
setprop("/systems/fadec/power-avail", 1);
setprop("/systems/fadec/powered-time", -310);
setprop("/controls/lighting/turnoff-light-switch", 1);
@@ -495,6 +499,8 @@ var takeoff = func {
setprop("/controls/flight/flap-lever", 1);
setprop("/controls/flight/flap-pos", 2);
setprop("/controls/flight/flap-txt", "1+F");
+ setprop("/controls/atc/mode-knob", 4);
+ atc.transponderPanel.modeSwitch(5);
libraries.flaptimer.start();
setprop("/controls/flight/elevator-trim", -0.07);
systems.arm_autobrake(3);
diff --git a/Models/FlightDeck/a320.flightdeck.xml b/Models/FlightDeck/a320.flightdeck.xml
index 0e6c4a65..dc1911ff 100644
--- a/Models/FlightDeck/a320.flightdeck.xml
+++ b/Models/FlightDeck/a320.flightdeck.xml
@@ -350,6 +350,8 @@
arpt_led
arpt_led.001
a-thr_led
+ atc-code
+ atc-test
audio_att_led
audio_att_sgn
audio_call_hf2_led
@@ -443,11 +445,25 @@
+
+ select
+ atc-code
+
+
+
+ controls/switches/annun-test
+ 1
+
+
+
+
+
select
alt-text-test
+ atc-test
audio_att_sgn
audio_call_hf2_led
audio_call_hf1_led
@@ -5912,6 +5928,8 @@
hdg-text-test
alt-text-test
vs-text-test
+ atc-code
+ atc-test
fpa-text
qnh-inhg
qnh-hpa
diff --git a/Models/Instruments/Pedestal_up/Pedestal_up.xml b/Models/Instruments/Pedestal_up/Pedestal_up.xml
index 56acbf9e..67446fa1 100644
--- a/Models/Instruments/Pedestal_up/Pedestal_up.xml
+++ b/Models/Instruments/Pedestal_up/Pedestal_up.xml
@@ -9,7 +9,23 @@
Panel lighting
material
+ atc_0
+ atc_1
+ atc_2
+ atc_3
+ atc_4
+ atc_5
+ atc_6
+ atc_7
+ atc_abv
atc_body
+ atc_clr
+ atc_fail
+ atc_ident
+ atc_screen
+ atc_stby
+ atc_sys
+ atc_thrt
ecam_body
ecam_switch_body
engine_body
@@ -79,7 +95,6 @@
radar_glare
-
Aircraft/IDG-A32X/Models/Effects/cockpit-irradiance
ecam_body
@@ -106,4 +121,309 @@
vu112_aids
vu112_dfdr
+
+
+ Aircraft/IDG-A32X/Models/Effects/cockpit-irradiance
+ atc_0
+ atc_1
+ atc_2
+ atc_3
+ atc_4
+ atc_5
+ atc_6
+ atc_7
+ atc_abv
+ atc_body
+ atc_clr
+ atc_fail
+ atc_ident
+ atc_screen
+ atc_stby
+ atc_sys
+ atc_thrt
+
+
+
+ atc-code
+
+ -0.01279
+ 0.20
+ -0.13391
+ 90
+
+ left-center
+ xy-plane
+ text-value
+ /systems/atc/transponder-code
+ %s
+ false
+ led.txf
+ true
+ false
+ false
+ 0.009
+
+ 32
+ 32
+
+
+
+
+ atc-test
+
+ -0.01279
+ 0.20
+ -0.13391
+ 90
+
+ left-center
+ xy-plane
+ literal
+ 8888
+ led.txf
+ true
+ false
+ false
+ 0.009
+
+ 32
+ 32
+
+
+
+
+ pick
+ atc_0
+
+
+ false
+
+ nasal
+
+
+
+
+
+
+ pick
+ atc_1
+
+
+ false
+
+ nasal
+
+
+
+
+
+
+ pick
+ atc_2
+
+
+ false
+
+ nasal
+
+
+
+
+
+
+ pick
+ atc_3
+
+
+ false
+
+ nasal
+
+
+
+
+
+
+ pick
+ atc_4
+
+
+ false
+
+ nasal
+
+
+
+
+
+
+ pick
+ atc_5
+
+
+ false
+
+ nasal
+
+
+
+
+
+
+ pick
+ atc_6
+
+
+ false
+
+ nasal
+
+
+
+
+
+
+ pick
+ atc_7
+
+
+ false
+
+ nasal
+
+
+
+
+
+
+ pick
+ atc_clr
+
+
+ false
+
+ nasal
+
+
+
+
+
+
+ rotate
+ atc_sys
+ -30
+ 30
+
+ -0.003352
+ 0.131446
+ -0.13275
+
+
+ 0
+ 0
+ 1
+
+ controls/atc/system-knob
+
+
+
+ pick
+ atc_sys
+
+
+
+ property-cycle
+ controls/atc/system-knob
+ 0
+ 1
+
+
+ nasal
+
+
+
+
+
+
+ rotate
+ atc_stby
+ -35
+ 70
+
+ 0.01146
+ 0.213663
+ -0.13086
+
+
+ 0
+ 0
+ 1
+
+ controls/atc/mode-knob
+
+
+
+ pick
+ atc_stby
+
+
+
+
+ property-cycle
+ controls/atc/mode-knob
+ 0
+ 1
+ 2
+ 3
+ 4
+
+
+ nasal
+
+
+
+
+
+
+
+ property-cycle
+ controls/atc/mode-knob
+ 4
+ 3
+ 2
+ 1
+ 0
+
+
+ nasal
+
+
+
+
+
+
+ pick
+ atc_ident
+
+
+
+ nasal
+
+
+
+
+
+
+ select
+ atc_fail
+
+
+ systems/atc/failed
+
+ systems/electrical/bus/dc-ess
+ 25
+
+
+
+
diff --git a/Nasal/atc.nas b/Nasal/atc.nas
new file mode 100644
index 00000000..b58feeb8
--- /dev/null
+++ b/Nasal/atc.nas
@@ -0,0 +1,245 @@
+# A3XX ATC Panel
+# Jonathan Redpath
+
+# Copyright (c) 2019 Jonathan Redpath
+
+var idCode = props.globals.getNode("/instrumentation/transponder/id-code", 1);
+
+var guiModes = ['OFF', 'STANDBY', 'TEST', 'GROUND', 'ON', 'ALTITUDE'];
+var guiNode = props.globals.getNode("/sim/gui/dialogs/radios/transponder-mode", 1);
+var forLoopFlag = 0;
+
+var Transponder = {
+ mode: 0,
+ code: "2000",
+ selected: 0,
+ electricalSrc: "",
+ activeADIRS: 0,
+ condition: 0,
+ failed: 0,
+ codeDigitsNodes: [props.globals.getNode("/instrumentation/transponder/inputs/digit[0]", 1), props.globals.getNode("/instrumentation/transponder/inputs/digit[1]", 1), props.globals.getNode("/instrumentation/transponder/inputs/digit[2]", 1), props.globals.getNode("/instrumentation/transponder/inputs/digit[3]", 1)],
+ serviceableNode: props.globals.getNode("/instrumentation/transponder/serviceable", 1),
+ knobNode: props.globals.getNode("instrumentation/transponder/inputs/knob-mode", 1),
+ identNode: props.globals.getNode("/instrumentation/transponder/inputs/ident-btn", 1),
+ wowNode: props.globals.getNode("/fdm/jsbsim/position/wow"),
+ ac1Node: props.globals.getNode("/systems/electrical/bus/ac1", 1),
+ tcasNode: props.globals.getNode("/instrumentation/tcas/inputs/mode"),
+ aglNode: props.globals.getNode("/position/gear-agl-ft", 1),
+ electricNode: props.globals.getNode("/systems/electrical/outputs/transponder", 1),
+ new: func(elecSrc, ADIRS) {
+ var t = {parents:[Transponder]};
+ t.mode = 1;
+ t.code = "2000";
+ t.selected = 0;
+ t.condition = 100;
+ t.failed = 0;
+ t.electricalSrc = props.globals.getNode(elecSrc, 1);
+ t.activeADIRS = ADIRS;
+
+ return t;
+ },
+ update: func() {
+ # TCAS - on seperate electrical source, so has to be before transponder electrical checking
+ if (me.ac1Node.getValue() < 110) {
+ me.tcasNode.setValue(0); # off
+ } else {
+ if (me.mode >= 1 and me.mode <= 3) {
+ me.tcasNode.setValue(1); # stby
+ } else if (me.mode == 4 or (me.mode == 5 and me.aglNode.getValue() < 1000)) {
+ me.tcasNode.setValue(2); # TA only
+ } else if (me.mode == 5) {
+ me.tcasNode.setValue(3); # TA/RA
+ }
+ }
+
+ if (me.electricalSrc.getValue() > 110 and me.failed == 0) {
+ me.condition = 100;
+ transponderPanel.atcFailLight(0);
+ me.electricNode.setValue(28);
+ transponderPanel.modeSwitch(transponderPanel.modeSel);
+ } else {
+ me.condition = 0;
+ transponderPanel.atcFailLight(1);
+ me.setMode(0); # off
+ if (me.electricalSrc.getValue() < 110) {
+ me.electricNode.setValue(0);
+ } else {
+ me.electricNode.setValue(28);
+ }
+ }
+
+ if (me.condition == 0 or me.selected != 1) {
+ return;
+ }
+
+ if (me.mode == 1) {
+ if (me.knobNode.getValue() != 1) {
+ me.setMode(1); # stby
+ }
+ } else if (me.mode == 2) {
+ if (me.knobNode.getValue() != 4) {
+ me.setMode(4); # on
+ }
+ } else if (me.mode >= 3) {
+ if (me.wowNode.getBoolValue()) {
+ if (me.knobNode.getValue() != 3) {
+ me.setMode(3); # gnd
+ }
+ } else {
+ if (me.knobNode.getValue() != 5) {
+ me.setMode(5); # alt
+ }
+ }
+ }
+ },
+ switchADIRS: func(newADIRS) {
+ if (newADIRS < 1 or newADIRS > 3) {
+ return;
+ }
+ me.activeADIRS = newADIRS;
+ },
+ modeSwitch: func(newMode) {
+ me.mode = newMode;
+ },
+ setCode: func(newCode) {
+ me.code = newCode;
+ forLoopFlag = 1;
+ for (index = 0; index < 4; index = index + 1) {
+ me.codeDigitsNodes[3 - index].setValue(substr(me.code, index, 1));
+ }
+ forLoopFlag = 0;
+ },
+ setMode: func(m) {
+ me.knobNode.setValue(m);
+ guiNode.setValue(guiModes[m]);
+ },
+ fail: func() {
+ me.failed = 1;
+ me.serviceableNode.setBoolValue(0);
+ transponderPanel.atcFailLight(1);
+ },
+ restore: func() {
+ me.failed = 0;
+ me.serviceableNode.setBoolValue(1);
+ transponderPanel.atcFailLight(0);
+ },
+ ident: func() {
+ me.identNode.setValue(0);
+ settimer(func() {
+ me.identNode.setValue(1);
+ }, 0.1);
+ },
+};
+
+var transponderPanel = {
+ atcSel: 1,
+ modeSel: 1,
+ identBtn: 0,
+ code: "2000",
+ codeDisp: "2000",
+ codeProp: props.globals.initNode("/systems/atc/transponder-code", "2000", "STRING"),
+ failLight: 0,
+ clearFlag: 0,
+ keypad: func(keyNum) {
+ if (props.globals.getNode("/controls/switches/annun-test", 1).getBoolValue() or props.globals.getNode("/systems/electrical/bus/dc-ess", 1).getValue() < 25) {
+ return;
+ }
+ if (keyNum < 0 or keyNum > 7) {
+ return;
+ }
+
+ if (size(me.codeDisp) < 3) {
+ me.codeDisp = me.codeDisp ~ keyNum;
+ me.codeProp.setValue(sprintf("%s", me.codeDisp));
+ } elsif (size(me.codeDisp) == 3) {
+ me.codeDisp = me.codeDisp ~ keyNum;
+ me.codeProp.setValue(sprintf("%s", me.codeDisp));
+ me.code = me.codeDisp;
+ Transponders.vector[me.atcSel - 1].setCode(me.code);
+ }
+ },
+ clearKey: func() {
+ if (props.globals.getNode("/controls/switches/annun-test", 1).getBoolValue() or props.globals.getNode("/systems/electrical/bus/dc-ess", 1).getValue() < 25) {
+ return;
+ }
+ if (me.codeDisp != "") {
+ if (me.clearFlag == 0) {
+ me.codeDisp = left(me.codeDisp, size(me.codeDisp) - 1);
+ me.codeProp.setValue(sprintf("%s", me.codeDisp));
+ me.clearFlag = 1;
+ } else {
+ me.codeDisp = "";
+ me.codeProp.setValue(sprintf("%s", me.codeDisp));
+ }
+ }
+ },
+ atcSwitch: func(newSel) {
+ if (newSel < 1 or newSel > 2) {
+ return;
+ }
+ me.atcSel = newSel;
+
+ # update code
+ if (me.newSel = 1) {
+ Transponders.vector[1].selected = 0;
+ } else {
+ Transponders.vector[0].selected = 0;
+ }
+
+ Transponders.vector[me.atcSel - 1].selected = 1;
+ me.code = Transponders.vector[me.atcSel - 1].code;
+ me.codeDisp = me.code;
+ me.codeProp.setValue(sprintf("%s", me.codeDisp));
+ Transponders.vector[me.atcSel - 1].setCode(me.code); # update transmitted code to other transponders code
+ me.clearFlag = 0;
+
+ # update newly selected transponder
+ Transponders.vector[me.atcSel - 1].modeSwitch(me.modeSel);
+ me.atcFailLight(Transponders.vector[me.atcSel - 1].failed);
+ },
+ modeSwitch: func(newMode) {
+ if (newMode < 0 or newMode > 5) {
+ return;
+ }
+ me.modeSel = newMode;
+ Transponders.vector[me.atcSel - 1].modeSwitch(me.modeSel);
+ },
+ atcFailLight: func(newFail) {
+ if (newFail < 0 or newFail > 1) {
+ return;
+ }
+ me.failLight = newFail;
+ props.globals.getNode("/systems/atc/failed").setBoolValue(me.failLight);
+ },
+ identSwitch: func() {
+ Transponders.vector[me.atcSel - 1].ident();
+ },
+ fastSetCode: func(newCode) {
+ if (size(newCode) != 4 or size(me.codeDisp) != 4) {
+ return;
+ }
+ me.clearFlag = 0;
+ me.code = newCode;
+ me.codeDisp = me.code;
+ me.codeProp.setValue(sprintf("%s", me.codeDisp));
+ Transponders.vector[me.atcSel - 1].setCode(me.code);
+ }
+};
+
+var init = func() {
+ transponderPanel.atcSwitch(1);
+ transponderTimer.start();
+}
+
+# Handler for code change from generic dialog
+setlistener("/instrumentation/transponder/id-code", func {
+ if (transponderPanel.code != idCode.getValue() and forLoopFlag == 0) {
+ transponderPanel.fastSetCode(sprintf("%04d", idCode.getValue()));
+ }
+}, 0, 0);
+
+var Transponders = std.Vector.new([Transponder.new("/systems/electrical/bus/ac-ess-shed", 1), Transponder.new("/systems/electrical/bus/ac2", 2)]);
+
+var transponderTimer = maketimer(0.1, func() {
+ Transponders.vector[transponderPanel.atcSel - 1].update();
+});
diff --git a/Nasal/electrical.nas b/Nasal/electrical.nas
index d5822579..d4ac2209 100644
--- a/Nasal/electrical.nas
+++ b/Nasal/electrical.nas
@@ -731,7 +731,6 @@ var ELEC = {
setprop("/systems/electrical/outputs/stobe-lights", 0);
setprop("/systems/electrical/outputs/tacan", 0);
setprop("/systems/electrical/outputs/taxi-lights", 0);
- setprop("/systems/electrical/outputs/transponder", 0);
setprop("/systems/electrical/outputs/turn-coordinator", 0);
setprop("/controls/lighting/fcu-panel-norm", 0);
setprop("/controls/lighting/main-panel-norm", 0);
@@ -767,7 +766,6 @@ var ELEC = {
setprop("/systems/electrical/outputs/stobe-lights", dc_volt_std);
setprop("/systems/electrical/outputs/tacan", dc_volt_std);
setprop("/systems/electrical/outputs/taxi-lights", dc_volt_std);
- setprop("/systems/electrical/outputs/transponder", dc_volt_std);
setprop("/systems/electrical/outputs/turn-coordinator", dc_volt_std);
setprop("/controls/lighting/fcu-panel-norm", getprop("/controls/lighting/fcu-panel-knb"));
setprop("/controls/lighting/main-panel-norm", getprop("/controls/lighting/main-panel-knb"));
diff --git a/Nasal/libraries.nas b/Nasal/libraries.nas
index 8ff64be3..fa0c8867 100644
--- a/Nasal/libraries.nas
+++ b/Nasal/libraries.nas
@@ -205,6 +205,7 @@ var systemsInit = func {
rmp.init();
acp.init();
ecam.ECAM_controller.init();
+ atc.init();
}
setlistener("/sim/signals/fdm-initialized", func {
diff --git a/Systems/instrumentation.xml b/Systems/instrumentation.xml
index e17382e3..d03bea03 100644
--- a/Systems/instrumentation.xml
+++ b/Systems/instrumentation.xml
@@ -29,6 +29,8 @@
/systems/static/pressure-inhg
0
0
+ 1
+ 1
@@ -134,7 +136,9 @@
transponder
0
+ 2
/instrumentation/encoder/mode-c-alt-ft
+ /instrumentation/encoder/mode-s-alt-ft
@@ -156,6 +160,11 @@
tcas
0
+