MSFS2020 Transponder Keypad and Display on 7 Segment Module - MobiFlight/MobiFlight-Connector GitHub Wiki
How to Mimic the FBW A320 ATC Keypad and Display
In this tutorial we will configure Mobiflight to mimic the operation of the ATC (Transponder) panel keypad of the FlyByWire A320 mod airplane. Our focus will be only on mimicking the behavior of the keypad and display, using RPN code in both input and output configurations. We will not cover the other knobs and buttons in the ATC panel.
The A320 ATC Panel
The keypad has 9 keys, 8 numeric (numbers 0 to 7) plus a CLR key. The display shows the four octal digits transponder code. In normal operation, the numeric keys are disabled and the CLR key is pressed once or twice, depending on the action needed. Press CLR once to delete and reenter the last number, or press twice to delete the four digits and reenter the entire code. The led display will show the transponder code in normal operation or each new digit from left to right, when entering a new transponder code. The CLR key can be pressed at any time during entering a new code to delete the last number entered, or press twice to restart the code entry. If there is a delay of 7 seconds or more at any time during the entry of the code prior to completing the four digits, the unit resets the display back to the previously used code. When the fourth digit is entered the new code is automatically accepted.
This is the behavior we intend to reproduce in our external ATC panel keypad and display.
Preparations
We will need to have a
- Any supported Arduino board (Mega, Pro Micro, Uno, Nano)
- One MAX7219 eight digit 7-Segment LED display module (we will only use four digits),
- Nine buttons for the keypad
- Working installation of MSFS2020 and Mobiflight
We assume that you know how to wire the 7-segment display module and buttons to your Arduino board. If not, please pause this tutorial and refer to more basic tutorials already available on how to wire and configure devices with Arduino and Mobiflight. Please take note of the pin numbers used by the LED module display and the nine buttons. Once the hardware is wired to the arduino, please create the corresponding devices in your Mobiflight board configuration. Again, we assume that adding device configurations to your Mobiflight board is known by you. Be sure to upload the board configuration once you have completed the device configurations. Also save this configuration to a mfmc file.
Next, you need to create nine input configurations for the nine buttons and one output configuration for the LED display module. For your convenience, all of the code events, both inputs and outputs, shown in this tutorial are available as presets in Mobiflight and Hubhop. Please search for "ATC Custom" to locate all of them.
Button Configuration
Let's start with the button for "1". Name this configuration "ATC Btn 1". In the input tab select the board and corresponding button, which you have already created. In the On Press tab, select "MSFS2020-Custom Input" and enter the following code:
KEY 1
(L:XPNDR_clr) 0 > if{ 1 (>L:XPNDR_key) 1 (>L:XPNDR_act,bool) (>H:A320_Neo_ATC_BTN_1) }
Notes on the code:
XPNDR_clr is a user-defined control variable used to flag when the CLR key has been pressed. The CLR key should be pressed in order to activate entering numbers on the keypad, therefore we first check if this variable is not zero. If false, we do nothing. If true, we enter a "1" in variable XPNDR_key. This variable holds the value of the last key pressed to be used later. We then set the XPNDR_act variable to 1, signalling that a keypad key has been pressed. To maintain the sim in sync with our key press, we call the A320 H: event for the same key press. If you are not using the FBW A320, then you can delete this H: event from your code and replace with the appropriate event for your airplane.
All 8 keys from 0 to 7 will be treated in the same way. The only difference in the code for each key press will be the value entered in XPNDR_key and the corresponding H: event to maintain the sim display in sync with ours. Again, if not using the FBW A320, you can delete this H: event from your code and replace with the appropriate event for your airplane.
Following is the list of code to be entered in the Custom Input box for each subsequent button configuration. Please proceed to create the additional button configuration in the same way as the configuration for the "1" Key.
KEY 2
(L:XPNDR_clr) 0 > if{ 2 (>L:XPNDR_key) 1 (>L:XPNDR_act,bool) (>H:A320_Neo_ATC_BTN_2) }
KEY 3
(L:XPNDR_clr) 0 > if{ 3 (>L:XPNDR_key) 1 (>L:XPNDR_act,bool) (>H:A320_Neo_ATC_BTN_3) }
KEY 4
(L:XPNDR_clr) 0 > if{ 4 (>L:XPNDR_key) 1 (>L:XPNDR_act,bool) (>H:A320_Neo_ATC_BTN_4) }
KEY 5
(L:XPNDR_clr) 0 > if{ 5 (>L:XPNDR_key) 1 (>L:XPNDR_act,bool) (>H:A320_Neo_ATC_BTN_5) }
KEY 6
(L:XPNDR_clr) 0 > if{ 6 (>L:XPNDR_key) 1 (>L:XPNDR_act,bool) (>H:A320_Neo_ATC_BTN_6) }
KEY 7
(L:XPNDR_clr) 0 > if{ 7 (>L:XPNDR_key) 1 (>L:XPNDR_act,bool) (>H:A320_Neo_ATC_BTN_7) }
KEY 0
(L:XPNDR_clr) 0 > if{ 0 (>L:XPNDR_key) 1 (>L:XPNDR_act,bool) (>H:A320_Neo_ATC_BTN_0) }
The CLR Key
The CLR Key is very important in this setup. Remember, the keypad remains inactive until the CLR is pressed. The first press of the CLR key is to delete and reenter the last key pressed. To enter a new transponder code, the CLR key needs to be pressed twice. This requires some special treatment in the code in order to detect this second key press.
Create the button configuration in the same way we did for the number buttons. The code for the CLR key is a bit more complicated
KEY CLR
(L:XPNDR_clr) s1 2 < if{
(L:XPNDR_pos) -- s0 0 < if{ 3 } els{ l0 } (>L:XPNDR_pos)
l1 0 == if{ (A:TRANSPONDER CODE:1,number) }
els{ (L:XPNDR_temp) } 10 div (>L:XPNDR_temp) 2 (>L:XPNDR_clr) } }
els{ 0 (>L:XPNDR_temp) 0 (>L:XPNDR_pos) }
(>H:A320_Neo_ATC_BTN_CLR)
(E:SIMULATION TIME,second) 7 + (>L:XPNDR_timeout)
Notes on the CLR key code:
The first thing the code checks is to see if this is the first or second press of this key. XPNDR_clr is zero when there is no action pending or 1 if we are in the middle of entering the code. Therefore if the value of XPNDR_clear is equal to 0 or 1, we have the first press. To backspace one digit in the code we take either the current Transponder code (if no partial code has been entered yet) or the partial code being entered in XPNDR_temp and do integer division by 10. In effect, this shifts the code one position to the right. In the first press, the variable XPNDR_pos is decreased by one (to edit the last entered number) and XPNDR_clr is set to 2 as an indication that the first CLR press has been processed.
If the CLR key is pressed again, it will have a value of 2 and the code will set for entering the entire Transponder code. To that effect, the variables XPNDR_temp and XPNDR_pos are both set to 0.
We now call the H: event for the CLR key to maintain the in sim display in sync with our display module.
Lastly, we take care of the key timeout. The simulator has the variable "SIMULATION TIME" which keeps count of the time elapsed since the sim started to run. The timeout works by reading this variable (now time), adding 7 seconds and storing this in XPNDR_timeout. This adding of 7 seconds is done each time any key is pressed. We will see later how the timeout check code uses this information.
OUTPUT CONFIGURATIONS
Most of the action takes place in several output configurations as detailed below. To avoid code repetition for the key presses there is a Key Press Handler config that builds up the transponder code as it is entered. There is also a Timeout Handler output config and two code display configurations.
OUTPUT CONFIG 1 - NUM KEY PRESS HANDLER
(L:XPNDR_act,bool) if{
0 (>L:XPNDR_act) (E:SIMULATION TIME,second) 7 + (>L:XPNDR_timeout)
(L:XPNDR_clr) 2 == if{ 1 (>L:XPNDR_clr) }
(L:XPNDR_key) (L:XPNDR_temp,number) 10 * + (>L:XPNDR_temp,number)
(L:XPNDR_pos) ++ 4 min s0 (>L:XPNDR_pos)
l0 4 == if{ (L:XPNDR_temp,bco16) (>K:XPNDR_SET)
0 (>L:XPNDR_timeout) 0 (>L:XPNDR_temp,number)
0 (>L:XPNDR_pos) 0 (>L:XPNDR_clr) } }
(L:XPNDR_temp)
Notes on the Keypress Handler code:
Although this is an output config, we will not display it anywhere. It will be used as config ref in the actual display config.
This code builds up the Transponder code four digits as they are entered left to right. The Lvar XPNDR_act is the flag that indicates whether a key has been pressed or not. If zero, we do nothing. If equal to 1, we process the key press. They value of the key pressed is stored in XPNDR_key.
A key was pressed, so the timeout is reset by setting the timeout variable to seven seconds ahead of current time. If there is any delay of 7 seconds or more in entering the code, the timeout handler will abort the operation and reset the display. The 7-second timeout is consistent with the A320 ATC unit in the simulator.
The Lvar XPNDR_clear is the status of the CLR key, as pressing the CLR key once or twice (value 1 or 2) is required to initiate editing of the last digit or new code entry, respectively. A status value of 2 is immediately set to 1 (normal editing of transponder code) as CLR can be pressed again while editing the code to backspace. See the CLR key notes for a better explanation of the meaning of the XPNDR_clr values.
The new transponder code is stored in XPNDR_temp. The code is entered left to right by multiplying the stored code times 10 and adding the newly entered digit. The current transponder code position is stored in XPNDR_pos and is incremented as each number is entered. When the fourth position is entered, the XPNDR_temp variable is converted to BCO16 format before calling the K:XPNDR_SET event, which finally sets the code in the simulator. All variables are set back to 0 to end the edit mode.
The code returns to Mobiflight the current value of the XPNDR_temp Lvar
OUTPUT CONFIG 2 - 7 SEC TIMEOUT HANDLER
(L:XPNDR_timeout) 0 != if{ (E:SIMULATION TIME,second) (L:XPNDR_timeout) > if{ 0 s0 (>L:XPNDR_timeout) l0 (>L:XPNDR_temp) l0 (>L:XPNDR_pos) l0 (>L:XPNDR_clr) } }
Notes on the timeout handler code:
It just checks if XPNDR_timeout is zero or not. If it is equal to zero, no key has been pressed and we do nothing. If not equal to zero, then we check if the current time has exceeded the time stored in XPNDR_timeout. If the timeout is not exceeded we do nothing. If the timeout has been exceeded, we reset all the XPNDR variables back to zero.
If there is any delay of 7 seconds or more in entering the code, the timeout handler will abort the operation and reset the display to the previous transponder code, which is only changed when the fourth digit is entered. The 7-second timeout is consistent with the A320 ATC unit in the simulator.
OUTPUT CONFIG 3 - 7 SEGMENT DISPLAYS THE SIM TRANSPONDER CODE (ZERO LEFT PAD)
This output config displays in the 7 segment display module the current value transponder code in the simulator when in normal operation. This output has a precondition of being active when the XPNDR_clr Lvar is equal to zero, i.e. the unit is not in code editing mode.
The transponder code is read from the simulator with (A:TRANSPONDER CODE:1, number). Additional considerations have been taken to turn off the display when the avionics master switch is off or when there is no power in the main bus. When these conditions are present, the Transform assigns the special value of 8000 to the output config, which is then detected by the Compare function. In this configurations, when the IDENT button is pressed, the transponder code display will blink for 18 seconds
The Compare function takes care of blanking the display whenever the special value of 8000 is detected by setting the value to four spaces in single quotes.
The display device is set with a four character field with left padding activated with "0" character.
OUTPUT CONFIG 4 - 7 SEGMENT DISPLAYS THE CODE BEING EDITED
This output config displays the transponder code as it is being entered from left to right, with leading zeroes if appropriate. It has a precondition of XPNDR_clr Lvar is not equal to zero, i.e. the unit is in code editing mode. The display field is also four characters long with zero padding.
No variable is directly read by this output configuration. The required information is brought in as config references. The code position being edited is placed in the Transform field, so that the Compare function can use it. The XPNDR KEY PRESS HANDLER output config is also read. This configuration, in addition to handling the keypresses, it also returns the value of the code being edited.
The Compare function is used to add one, two, or three spaces at the end of the code being entered, depending on the position of the code. In this way, when the code is less than four characters long, the necessary number of spaces is added to make the width of the string exactly four characters. The spaces fill the remaining space to the right of the code being entered. This setup makes the code numbers be entered from left to right.
The display device is setup in the same way as the output configuration for normal operation. That is, a field with four characters width and padded with zeroes on the left. This left padding with zeroes is what allows leading zeroes in the code to be properly displayed.
The precondition for this output configuration is set for the XPNDR_clr status variable is not equal to 0, which is the case whenever the code is being entered or edited.
CONCLUSION
That's it, you should now have a working display that behaves just like the one in the simulator.
Enjoy!