Tool to connect Serial USB devices to MSFS2020 via SimConnect/WASM using VS2022

Chapter 5: Example of using X-var

This is an example of when you can make good use of the X-var in my tool. Let’s examine the below example variable definition to set the EFIS_L_OPTION:

INT32_W_X:s0 (L:A32NX_EFIS_L_OPTION, enum) == if{ 0 (>L:A32NX_EFIS_L_OPTION, enum) } els{ l0 (>L:A32NX_EFIS_L_OPTION, enum) }

You can use the same syntax for the EFIS_R_OPTION:

INT32_W_X:s0 (L:A32NX_EFIS_R_OPTION, enum) == if{ 0 (>L:A32NX_EFIS_R_OPTION, enum) } els{ l0 (>L:A32NX_EFIS_R_OPTION, enum) }

This will create variables which you can then use to set the EFIS_L_OPTION or EFIS_R_OPTION. Below screenshot shows both registered X-vars as variables 004 and 005.

But why using this complex X-var, and not simply use the L-var that was already created in our previous example (see variable number 003):

INT32_RW_L:A32NX_EFIS_L_OPTION, enum

The reason is that for using command “003=[param]”, we first need to determine the parameter based on the current status of the EFIS_L_OPTION. This will require some coding in our device, and the result will be sending the command “003=1” or “003=0” (if we want to set/reset CSTR).

The advantage of using the X-var is that we I can now use the same command “004=1” in all cases. This will set or reset CSTR depending on the current value of CSTR. This makes it extremely easy to connect this with a simple button in your Hardware, which always will send “004=1” - no coding required. The same applies to setting/resetting the other EFIS_L_OPTION values WPT (004=3), VOR D (004=2), NDP (004=4) and ARPT (004=5).

X-vars make use of execute_calculator_code in the WASM module, and this makes use of strings written in RPN notation. Some basic knowledge of RPN is required to make use of the full potential that X-vars offer. Let’s dissect the command in more detail.

Let’s use the parameter 1 to set CSTR of EFIS_L_OPTION. In below explanation, “L-var” is just a shortcut for “L:A32NX_EFIS_L_OPTION, enum”. The string that is executed could look like below:

1 (L-var) == if{ 0 (>L-var) } els{ 1 (>L-var) }

  • 1 (L-var) ==
    This compares the value 1 with the value of the L-var. The result can be TRUE or FALSE. You can even try this in the “execute_calculator_code”, and depending on the value of your L-var, you will see 0 (false) or 1 (true) as return values.
  • if{ ... } els{ ... }
    If the previous statements resulted in TRUE, then the first { … } is executed. If FALSE, the second { … } is executed.
  • 0 (>L-var)
    This sets the L-var to 0 - this means that if CSTR was set, it will now be reset
  • 1 (>L-var)
    This sets the L-var to 1 - this means that if CSTR was not set, it will now be set

So basically, I’m checking if the current value of the L-var is equal to the required value (1). If it is, I reset it to 0. If it is not, then I force the value to the required value (1).

But the above only works for the value 1. If I want to use the value 2 (VOR D), I should use:

2 (L-var) == if{ 0 (>L-var) } els{ 2 (>L-var) }.

A more common approach would be to write this as follows:

param (L-var) == if{ 0 (>L-var) } els{ param (>L-var) }

We now have to find a way when I use the command “NNN=X”, the 2 occurrences of param in the string are replaced with X. But the problem is that when I give a parameter to our command, this is only going to be added in FRONT of the variable. We should find a way to store the param somewhere, and then re-use it later in the string.

This can be done by using the RPN commands sN and lN. (be aware that the second command is the small caps “L”). Explanation of these commands can be found in the RPN documentation.

Now we can fully understand the string:

s0 (L:A32NX_EFIS_L_OPTION, enum) == if{ 0 (>L:A32NX_EFIS_L_OPTION, enum) } els{ l0 (>L:A32NX_EFIS_L_OPTION, enum) }

If we use the above with the command “NNN=4”, then in the WASM module, the following string is used with “execute_calculator_code” - the parameter 4 is added in front of the string:

4 s0 (L:A32NX_EFIS_L_OPTION, enum) == if{ 0 (>L:A32NX_EFIS_L_OPTION, enum) } els{ l0 (>L:A32NX_EFIS_L_OPTION, enum) }

First the 4 is stored in the internal register 0 using command s0. But the 4 stays on top of the stack, and is then used to be compared with the current value of EFIS_L_OPTION. If this is TRUE, then EFIS_L_OPTION is set to 0 (switch off). If this is FALSE, then first the stored param value is loaded from register 0 using command l0, which gives us the value 4, and then EFIS_L_OPTION is set to that value.

You can use the above string in the “execute_calculator_code” of the tool, and then change the 4 by a value between 0 and 5 and experiment with it. Below uses the value 2.

By the way, I haven’t invented this string myself. In my earlier post (see here), I showed a way how you use the “Behaviors” window to get some good examples of RPN strings. These are used by the developers of FlyByWire themselves. The above is exactly how they implemented the push-buttons of the EFIS_L_OPTION and EFIS_R_OPTION.

WARNING: Make sure you don’t exceed 256 bytes for the strings used to register variables.

Goto Chapter 6: Connecting with PIC Microcontroller

1 Like