Introduction

These are the docs for the Flightconnector.

Supported simulators

  • Microsoft Flight Simulator 2020
  • (will work on compatibility ASAP) Microsoft Flight Simulator 2024

How does the connector work

The connector uses Serial communication to communicate with your peripherals. It listens for data transmitted by your devices (we call them inputs) and at the same time it can send data to your devices (we call these outputs). ID's are used to match inputs and outputs to the correct simulation variables.

Input flow

You'll find a list of all available inputs in the inputs chapter. Input flow

Output flow

You'll find a list of all available outputs in the outputs chapter. Output flow

Installation

Connector

The connector can be installed using the latest installer. During startup the connector will automatically check for updates on Github. A pop-up will appear if a new version is available.

WASM

The WASM module unlocks more simulation variables with which to interact. The WASM chapter provides a full explanation. You're able to install the module by copying the entire wasm_module into the MFS2020 community package folder.

If you want to ensure the module is properly installed, you're able to follow these steps:

  • Start MFS2020
  • Open the option menu
  • Enable developer mode
  • Open the debug menu
  • Open the console
  • Search for BitsAndDroids

If the search results show messages that the module was initialized, the module will be loaded properly.

Install from the connector

You’re able to install the WASM module using the installer in the connector.

  • Click on settings from the menubar
  • Select install WASM
  • Click on the “select directory” button
  • Search for the MFS2020 community folder

WASM install community folder

  • Click “Select folder”
  • Click the confirm button

To check if the installation succeeded, you can open the community folder. If the installation succeeded, there should be a folder called BitsAndDroidsModule.

Your first flight with the Connector

Let's setup the connector and take it for a spin. The simplest action to perform is to connect a button to the connector and see if it works. We will use the simulator to see if the button press is registered. So, let's get started.

Make sure you have the connector installed. If not, follow the instructions in the Installation section.

Open the connector and you will see the following screen: //TODO add image

On this screen you're able to start/stop the connector and add/remove devices. For every peripheral you want to connect to the connector, you need to add a device. In this example we will add a single device to the connector.

To keep things simple, we will use a button to connect to the connector. The button will be used to trigger the parking brake in the simulator. The connector will send the signal to the simulator when the button is pressed. For this example we will be using an Arduino Uno but any other microcontroller will work as well. The code for the Arduino Uno can be found here. // THIS ARTICLE IS INCOMPLETE AND WILL BE EXPANDED

Bundles

A bundle is a group of outputs. For example, you can have a bundle for all outputs that are used for a specific controller. This makes it possible to send the correct data to the controller. You can also use these bundles to save multiple presets.

Inputs

EventInput TypeInput ID
SET_THROTTLESAction199
SET_MIXTURESAction115
SET_PROPSAction198
SET_BRAKESAction902
SET_YOKEAction103
AXIS_THROTTLE1_SETAxis203
AXIS_THROTTLE2_SETAxis204
AXIS_THROTTLE3_SETAxis205
AXIS_THROTTLE4_SETAxis206
THROTTLE1_AXIS_SET_EX1Axis207
THROTTLE2_AXIS_SET_EX1Axis208
THROTTLE3_AXIS_SET_EX1Axis209
THROTTLE4_AXIS_SET_EX1Axis210
AXIS_MIXTURE1_SETAxis211
AXIS_MIXTURE2_SETAxis212
AXIS_MIXTURE3_SETAxis213
AXIS_MIXTURE4_SETAxis214
AXIS_PROPELLER1_SETAxis215
AXIS_PROPELLER2_SETAxis216
AXIS_PROPELLER3_SETAxis217
AXIS_PROPELLER4_SETAxis218
AXIS_FLAPS_SETAxis421
AXIS_RUDDER_SETAxis901
AXIS_LEFT_BRAKE_SETAxis221
AXIS_RIGHT_BRAKE_SETAxis222
AXIS_ELEVATOR_SETAxis223
AXIS_AILERONS_SETAxis224
ELEVATOR_TRIM_SETAxis900
TOGGLE_MASTER_IGNITION_SWITCHTrigger101
COM_RADIO_SETSetValueCom100
COM2_RADIO_SETSetValueCom102
XPNDR_IDENT_OFFTrigger103
XPNDR_IDENT_ONTrigger104
XPNDR_IDENT_TOGGLETrigger105
XPNDR_SETSetValueCom106
COM_RADIO_WHOLE_DECTrigger111
COM_RADIO_WHOLE_INCTrigger112
COM2_RADIO_WHOLE_DECTrigger113
COM2_RADIO_WHOLE_INCTrigger114
COM1_RADIO_SWAPTrigger116
COM2_RADIO_SWAPTrigger117
NAV1_RADIO_SWAPTrigger118
NAV2_RADIO_SWAPTrigger119
COM_RADIO_FRACT_DECTrigger124
COM_RADIO_FRACT_INCTrigger125
COM_STBY_RADIO_SETSetValueCom260
COM2_RADIO_FRACT_DECTrigger120
COM2_RADIO_FRACT_INCTrigger121
COM_RADIO_FRACT_DEC_CARRYTrigger126
COM_RADIO_FRACT_INC_CARRYTrigger127
COM2_RADIO_FRACT_DEC_CARRYTrigger122
COM2_RADIO_FRACT_INC_CARRYTrigger123
COM2_STBY_RADIO_SETSetValueCom261
NAV1_RADIO_FRACT_INCTrigger128
NAV1_RADIO_FRACT_DECTrigger129
NAV2_RADIO_FRACT_INCTrigger130
NAV2_RADIO_FRACT_DECTrigger131
NAV1_RADIO_WHOLE_INCTrigger132
NAV1_RADIO_WHOLE_DECTrigger133
NAV2_RADIO_WHOLE_INCTrigger134
NAV2_RADIO_WHOLE_DECTrigger135
RADIO_SELECTED_DME1_IDENT_ENABLETrigger136
RADIO_SELECTED_DME1_IDENT_DISABLETrigger137
RADIO_SELECTED_DME1_IDENT_SETSetValueCom138
RADIO_SELECTED_DM1E_IDENT_TOGGLETrigger139
RADIO_SELECTED_DME2_IDENT_ENABLETrigger140
RADIO_SELECTED_DME2_IDENT_DISABLETrigger141
RADIO_SELECTED_DME2_IDENT_SETSetValueCom142
RADIO_SELECTED_DME2_IDENT_TOGGLETrigger143
TOGGLE_DMETrigger144
RADIO_SELECTED_VOR1_IDENT_ENABLETrigger145
RADIO_SELECTED_VOR1_IDENT_DISABLETrigger146
RADIO_SELECTED_VOR1_IDENT_SETSetValueCom147
RADIO_SELECTED_VOR1_IDENT_TOGGLETrigger148
RADIO_SELECTED_VOR2_IDENT_ENABLETrigger149
RADIO_SELECTED_VOR2_IDENT_DISABLETrigger150
RADIO_SELECTED_VOR2_IDENT_SETSetValueCom151
RADIO_SELECTED_VOR2_IDENT_TOGGLETrigger152
TOGGLE_VORTrigger153
VOR1_OBI_DECTrigger154
VOR1_OBI_INCTrigger155
VOR2_OBI_DECTrigger156
VOR2_OBI_INCTrigger157
RADIO_SELECTED_ADF_IDENT_ENABLETrigger158
RADIO_SELECTED_ADF_IDENT_DISABLETrigger159
RADIO_SELECTED_ADF_IDENT_SETSetValueCom160
RADIO_SELECTED_ADF_IDENT_TOGGLETrigger161
ADF_CARD_INCTrigger162
ADF_CARD_DECTrigger163
ADF_CARD_SETSetValue164
ADF_100_INCTrigger165
ADF_10_INCTrigger166
ADF_1_INCTrigger167
ADF_100_DECTrigger168
ADF_10_DECTrigger169
ADF_1_DECTrigger170
ADF_COMPLETE_SETSetValue179
ADF1_RADIO_TENTHS_DECTrigger390
ADF1_RADIO_TENTHS_INCTrigger391
ADF1_WHOLE_INCTrigger180
ADF1_WHOLE_DECTrigger181
ADF2_100_INCTrigger182
ADF2_10_INCTrigger183
ADF2_1_INCTrigger184
ADF2_RADIO_TENTHS_INCTrigger185
ADF2_100_DECTrigger186
ADF2_10_DECTrigger187
ADF2_1_DECTrigger188
ADF2_RADIO_TENTHS_DECTrigger189
ADF2_WHOLE_INCTrigger190
ADF2_WHOLE_DECTrigger191
ADF2_FRACT_DEC_CARRYTrigger192
ADF2_FRACT_INC_CARRYTrigger193
ADF2_COMPLETE_SETSetValue194
RADIO_ADF2_IDENT_DISABLETrigger195
RADIO_ADF2_IDENT_ENABLETrigger196
RADIO_ADF2_IDENT_TOGGLETrigger197
RADIO_ADF2_IDENT_SETSetValue200
XPNDR_1000_INCTrigger171
XPNDR_100_INCTrigger172
XPNDR_10_INCTrigger173
XPNDR_1_INCTrigger174
XPNDR_1000_DECTrigger175
XPNDR_100_DECTrigger176
XPNDR_10_DECTrigger177
XPNDR_1_DECTrigger178
XPNDR_SETSetValue201
AVIONICS_MASTER_1_SETSetValueBool402
AVIONICS_MASTER_1_SETSetValueBool401
AVIONICS_MASTER_2_SETSetValueBool404
AVIONICS_MASTER_2_SETSetValueBool403
BAT_1_ONTrigger0
BAT_2_ONTrigger0
BAT_1_OFFTrigger0
BAT_2_OFFTrigger0
PARKING_BRAKESTrigger420
TOGGLE_MASTER_1_BATTERYTrigger0
TOGGLE_MASTER_2_BATTERYTrigger0
TOGGLE_EXTERNAL_POWERTrigger408
TOGGLE_MASTER_BATTERYTrigger405
TOGGLE_MASTER_BATTERY_ALTERNATORTrigger407
G1000_MFD_ZOOMIN_BUTTONTrigger0
G1000_MFD_ZOOMOUT_BUTTONTrigger0
AP_MASTERTrigger301
AP_PANEL_HEADING_HOLDTrigger302
AP_PANEL_ALTITUDE_HOLDTrigger303
AP_ATT_HOLD_ONTrigger304
AP_LOC_HOLD_ONTrigger305
AP_APR_HOLD_ONTrigger306
AP_HDG_HOLD_ONTrigger307
AP_ALT_HOLD_ONTrigger308
AP_WING_LEVELER_ONTrigger309
AP_BC_HOLD_ONTrigger310
AP_NAV1_HOLD_ONTrigger311
AP_ATT_HOLD_OFFTrigger312
AP_LOC_HOLD_OFFTrigger313
AP_APR_HOLD_OFFTrigger314
AP_HDG_HOLD_OFFTrigger315
AP_ALT_HOLD_OFFTrigger316
AP_WING_LEVELER_OFFTrigger317
AP_BC_HOLD_OFFTrigger318
AP_NAV1_HOLD_OFFTrigger319
AP_AIRSPEED_HOLDTrigger320
AP_PANEL_SPEED_HOLDTrigger321
AP_ALT_VAR_INCTrigger322
AP_ALT_VAR_DECTrigger323
AP_VS_VAR_INCTrigger324
AP_VS_VAR_DECTrigger325
AP_SPD_VAR_INCTrigger326
AP_SPD_VAR_DECTrigger327
AP_PANEL_MACH_HOLDTrigger328
AP_MACH_VAR_INCTrigger329
AP_MACH_VAR_DECTrigger330
AP_MACH_HOLDTrigger331
AP_ALT_VAR_SET_METRICSetValue332
AP_VS_VAR_SET_ENGLISHSetValue333
AP_SPD_VAR_SETSetValue334
AP_MACH_VAR_SETSetValue335
AP_AIRSPEED_ONTrigger336
AP_AIRSPEED_OFFTrigger337
AP_AIRSPEED_SETSetValue338
AP_MACH_ONTrigger339
AP_MACH_OFFTrigger340
AP_MACH_SETSetValue341
AP_PANEL_ALTITUDE_ONTrigger342
AP_PANEL_ALTITUDE_OFFTrigger343
AP_PANEL_ALTITUDE_SETSetValue345
AP_PANEL_HEADING_ONTrigger346
AP_PANEL_HEADING_OFFTrigger347
AP_PANEL_HEADING_SETSetValue348
AP_PANEL_MACH_ONTrigger349
AP_PANEL_MACH_OFFTrigger350
AP_PANEL_MACH_SETSetValue351
AP_PANEL_SPEED_ONTrigger352
AP_PANEL_SPEED_OFFTrigger353
AP_PANEL_SPEED_SETSetValue354
AP_ALT_VAR_SET_ENGLISHSetValue355
AP_VS_VAR_SET_METRICSetValue356
AP_PANEL_SPEED_HOLD_TOGGLETrigger357
AP_PANEL_MACH_HOLD_TOGGLETrigger358
AP_NAV_SELECT_SETSetValue359
AP_PITCH_REF_INC_UPTrigger360
AP_PITCH_REF_INC_DNTrigger361
AP_PITCH_REF_SELECTTrigger362
AP_ATT_HOLDTrigger304
AP_LOC_HOLDTrigger364
AP_APR_HOLDTrigger365
AP_HDG_HOLDTrigger366
AP_ALT_HOLDTrigger367
AP_WING_LEVELERTrigger368
AP_BC_HOLDTrigger369
AP_NAV1_HOLDTrigger370
HEADING_BUG_INCTrigger371
HEADING_BUG_DECTrigger372
TOGGLE_FLIGHT_DIRECTORTrigger373
AP_VS_HOLDTrigger374
KOHLSMAN_INCTrigger375
KOHLSMAN_DECTrigger376
KOHLSMAN_SETSetValue377
AUTO_THROTTLE_ARMTrigger378
AUTO_THROTTLE_TO_GATrigger379
FLAPS_UPTrigger501
FLAPS_1Trigger502
FLAPS_2Trigger503
FLAPS_3Trigger504
FLAPS_DOWNTrigger505
FLAPS_INCRTrigger506
FLAPS_DECRTrigger507
AXIS_FLAPS_SETSetValue0
PITOT_HEAT_TOGGLETrigger508
PITOT_HEAT_ONTrigger509
PITOT_HEAT_OFFTrigger510
MAGNETOTrigger511
MAGNETO_DECRTrigger512
MAGNETO_INCRTrigger513
MAGNETO1_OFFTrigger514
MAGNETO1_RIGHTTrigger515
MAGNETO1_LEFTTrigger516
MAGNETO1_BOTHTrigger517
MAGNETO1_STARTTrigger518
MAGNETO2_OFFTrigger519
MAGNETO2_RIGHTTrigger520
MAGNETO2_LEFTTrigger521
MAGNETO2_BOTHTrigger522
MAGNETO2_STARTTrigger523
MAGNETO3_OFFTrigger524
MAGNETO3_RIGHTTrigger525
MAGNETO3_LEFTTrigger526
MAGNETO3_BOTHTrigger527
MAGNETO3_STARTTrigger528
MAGNETO4_OFFTrigger529
MAGNETO4_RIGHTTrigger530
MAGNETO4_LEFTTrigger531
MAGNETO4_BOTHTrigger532
MAGNETO4_STARTTrigger533
MAGNETO_OFFTrigger534
MAGNETO_RIGHTTrigger535
MAGNETO_LEFTTrigger536
MAGNETO_BOTHTrigger537
MAGNETO_STARTTrigger538
MAGNETO1_DECRTrigger539
MAGNETO1_INCRTrigger540
MAGNETO2_DECRTrigger541
MAGNETO2_INCRTrigger542
MAGNETO3_DECRTrigger543
MAGNETO3_INCRTrigger544
MAGNETO4_DECRTrigger545
MAGNETO4_INCRTrigger546
MAGNETO_SETSetValue547
MAGNETO1_SETSetValue548
MAGNETO2_SETSetValue549
MAGNETO3_SETSetValue550
MAGNETO4_SETSetValue551
ANTI_ICE_ONTrigger552
ANTI_ICE_OFFTrigger553
ANTI_ICE_SETSetValue554
ANTI_ICE_TOGGLETrigger555
ANTI_ICE_TOGGLE_ENG1Trigger556
ANTI_ICE_TOGGLE_ENG2Trigger557
ANTI_ICE_TOGGLE_ENG3Trigger558
ANTI_ICE_TOGGLE_ENG4Trigger559
ANTI_ICE_SET_ENG1SetValue560
ANTI_ICE_SET_ENG2SetValue561
ANTI_ICE_SET_ENG3SetValue562
ANTI_ICE_SET_ENG4SetValue563
TOGGLE_FUEL_VALVE_ALLTrigger564
TOGGLE_FUEL_VALVE_ENG1Trigger565
TOGGLE_FUEL_VALVE_ENG2Trigger566
TOGGLE_FUEL_VALVE_ENG3Trigger567
TOGGLE_FUEL_VALVE_ENG4Trigger568
FUEL_SELECTOR_OFFTrigger569
FUEL_SELECTOR_ALLTrigger570
FUEL_SELECTOR_LEFTTrigger571
FUEL_SELECTOR_RIGHTTrigger572
FUEL_SELECTOR_LEFT_AUXTrigger573
FUEL_SELECTOR_RIGHT_AUXTrigger574
FUEL_SELECTOR_CENTERTrigger575
FUEL_SELECTOR_SETSetValue576
FUEL_SELECTOR_2_OFFTrigger577
FUEL_SELECTOR_2_ALLTrigger578
FUEL_SELECTOR_2_LEFTTrigger579
FUEL_SELECTOR_2_RIGHTTrigger580
FUEL_SELECTOR_2_LEFT_AUXTrigger581
FUEL_SELECTOR_2_RIGHT_AUXTrigger582
FUEL_SELECTOR_2_CENTERTrigger583
FUEL_SELECTOR_2_SETSetValue584
FUEL_SELECTOR_3_OFFTrigger585
FUEL_SELECTOR_3_ALLTrigger586
FUEL_SELECTOR_3_LEFTTrigger587
FUEL_SELECTOR_3_RIGHTTrigger588
FUEL_SELECTOR_3_LEFT_AUXTrigger589
FUEL_SELECTOR_3_RIGHT_AUXTrigger590
FUEL_SELECTOR_3_CENTERTrigger591
FUEL_SELECTOR_3_SETSetValue592
FUEL_SELECTOR_4_OFFTrigger593
FUEL_SELECTOR_4_ALLTrigger594
FUEL_SELECTOR_4_LEFTTrigger595
FUEL_SELECTOR_4_RIGHTTrigger596
FUEL_SELECTOR_4_LEFT_AUXTrigger597
FUEL_SELECTOR_4_RIGHT_AUXTrigger598
FUEL_SELECTOR_4_CENTERTrigger599
FUEL_SELECTOR_4_SETSetValue600
CROSS_FEED_OPENTrigger601
CROSS_FEED_TOGGLETrigger602
CROSS_FEED_OFFTrigger603
G1000_PFD_ZOOMIN_BUTTONTrigger251
G1000_PFD_ZOOMOUT_BUTTONTrigger250
ELEV_TRIM_DNTrigger604
DOWNTrigger605
ELEV_TRIM_UPTrigger606
ELEV_UPTrigger607
SPOILERS_ARM_TOGGLETrigger608
SPOILERS_ONTrigger609
SPOILERS_OFFTrigger610
SPOILERS_ARM_ONTrigger611
SPOILERS_ARM_OFFTrigger612
AILERON_TRIM_LEFTTrigger613
AILERON_TRIM_RIGHTTrigger614
RUDDER_TRIM_LEFTTrigger615
RUDDER_TRIM_RIGHTTrigger616
COWLFLAP1_SETSetValue617
COWLFLAP2_SETSetValue618
COWLFLAP3_SETSetValue619
COWLFLAP4_SETSetValue620
INC_COWL_FLAPSTrigger621
DEC_COWL_FLAPSTrigger622
DEC_COWL_FLAPS1Trigger624
INC_COWL_FLAPS1Trigger623
DEC_COWL_FLAPS2Trigger626
DEC_COWL_FLAPS3Trigger628
DEC_COWL_FLAPS4Trigger630
INC_COWL_FLAPS2Trigger625
INC_COWL_FLAPS3Trigger627
INC_COWL_FLAPS4Trigger629
FUEL_PUMPTrigger631
TOGGLE_ELECT_FUEL_PUMPTrigger632
TOGGLE_ELECT_FUEL_PUMP1Trigger634
TOGGLE_ELECT_FUEL_PUMP2Trigger636
TOGGLE_ELECT_FUEL_PUMP3Trigger638
TOGGLE_ELECT_FUEL_PUMP4Trigger640
ENGINE_PRIMERTrigger637
TOGGLE_PRIMERTrigger638
TOGGLE_PRIMER1Trigger639
TOGGLE_PRIMER2Trigger640
TOGGLE_PRIMER3Trigger641
TOGGLE_PRIMER4Trigger642
TOGGLE_FEATHER_SWITCHESTrigger643
TOGGLE_FEATHER_SWITCH_1Trigger644
TOGGLE_FEATHER_SWITCH_2Trigger645
TOGGLE_FEATHER_SWITCH_3Trigger646
TOGGLE_FEATHER_SWITCH_4Trigger647
TOGGLE_PROPELLER_SYNCTrigger648
TOGGLE_AUTOFEATHER_ARMTrigger649
TOGGLE_AFTERBURNERTrigger650
TOGGLE_AFTERBURNER1Trigger651
TOGGLE_AFTERBURNER2Trigger652
TOGGLE_AFTERBURNER3Trigger653
TOGGLE_AFTERBURNER4Trigger654
ENGINETrigger655
SPOILERS_TOGGLETrigger656
TOGGLE_STARTER1Trigger657
TOGGLE_STARTER2Trigger658
TOGGLE_STARTER3Trigger659
TOGGLE_STARTER4Trigger660
TOGGLE_ALL_STARTERSTrigger661
ENGINE_AUTO_STARTTrigger662
ENGINE_AUTO_SHUTDOWNTrigger663
FUEL_SELECTOR_LEFT_MAINTrigger664
FUEL_SELECTOR_2_LEFT_MAINTrigger665
FUEL_SELECTOR_3_LEFT_MAINTrigger666
FUEL_SELECTOR_4_LEFT_MAINTrigger667
FUEL_SELECTOR_RIGHT_MAINTrigger668
FUEL_SELECTOR_2_RIGHT_MAINTrigger669
FUEL_SELECTOR_3_RIGHT_MAINTrigger670
FUEL_SELECTOR_4_RIGHT_MAINTrigger671
APU_STARTERTrigger672
APU_OFF_SWITCHTrigger673
APU_GENERATOR_SWITCH_TOGGLETrigger674
CABIN_NO_SMOKING_ALERT_SWITCH_TOGGLETrigger675
STROBES_TOGGLETrigger677
CABIN_SEATBELTS_ALERT_SWITCH_TOGGLETrigger676
ALL_LIGHTS_TOGGLETrigger678
PANEL_LIGHTS_TOGGLETrigger679
LANDING_LIGHTS_TOGGLETrigger680
LANDING_LIGHT_UPTrigger681
LANDING_LIGHT_DOWNTrigger682
LANDING_LIGHT_LEFTTrigger683
LANDING_LIGHT_RIGHTTrigger684
LANDING_LIGHT_HOMETrigger685
STROBES_ONTrigger686
STROBES_OFFTrigger687
PANEL_LIGHTS_ONTrigger688
PANEL_LIGHTS_OFFTrigger689
LANDING_LIGHTS_ONTrigger690
LANDING_LIGHTS_OFFTrigger691
TOGGLE_BEACON_LIGHTSTrigger692
TOGGLE_TAXI_LIGHTSTrigger693
TOGGLE_LOGO_LIGHTSTrigger694
TOGGLE_RECOGNITION_LIGHTSTrigger695
TOGGLE_WING_LIGHTSTrigger696
TOGGLE_NAV_LIGHTSTrigger697
TOGGLE_CABIN_LIGHTSTrigger698
GEAR_UPTrigger699
GEAR_DOWNTrigger700
TOGGLE_STRUCTURAL_DEICETrigger701
TOGGLE_PROPELLER_DEICETrigger702
TOGGLE_ALTERNATOR1Trigger703
TOGGLE_ALTERNATOR2Trigger704
TOGGLE_ALTERNATOR3Trigger705
TOGGLE_ALTERNATOR4Trigger706
ATCTrigger707
ATC_MENU_1Trigger708
ATC_MENU_2Trigger709
ATC_MENU_3Trigger710
ATC_MENU_4Trigger711
ATC_MENU_5Trigger712
ATC_MENU_6Trigger713
ATC_MENU_7Trigger714
ATC_MENU_8Trigger715
ATC_MENU_9Trigger716
ATC_MENU_0Trigger717
EGT1_INCTrigger718
EGT1_DECTrigger719
EGT2_INCTrigger720
EGT2_DECTrigger721
EGT3_INCTrigger722
EGT3_DECTrigger723
EGT4_INCTrigger724
EGT4_DECTrigger725
EGT_INCTrigger726
EGT_DECTrigger727
TOGGLE_GPS_DRIVES_NAV1Trigger728
GPS_POWER_BUTTONTrigger729
GPS_NEAREST_BUTTONTrigger730
GPS_OBS_BUTTONTrigger731
GPS_MSG_BUTTONTrigger732
GPS_MSG_BUTTON_DOWNTrigger733
GPS_MSG_BUTTON_UPTrigger734
GPS_FLIGHTPLAN_BUTTONTrigger735
GPS_TERRAIN_BUTTONTrigger736
GPS_PROCEDURE_BUTTONTrigger737
GPS_ZOOMIN_BUTTONTrigger738
GPS_ZOOMOUT_BUTTONTrigger739
GPS_DIRECTTO_BUTTONTrigger740
GPS_MENU_BUTTONTrigger741
GPS_CLEAR_BUTTONTrigger742
GPS_CLEAR_ALL_BUTTONTrigger743
GPS_CLEAR_BUTTON_DOWNTrigger744
GPS_CLEAR_BUTTON_UPTrigger745
GPS_ENTER_BUTTONTrigger746
GPS_CURSOR_BUTTONTrigger747
GPS_GROUP_KNOB_INCTrigger748
GPS_GROUP_KNOB_DECTrigger749
GPS_PAGE_KNOB_INCTrigger750
GPS_PAGE_KNOB_DECTrigger751
YAW_DAMPER_TOGGLETrigger752
AP_MAX_BANK_INCTrigger803
AP_MAX_BANK_DECTrigger804
GYRO_DRIFT_INCTrigger805
GYRO_DRIFT_DECTrigger806
TRUE_AIRSPEED_CAL_INCTrigger807
TRUE_AIRSPEED_CAL_DECTrigger808
DECREASE_DECISION_HEIGHTTrigger809
INCREASE_DECISION_HEIGHTTrigger810
SIM_PAUSE_ONTrigger908
SIM_PAUSE_OFFTrigger909

Outputs

In this chapter we'll go over the information needed to retrieve data from Microsoft Flight Simulator 2020 and send it to your controller. The simulator requires us to indicate which data we want to subscribe to. This enables us to only focus on the relevant data without having to filter out unwanted data. It would be a waste of logic having to handle your indicated altitude when you only want to access the latest nav frequency. That is why the first step will be to create a bundle of outputs. //TODO: link to pages i.e. custom events

Bundle creation

A bundle is a group of outputs that tell the connector which data to request from the simulator. To receive data on your controller we first have to create a bundle. It's recommended to create a bundle for each controller that you want to connect. Let's go over the steps required to receive your indicated altitude and the current com frequency 1.

  1. Go to the bundle menu (in the top navbar events -> bundle settings)
  2. Click the green encircled + button to create your first bundle
  3. Give it a descriptive name
  4. Your new bundle should now appear in the available bundles
  5. Click the pencil on the right side of your new bundle
  6. Navigate to the Nav and Coms tab
  7. Select com active frequency 1
  8. Navigate to the instruments tab
  9. Select indicated altitude
  10. Hit the save icon next to the title of your bundle

//TODO: Add images

In this example we've created a rather minimalistic set. If your use case requires different events you now know where to look.

Starting the connection

Each controller can subscribe to a single bundle. On the other hand multiple controllers are able to subscribe to the same bundle. But in order for the connector to send the right data to the right controller we have to link them together. This will be done from the home screen. Lets go over the steps required to send your first data.

  1. From the home screen select your controller from the com port selector.
  2. Select your newly created bundle in the bundle column.
  3. Press the green start button

If you've already connected multiple controllers that you'd like to connect you can add a new row by clicking the green add button. Repeat these steps for the amount of controllers required.

//TODO: Add images

Receiving the data

Now we've got everything setup to transmit data we need to setup the receiver. In this example we will connect an I2C LCD screen to our controller in order to display our data.

#include <BitsAndDroidsFlightConnector.h>
#include <LiquidCrystal_I2C.h>

BitsAndDroidsFlightConnector conn = BitsAndDroidsFlightConnector();
LiquidCrystal_I2C lcd(0x27,20,4);

long currentActiveCom = 0;
int currentIndicatedAltitude = 0;

void setup() {
  lcd.init();
  lcd.backlight();
  Serial.begin(115200);
}

void displayCom1(long com){
  lcd.setCursor(0,0);
  lcd.print(com);
}

void displayIndicatedAlt(int alt){
  lcd.setCursor(0,1);
  lcd.print(alt);
}

void loop() {
  //This polls the serial line for incomming messages
  conn.dataHandling();
  long activeCom = conn.getActiveCom1();
  int  indicatedAltitude = conn.getIndicatedAltitude();

  if (activeCom != currentActiveCom){
    currentActiveCom = activeCom;
    displayCom1(activeCom);
  }
  if (currentIndicatedAltitude != indicatedAltitude){
    currentIndicatedAltitude = indicatedAltitude;
    displayIndicatedAlt(indicatedAltitude);
  }
}

Outputs

SimvarMetricUpdate EveryCallback TextIdOutput TypeCategory
AMBIENT PRESSUREinHG0.01Ambient pressure650INHGEnvironment
AMBIENT TEMPERATURECelsius0.1Ambient temperature651Float2DecPlacesEnvironment
AMBIENT WIND VELOCITYKnots0.1Ambient wind velocity652Float1DecPlacesEnvironment
AMBIENT WIND DIRECTIONDegrees1Ambient wind direction653IntegerEnvironment
AMBIENT PRECIP RATEmillimeters of water1Ambient precipitation rate654IntegerEnvironment
THROTTLE LOWER LIMITPercent Over 1000.01Throttle lower limit655PercentageEngines
PLANE HEADING DEGREES GYRODegrees0.1plane heading degrees gyro656IntegerData
PLANE HEADING DEGREES MAGNETICRadians0.01plane heading degrees magnetic657DegreesData
PLANE HEADING DEGREES TRUERadians0.01Plane heading degrees true658DegreesData
INDICATED_ALTITUDE_CALIBRATEDFeet1Indicated altitude calibrated659IntegerInstruments
FUEL SELECTED QUANTITY PERCENTPercent Over 1000.01Fuel quantity %275PercentageFuel
AUTOPILOT AIRSPEED HOLD VARknots0AP airspeed var700IntegerFuel
FUEL TANK CENTER LEVELPercent Over 1000.01Fuel tank center level234PercentageFuel
FUEL TANK CENTER2 LEVELPercent Over 1000.01Fuel tank center 2 level235PercentageFuel
FUEL TANK CENTER3 LEVELPercent Over 1000.01Fuel tank center 3 level236PercentageFuel
FUEL TANK LEFT MAIN LEVELPercent Over 1000.01Fuel tank left main level237PercentageFuel
FUEL TANK LEFT AUX LEVELPercent Over 1000.01Fuel tank left aux level238PercentageFuel
FUEL TANK LEFT TIP LEVELPercent Over 1000.01Fuel tank left tip level239PercentageFuel
FUEL TANK RIGHT MAIN LEVELPercent Over 1000.01Fuel tank right main level240PercentageFuel
FUEL TANK RIGHT AUX LEVELPercent Over 1000.01Fuel tank right aux level241PercentageFuel
FUEL TANK RIGHT TIP LEVELPercent Over 1000.01Fuel tank right tip level242PercentageFuel
FUEL TANK EXTERNAL1 LEVELPercent Over 1000.01Fuel tank external 1 level243PercentageFuel
FUEL TANK EXTERNAL2 LEVELPercent Over 1000.01Fuel tank external 2 level244PercentageFuel
FUEL TANK CENTER CAPACITYGallons1Fuel tank center capacity245IntegerFuel
FUEL TANK CENTER2 CAPACITYGallons1Fuel tank center 2 capacity246IntegerFuel
FUEL TANK CENTER3 CAPACITYGallons1Fuel tank center 3 capacity247IntegerFuel
FUEL TANK LEFT MAIN CAPACITYGallons1Fuel tank left main capacity248IntegerFuel
FUEL TANK LEFT AUX CAPACITYGallons1Fuel tank left aux capacity249IntegerFuel
FUEL TANK LEFT TIP CAPACITYGallons1Fuel tank left tip capacity250IntegerFuel
FUEL TANK RIGHT MAIN CAPACITYGallons1Fuel tank right main capacity251IntegerFuel
FUEL TANK RIGHT AUX CAPACITYGallons1Fuel tank right aux capacity252IntegerFuel
FUEL TANK RIGHT TIP CAPACITYGallons1Fuel tank right tip capacity253IntegerFuel
FUEL TANK EXTERNAL1 CAPACITYGallons1Fuel tank external 1 capacity254IntegerFuel
FUEL TANK EXTERNAL2 CAPACITYGallons1Fuel tank external 2 capacity255IntegerFuel
FUEL LEFT CAPACITYGallons1Fuel left capacity256IntegerFuel
FUEL RIGHT CAPACITYGallons1Fuel right capacity257IntegerFuel
FUEL TANK CENTER QUANTITYGallons1Fuel tank center quantity258IntegerFuel
FUEL TANK CENTER2 QUANTITYGallons1Fuel tank center 2 quantity259IntegerFuel
FUEL TANK CENTER3 QUANTITYGallons1Fuel tank center 3 quantity260IntegerFuel
FUEL TANK LEFT MAIN QUANTITYGallons1Fuel tank left main quantity261IntegerFuel
FUEL TANK LEFT AUX QUANTITYGallons1Fuel tank left aux quantity262IntegerFuel
FUEL TANK LEFT TIP QUANTITYGallons1Fuel tank left tip quantity263IntegerFuel
FUEL TANK RIGHT MAIN QUANTITYGallons1Fuel tank right main quantity264IntegerFuel
FUEL TANK RIGHT AUX QUANTITYGallons1Fuel tank right aux quantity265IntegerFuel
FUEL TANK RIGHT TIP QUANTITYGallons1Fuel tank right tip quantity266IntegerFuel
FUEL TANK EXTERNAL1 QUANTITYGallons1Fuel tank external 1267IntegerFuel
FUEL TANK EXTERNAL2 QUANTITYGallons1Fuel tank external 2 quantity268IntegerFuel
FUEL LEFT QUANTITYGallons1Fuel left quantity269IntegerFuel
FUEL RIGHT QUANTITYGallons1Fuel right quantity270IntegerFuel
FUEL TOTAL QUANTITYGallons1Fuel total quantity271IntegerFuel
PLANE ALT ABOVE GROUNDFeet100Feet above ground312IntegerData
SIM ON GROUNDBool0(bool) on the ground323BooleanData
VERTICAL SPEEDFeet per second10Vertical speed330IntegerData
TITLENULL0Plane name999PercentageData
BAROMETER PRESSUREMillibars10Barometer pressure632IntegerInstruments
AIRSPEED INDICATEDKnots1Indicated airspeed326IntegerInstruments
HEADING INDICATORRadians0.02Indicated heading344DegreesInstruments
VARIOMETER RATEFeet per minute10Vario rate345IntegerInstruments
INDICATED ALTITUDEFeet10Indicated altitude335IntegerInstruments
INDICATED ALTITUDE:2Feet10indicated altitude336IntegerInstruments
KOHLSMAN SETTING HGinHg0Kohlsman HG337INHGInstruments
LOCAL TIMESeconds1Local time338SecondsAfterMidnightData
TIME ZONE OFFSETSeconds1Zulu time339IntegerData
ZULU TIMESeconds1Zulu time340SecondsAfterMidnightData
GPS GROUND SPEEDMeters per second1GPS groundspeed430MetersPerSecondToKnotsGPS
GPS WP BEARINGDegrees1GPS course to steer454IntegerGPS
AUTOPILOT HEADING LOCK DIRDegrees0AP heading lock582IntegerAutopilot
AUTOPILOT ALTITUDE LOCK VARFeet0AP altitude lock var584IntegerAutopilot
AUTOPILOT VERTICAL HOLD VARFeet/minute0AP vertical hold var590IntegerAutopilot
AUTOPILOT AVAILABLEBool0(bool) AP available576BooleanAutopilot
AUTOPILOT MASTERBool0(bool) AP master577BooleanAutopilot
AUTOPILOT WING LEVELERBool0(bool) AP wing leveler579BooleanAutopilot
AUTOPILOT HEADING LOCKBool0(bool) AP heading lock581BooleanAutopilot
AUTOPILOT ALTITUDE LOCKBool0(bool) AP altitude lock583BooleanAutopilot
AUTOPILOT ATTITUDE HOLDBool0(bool) AP attitude lock585BooleanAutopilot
AUTOPILOT GLIDESLOPE HOLDBool0(bool) AP glideslope hold586BooleanAutopilot
AUTOPILOT APPROACH HOLDBool0(bool) AP approach hold588BooleanAutopilot
AUTOPILOT BACKCOURSE HOLDBool0(bool) AP backcourse hold589BooleanAutopilot
AUTOPILOT FLIGHT DIRECTOR ACTIVEBool0(bool) AP flight director591BooleanAutopilot
AUTOPILOT AIRSPEED HOLDBool0(bool) AP airspeed hold594BooleanAutopilot
AUTOPILOT MACH HOLDBool0(bool) AP mach hold596BooleanAutopilot
AUTOPILOT YAW DAMPERBool0(bool) AP yaw damper598BooleanAutopilot
AUTOPILOT THROTTLE ARMBool0(bool) AP throttle arm600BooleanAutopilot
AUTOPILOT TAKEOFF POWER ACTIVEBool0(bool) AP takeoff power601BooleanAutopilot
AUTOTHROTTLE ACTIVEBool0(bool) Autothrottle602BooleanAutopilot
AUTOPILOT NAV1 LOCKBool0(bool) AP NAV1 lock580BooleanAutopilot
AUTOPILOT VERTICAL HOLDBool0(bool) AP vertical hold604BooleanAutopilot
AUTOPILOT RPM HOLDBool0(bool) AP RPM hold605BooleanAutopilot
COM ACTIVE FREQUENCY:1Khz0Com 1 active900IntegerNAV and COMS
COM ACTIVE FREQUENCY:2Khz0Com 2 active902IntegerNAV and COMS
COM STANDBY FREQUENCY:1Khz0Com 1 standby901IntegerNAV and COMS
COM STANDBY FREQUENCY:2Khz0Com 2 standby903IntegerNAV and COMS
NAV ACTIVE FREQUENCY:1KHz0NAV 1 active910IntegerNAV and COMS
NAV STANDBY FREQUENCY:1KHz0NAV 1 standby911IntegerNAV and COMS
NAV ACTIVE FREQUENCY:2KHz0NAV 2 active912IntegerNAV and COMS
NAV STANDBY FREQUENCY:2KHz0NAV 2 standby913IntegerNAV and COMS
NAV RADIAL ERROR:1Degrees0NAV 1 radial error914IntegerNAV and COMS
NAV VOR LATLONALT:1SIMCONNECT_DATA_LATLONALT0Nav 1 VOR LATLONALT915IntegerNAV and COMS
ADF ACTIVE FREQUENCY:1Hz0ADF 1 active954ADFNAV and COMS
ADF STANDBY FREQUENCY:1Hz0ADF 1 standby955ADFNAV and COMS
ADF RADIAL:1Degrees0ADF 1 radial956IntegerNAV and COMS
ADF SIGNAL:1Number0ADF 1 signal957IntegerNAV and COMS
ADF ACTIVE FREQUENCY:2Hz0ADF 2 active958ADFNAV and COMS
ADF STANDBY FREQUENCY:2Hz0ADF 2 standby959ADFNAV and COMS
ADF RADIAL:2Degrees0ADF 2 radial960IntegerNAV and COMS
ADF SIGNAL:2Number0ADF 2 signal961IntegerNAV and COMS
NAV DME:1Nautical miles0NAV DME 1950IntegerNAV and COMS
NAV DMESPEED:1Knots0NAV DME 1 speed951IntegerNAV and COMS
NAV DME:2Nautical miles0NAV DME 2952IntegerNAV and COMS
NAV DMESPEED:2Knots0NAV DME 2 speed953IntegerNAV and COMS
TRANSPONDER CODE:1number0Transponder 1 code962IntegerNAV and COMS
TRANSPONDER CODE:2number0Transponder 2 code963IntegerNAV and COMS
NAV OBS:1Degrees0.1NAV OBS 1606IntegerNAV and COMS
NAV OBS:2Degrees0.1NAV OBS 2607IntegerNAV and COMS
TRANSPONDER IDENT:1Bool0Transponder ident 1608IntegerNAV and COMS
TRANSPONDER STATE:1Enum0Transponder state 1609IntegerNAV and COMS
TRANSPONDER IDENT:2Bool0Transponder ident 2610IntegerNAV and COMS
TRANSPONDER STATE:2Enum0Transponder state 2611IntegerNAV and COMS
LIGHT TAXI ONBool0(bool) Taxi lights133BooleanLights
LIGHT STROBE ONBool0(bool) Strobe lights134BooleanLights
LIGHT PANEL ONBool0(bool) Panel lights135BooleanLights
LIGHT RECOGNITION ONBool0(bool) Recognition lights136BooleanLights
LIGHT WING ONBool0(bool) Wing lights137BooleanLights
LIGHT LOGO ONBool0(bool) Logo lights138BooleanLights
LIGHT CABIN ONBool0(bool) Cabin lights139BooleanLights
LIGHT HEAD ONBool0(bool) Head light140BooleanLights
LIGHT BRAKE ONBool0(bool) Brake lights (not the brakes!)141BooleanLights
LIGHT NAV ONBool0(bool) NAV lights142BooleanLights
LIGHT BEACON ONBool0(bool) Beacon lights143BooleanLights
LIGHT LANDING ONBool0(bool) Landing lights144BooleanLights
STALL WARNINGBool0(bool) Stall warning333BooleanWarnings
OVERSPEED WARNINGBool0(bool) Overspeed warning334BooleanWarnings
BRAKE PARKING INDICATORBool0(bool) Parking brake indicator505BooleanMechanical
AILERON TRIMRadians0Aileron trim degrees562DegreesMechanical
AILERON TRIM PCTPercent Over 1000.01Aileron trim %563PercentageMechanical
RUDDER TRIMRadians0.01Rudder trim degrees566DegreesMechanical
RUDDER TRIM PCTPercent Over 1000.01Rudder trim %567PercentageMechanical
ELEVATOR TRIM POSITIONRadians0.01Elevator trim position degrees498DegreesMechanical
ELEVATOR TRIM PCTPercent Over 1000.01Elevator trim %500PercentageMechanical
FLAPS HANDLE PERCENTPercent Over 1000.01Flaps handle %510PercentageMechanical
FLAPS HANDLE INDEXNumber0Flaps handle index511IntegerMechanical
FLAPS NUM HANDLE POSITIONSNumber0Flaps number handle positions512IntegerMechanical
TRAILING EDGE FLAPS LEFT PERCENTPercent Over 1000.01Trailing edge flaps left %513PercentageMechanical
TRAILING EDGE FLAPS RIGHT PERCENTPercent Over 1000.01Trailing edge flaps right %514PercentageMechanical
TRAILING EDGE FLAPS LEFT ANGLERadians0.01Trailing edge flaps left degrees515DegreesMechanical
TRAILING EDGE FLAPS RIGHT ANGLERadians0.01Trailing edge flaps right degree516DegreesMechanical
LEADING EDGE FLAPS LEFT PERCENTPercent Over 1000.01Leading edge flaps left %517PercentageMechanical
LEADING EDGE FLAPS RIGHT PERCENTPercent Over 1000.01Leading edge flaps right %518PercentageMechanical
LEADING EDGE FLAPS LEFT ANGLERadians0.01Leading edge flaps left degrees519DegreesMechanical
LEADING EDGE FLAPS RIGHT ANGLERadians0.01Leading edge flaps right degrees520DegreesMechanical
GEAR HANDLE POSITIONBool0(bool) Gear handle position526BooleanMechanical
GEAR HYDRAULIC PRESSUREpsf1Gear hydraulic pressure527IntegerMechanical
TAILWHEEL LOCK ONBool0(bool) Tailwheel lock528BooleanMechanical
GEAR CENTER POSITIONPercent Over 1000.01Gear center position %529PercentageMechanical
GEAR LEFT POSITIONPercent Over 1000.01Gear left position %530PercentageMechanical
GEAR RIGHT POSITIONPercent Over 1000.01Gear right position %531PercentageMechanical
GEAR TAIL POSITIONPercent Over 1000.01Gear tail position %532PercentageMechanical
GEAR AUX POSITIONPercent Over 1000.01Gear AUX position %533PercentageMechanical
GEAR TOTAL PCT EXTENDEDPercentage0.01Gear total extended %536PercentageMechanical

Presets

Presets are a way to save multiple device configurations for flight simmers that want to match their setup to their needs. This makes it simple to swap your devices when you switch your airliner for a general aviation plane. In short, each preset contains one or multiple bundles (A bundle is a device matched with the outputs it needs to receive) that can be saved as a set.

connector_presets.png

Your presets can be managed from the home screen. From here, you can create, save, and edit them. Your first preset will be called (what a coincidence) default by default. You’re able to alter this preset to your heart’s desire.

preset_controls.png

Create a preset

If you want to create a new preset, press the Create new preset button. This prompts you to enter a fitting name. The connector will save the new empty preset to your settings. It will also be selected as the current active preset. To ensure you’re using the correct set, you should see the name of your new set in the dropdown menu. If you hit start for the first time using your new preset, the connector will save the set as the last active preset. If you start the connector, your last preset will be reinstated. The connector defaults to the first available device if the device isn't connected. If this happens, the alternate device won’t be saved to memory unless you manually press the save preset button.

Edit a preset

You can edit your presets by changing the run configuration by adding and removing rows, changing devices, and altering the bundles. Remember to save your changes before changing the preset you’ve equipped.

These changes will automatically be saved when you make changes

Delete a preset

You're able to remove a preset from the manage preset page.

  • Click on settings in the main menu
  • Navigate to the Manage presets page
  • Click on the trashcan to delete the preset

You're not able to delete the default preset

Edit preset name

This is a placeholder. This functionality isn't finished yet.

Settings

In this chapter, we'll go over the connector's available settings. The settings menu can be accessed from the main menu in the settings tab.

Connection settings

These settings affect the way the connector interacts with your devices.

Enable TRS

Iputcheckbox
Typeboolean
Defaultfalse

The terminal-ready signal is a signal that can be sent to your devices when the connector connects to your controller. Specific microcontrollers like the Arduino use this signal to prepare the controller for incoming data. The behavior of this signal depends on the microcontroller manufacturer's implementation. For example, an Arduino Due uses the signal to reset the controller before establishing a serial connection.

If your microcontrollers reset, pay attention to the order of your devices. For example, the Arduino Due has 2 USB ports (programmer and default). When these ports are reset, the order in which the connectors are reset can affect whether the connection is established or dropped. For the Due, it’s recommended that the programming port be placed at the top of the connection rows.

Launch when sim starts

Iputcheckbox
Typeboolean
Defaultfalse

This settings will launch the connector when you start Microsoft Flight Simulator 2020. At the moment it just opens the application but doesn't start a connection (this is being worked on). In order to achieve this the connector adds an entry to the exe.xml file used by MFS2020. This file is located 2 levels up from the community folder. The connector uses the community folder path to navigate to this file. If no community folder path has been set the connector will ask for the path.

Logs

When tinkering with your projects, seeing what the connector does can provide valuable information.

Log window

You can use the log window to see a live stream of the logs being output. The log window can be accessed from the main menu. It shows the last 1000 log entries. The logs can fill up quite rapidly if you send a lot of data to or from your controller. If you need some breathing room to analyze the logs, you’re able to pause and resume the log stream using the pause button.

Log file

Looking for information about events that happened when the log window was closed? Don’t worry. All logs get saved to an external file as well. This provides a more accessible format to share during a bug report as well. On Windows, you can type %localappdata% in the file explorer address bar to navigate to your appdata/local folder. The log files can be found in the bitsanddroids/logs folder.

WASM

Usually, the connector communicates with MFS2020 using SimConnect. SimConnect is an interface that exposes the simulation data to other software. This interface provides an easy way to start consuming the sim data but has some downsides.

One of these downsides is that third-party developers can’t easily add functionality to this interface when they want to implement new features. The result for you as a user is that some interactions are locked in the simulator.

SimConnect flow diagram

Luckily, there is an answer to this problem! MFS2020 provides functionality that lets an add-on interact with the in-game data. Even the data that isn’t created by the add-on itself. These add-ons are called WASM (web-assembly) modules. These WASM modules live inside the simulator but can talk to the outside world using SimConnect. There are other ways these modules can communicate to the outside world, but since we’re already utilizing SimConnect, this route will be our pick.

WASM flow diagram

The great benefit of this system is that we can add more functionality to this module when necessary. That way we’re able to interact with new aircraft the moment they’re released.

Custom events

As explained in the previous chapter not all events can be accessed through SimConnect. Using the WASM module we're able to utilize a whole new set of functionalities. You're able to send data to MFS or receive data and send it to your microcontroller. Since there are more third party planes available than my wallet allows me to obtain it's not possible to add events for everyone of them to the connector. By adding custom events you're able to control event the most obscure aircraft. These events are formatted using Reverse Polish Notation. The connector calls these actions custom commands. You're able to see and edit the custom commands from the custom events menu under the events menu.

custom events

Events broken down

An event can be broken down in smaller parts.

  • ID
  • Actions
  • Description
  • Type
  • Category
  • Output format
  • Update every

ID

The ID is used to identify the event. When the event is defined as an input, you can trigger it by sending the ID to the connector. The connector will then trigger the corresponding action. When the event is defined as an output the connector will prefix the value with the ID. This makes it possible to identify the received value on your controller.

Action

The action is the event that will be triggered if the connector receives the corresponding ID or the data that MFS requests.

HubHop is a website that contains a library of events created by other simmers.

You can add logical/conditional steps into these events to create complex events. An example of a more complex event is: (A:AUTOPILOT ALTITUDE LOCK VAR, feet) - 1000 + (>K:AP_ALT_VAR_SET_ENGLISH) (>H:AP_KNOB_Down) This basically involves taking the current AP alt lock variable and subtracting 1000, assigning this value to the AP alt variable, and animating the button press. A simpler event would be 1 (>H:TRANSPONDER:1, Enum), which sets the transponder state to mode 1.

Description

Actions can become quite complex and challenging to follow. The description provides a readable description of the event. When the event is defined as an output, the description is also used as a label for the checkbox in the bundle editor.

Type

There are two types of events: inputs and outputs. Inputs are events that are triggered by an incoming message from your controller. To trigger these events, you need to send the ID to the connector. Output events define events that the connector continuously requests from the simulator. If the data changes more than the threshold (update every field), the connector sends the value to your controller, which is prefixed by the ID.

Category

You can add a category to organize your events. This will eventually be used to filter the events table (WIP). In the future, you can add more categories.

Output format

If the event is an output, the output format field will appear. This determines in which format the connector needs to return the data. Available types are:

  • Float (1.5)
  • Integer (1)
  • Time (20:10:10)
  • Boolean (true/false or 1/0)
  • String (still untested)

Update every

Update every is only applicable to outputs. This value dictates at which interval the connector needs to send data. Let’s say you want to receive the altitude of your aircraft. The simulator will send every altitude change even if it's just a few inches/millimeters. In reality, you're probably more interested in the changes per foot. To achieve this, you could set the update for every value to 1.0.

Update default events

The custom event menu has a button that says update default events. This button resets the default events or adds them if they were added to the connector after your install date. To prevent overwriting of your changes, this isn’t done automatically. In the future you’ll be able to pick and choose which events to import/reset.

Resetting the default events only reinstates the original events the connector ships with (or those added later). It won’t affect events you’ve added yourself.

Library

To make it easier to interface with the connector you're able to utilize the C++ library.

Library generator

You're able to create your own inputs and outputs in the connector. To allow this customization the connector comes with a library generator. The generator will add the outputs you've created to the library. This way the data will be routed to the correct variables in the library. Library generator menu

It's recommended to save the library to your Arduino library folder if using the Arduino IDE library generator path

Generated format

The generator will add three components:

  • variables
  • getters
  • switch cases

variables

The added variables are generated in the format output{id} i.e.: int output1000; The type can be altered by changing the output_format in the event editor.

getters

The generator adds get functions to make it easy to retrieve the latest value of the event you defined. This function is designed to retrieve the value in a consistent manner. A getter might look like this: int getOutput1000() { return getOutput1000; }

switch cases

Last but not least the generator adds switch cases. These look like this: case 1000: { output1000 = incommingValue; break; } These cases will route the incoming values to the correct variables.

PLACEHOLDER

Inputs with values

Using SimConnect with Microsoft Flight Simulator 2020 allows sending values directly to the simulator. Some examples would be:

  • Set the com frequency to 124.850
  • Set the Kohlman altitude indicator to 29.98
  • Set the nav frequency to 116.85

The format expected by the simulator might not always be the direct value. For example the Kohlman altitude indicator requires the value to be passed in Millibars multiplied by 16.

Helper functions

The library has helper functions that parse the desired values into the correct format to simplify their use.

connector.sendSetKohlmanAltimeterInHg(float value)

ExpectsThe InHg value to set i.e. 29.92 as
Value typefloat
ConvertsValue * 33.8639 (to mb) * 16
Sends“377 16211”

connector.sendSetKohlmanAltimeterMb(float value)

ExpectsThe mb value to set i.e. 1011 as
Value typefloat
ConvertsValue * 16
Sends“377 162176”

Library Functions

NameDirectionReturn TypeParameters
getFuelLevel()Outint
getVersion()OutString
getConnected()Outint
getPercentage(intOutbyte
getFeetAboveGround()Outint
getOnGround()Outbool
getApVerticalSpeed()Outint
intOutlong
getGpsCourseToSteer()Outint
getApHeadingLock()Outint
getKohlmanAltimeter()Outint
getBarPressure()Outint
getFuelTotalPercentage()Outbyte
getIndicatedAirspeed()Outint
getVarometerRate()Outint
getIndicatedAltitude()Outint
getIndicatedAltitude2()Outint
getIndicatedAltitudeCalibrated()Outint
getIndicatedHeading()Outint
getIndicatedGPSGroundspeed()Outint
getTrueVerticalSpeed()Outint
getLastPrefix();Outint
getLightTaxiOn()Outbool
getLightStrobeOn()Outbool
getLightPanelOn()Outbool
getLightRecognitionOn()Outbool
getLightWingOn()Outbool
getLightLogoOn()Outbool
getLightCabinOn()Outbool
getLightHeadOn()Outbool
getLightBrakeOn()Outbool
getLightNavOn()Outbool
getLightBeaconOn()Outbool
getLightLandingOn()Outbool
getActiveCom1()Outlong
getActiveCom2()Outlong
getStandbyCom1()Outlong
getStandbyCom2()Outlong
getActiveNav1()Outlong
getActiveNav2()Outlong
getStandbyNav1()Outlong
getStandbyNav2()Outlong
getNavRadialError1()OutString
getNavVorLationalt1()OutString
getNavObs1()Outint
getNavObs2()Outint
getStallWarningOn()Outbool
getOverspeedWarningOn()Outbool
getFlapsHandlePct()Outbyte
getFlapsHandleIndex()Outbyte
getFlapsNumHandlePos()Outbyte
getTrailingEdgeFlapsLeftPercent()Outbyte
getTrailingEdgeFlapsRightPercent()Outbyte
getTrailingEdgeFlapsLeftAngle()Outint
getTrailingEdgeFlapsRightAngle()Outint
getLeadingEdgeFlapsLeftPct()Outbyte
getLeadingEdgeFlapsRightPct()Outbyte
getLeadingEdgeFlapsLeftAngle()Outint
getLeadingEdgeFlapsRightAngle()Outint
getGearHandlePos()Outbool
getGearHydraulicPressure()Outint
getTailWheelLock()Outbool
getGearCenterPositionPct()Outbyte
getGearLeftPositionPct()Outbyte
getGearRightPositionPct()Outbyte
getGearTailPositionPct()Outbyte
getGearAuxPosition()Outbyte
getGearTotalPct()Outbyte
getAileronTrimPct()Outint
getAileronTrimDegr()Outint
getRudderTrimDegr()Outint
getRudderTrimPct()Outint
getElevatorTrimPos()Outint
getElevatorTrimPct()Outint
getNavDme1()OutString
getNavDme2()OutString
getNavDmeSpeed1()OutString
getNavDmeSpeed2()OutString
getAdfActiveFreq1()Outlong
getAdfStandbyFreq1()Outlong
getAdfRadial1()OutString
getAdfSignal1()OutString
getAdfActiveFreq2()Outlong
getAdfStandbyFreq2()Outlong
getAdfRadial2()OutString
getAdfSignal2()OutString
getTransponderCode1()OutString
getTransponderCode2()OutString
getTransponderIdent1()Outbool
getTransponderIdent2()Outbool
getTransponderState1()Outuint8_t
getTransponderState2()Outuint8_t
getAPAvailable()Outbool
getAPMasterOn()Outbool
getAPWingLevelerOn()Outbool
getAPNav1LockOn()Outbool
getAPHeadingLockOn()Outbool
getAPAltitudeLockOn()Outbool
getAPAttitudeLockOn()Outbool
getAPGlideslopeHoldOn()Outbool
getAPApproachHoldOn()Outbool
getAPBackcourseHoldOn()Outbool
getAPFlightDirectorOn()Outbool
getAPAirspeedHoldOn()Outbool
getAPMachHoldOn()Outbool
getAPYawDampenerOn()Outbool
getAPAutothrottleArm()Outbool
getAPTakeoffPowerOn()Outbool
getAPAutothrottleOn()Outbool
getAPVerticalHoldOn()Outbool
getAPRPMHoldOn()Outbool
getParkingBrakeIndicator()Outbool
getFuelTankCenterLevel()Outbyte
getFuelTankCenter2Level()Outbyte
getFuelTankCenter3Level()Outbyte
getFuelTankLeftMainLevel()Outbyte
getFuelTankLeftAuxLevel()Outbyte
getFuelTankLeftTipLevel()Outbyte
getFuelTankRightMainLevel()Outbyte
getFuelTankRightAuxLevel()Outbyte
getFuelTankRightTipLevel()Outbyte
getFuelTankExternal1Level()Outbyte
getFuelTankExternal2Level()Outbyte
getFuelTankCenter()Outint
getFuelTankCenter2()Outint
getFuelTankCenter3()Outint
getFuelTankLeftMainCapacity()Outint
getFuelTankLeftAuxCapacity()Outint
getFuelTankLeftTipCapacity()Outint
getFuelTankRightMainCapacity()Outint
getFuelTankRightAuxCapacity()Outint
getFuelTankRightTipCapacity()Outint
getFuelTankExternal1Capacity()Outint
getFuelTankExternal2Capacity()Outint
getFuelTankLeftCapacity()Outfloat
getFuelTankRightCapacity()Outfloat
getFuelTankCenterQuantity()Outint
getFuelTankCenter2Quantity()Outint
getFuelTankCenter3Quantity()Outint
getFuelTankLeftMainQuantity()Outint
getFuelTankLeftAuxQuantity()Outint
getFuelTankLeftTipQuantity()Outint
getFuelTankRightMainQuantity()Outint
getFuelTankRightAuxQuantity()Outint
getFuelTankRightTipQuantity()Outint
getFuelTankExternal1Quantity()Outint
getFuelTankExternal2Quantity()Outint
getFuelTankLeftQuantity()Outfloat
getFuelTankRightQuantity()Outfloat
getFuelTankTotalQuantity()Outint
getAmbientTemperature()Outfloat
getAmbientPressure()Outint
getAmbientWindVelocity()Outfloat
getAmbientWindDirection()Outint
getAmbientPrecipRate()Outint
getAmbientPrecipState()Outint
getHeadingGyro()Outint
getHeadingMag()Outint
getHeadingTrue()Outint
getMasterWarningOn()Outbool
getMasterCautionOn()Outbool
getPlaneName()OutString
getZuluTime()OutString
getTimezoneOffset()Outint
getLocalTime()OutString

Autpilot button example

The easiest setup to get you started is getting a pushbutton to interact with MFS2020. In this example, we'll explain everything you need to create your first project.

What you’ll need

  • A microcontroller (Arduino, ESP, Teensy, etc.).
  • A pushbutton.
  • 2 Wires (preferably 1 black and 1 colored).
  • A breadboard

Other components will work as well so feel free to experiment to your hearts desire

Wiring the components

There are multiple ways to connect the pushbutton to a microcontroller. We’ll teach you the easiest way, which utilizes the microcontroller's built-in pullup resistors.

First place the pushbutton in the middle of the breadboard so it bridges the gap in the middle. Now connect one of the wires to the ground connection on your controller and the other end to the top leg of the button (see the image below). The next step will be to connect the other leg of the button to pin 8 on your controller (you can change the pin as long as you alter the code as well).

Pullup button wiring

Writing the firmware

We need to write a small bit of code to make the controller interact with the button. Remember to make any changes if you’ve decided to connect the button to another pin.

// This is needed when using another IDE than the Arduino IDE
#include <Arduino.h>
#include <BitsAndDroidsFlightConnector.h>
// Connect the button to pin 8
#define APBTNPIN 8

// Create a connector instance
auto connector = BitsAndDroidsFlightConnector();
// To check against if the state changed
int old_btn_state = HIGH;

void setup() {
  // Start serial coms at a rate of 115200 (this can be changed later)
  Serial.begin(115200);
  // Enable the internal pullup resistors
  pinMode(APBTNPIN, INPUT_PULLUP);
}

void loop() {
  const int btn_state = digitalRead(APBTNPIN);
  // To avoid unnescesary triggers
  if (old_btn_state != btn_state){
    if(btn_state == LOW){
      // A  full list of commands can be found in the inputs chapter 
      connector.send(sendApMasterOn);
    }
    old_btn_state = btn_state;
    // Add a delay to debounce noise
    delay(200);
  }
}

Contributing

Events

In this chapter we will go over events and what to keep in mind when contributing events to the connector.

Outputs

Outputs are events that retrieve data from the simulator and get sent to your microcontroller. There are two types of outputs:

  1. Simconnect events
  2. WASM events

Simconnect events

Simconnect events are provided by Microsoft Flight Simulator. They can be subscribed to, and the simulator will send an update if the value has changed.

  {
    "simvar": "ADF ACTIVE FREQUENCY:1",
    "metric": "Hz",
    "update_every": 0,
    "cb_text": "ADF 1 active",
    "id": 954,
    "output_type": "adf",
    "category": "NAV and COMS"
  },

Simvar

The event itself is declared in the same field. This field dictates which event is subscribed to in the Simconnect SDK. Most events are documented in the Simconnect SDK docs of Microsoft Flight Simulator. In practice, some events aren't appropriately documented. The ingame dev tools can provide more information on the implementation of events.

Metric

The metric value is the value format requested from the simulator. This is usually documented in the Simconnect docs, but it's possible to experiment with different values that aren't documented. For example, events that accept Hz might also accept Khz and Mhz as metric values.

Update rate / Epsilon

The interval at which these events are transmitted can be altered using the epsilon parameter (update_every). The epsilon parameter indicates at which float interval an update has to be sent. For example, when retrieving the height, you can receive an update every 0.00001 feet, 1 foot, or 10 feet. These values can be tweaked to a sensible threshold. Currently, the threshold is set by the connector. At a later point, it will be possible for users of the connector to override these values. Try to set these values at a sensible threshold for most users. For example, most people don't need to receive a heading update every millimeter. Setting the update value to either 0.5 or 1 makes more sense.

Checkbox text

The cb_text field describes the event. This is also the text that will be displayed in the bundle editor. If necessary, this field can be postfixed with a minor description. Try to use descriptors as little as possible. The target is short and to the point.

ID

The ID field is an identifier used to identify events when transmitting them to your controllers. The reserved ID range for Simconnect events is 100-1000.

Output type

Output type dictates the registration and formatting of events. Possible values are:

            "adf" => Ok(OutputType::ADF),
            "boolean" => Ok(OutputType::Boolean),
            "integer" => Ok(OutputType::Integer),
            "float" => Ok(OutputType::Float) // Retrieved as float send as is,
            "float1decplaces" => Ok(OutputType::Float1DecPlaces) // Retrieved as float rounded to 1 dec place,
            "float2decplaces" => Ok(OutputType::Float2DecPlaces) // Retrieved as float rounded to 2 dec places,
            "seconds" => Ok(OutputType::Seconds) // Parsed to time hh:mm:ss,
            "secondsaftermidnight" => Ok(OutputType::Secondsaftermidnight) // Parsed to 15:34:15 (time of day),
            "percentage" => Ok(OutputType::Percentage) // Parsed to 80 for 80%,
            "degrees" => Ok(OutputType::Degrees) // Retrieved as radians parsed to degrees,
            "inhg" => Ok(OutputType::INHG),
            "meterspersecond" => Ok(OutputType::Meterspersecond) // retrieved as mps converted to kmh,
            "meterspersecondtoknots" => Ok(OutputType::MeterspersecondToKnots) // Retrieved as mps converted to knots,
            "string" => Ok(OutputType::String),

The first distinction is whether the output is a string or a number. Both types have separate registration logic in the connector. The second part determined by the output type is the output format. If the value is a number, the output format is determined by the type belonging to the event. In theory, the connector receives all numbers as float values. The parsing logic can be found in the sim_utils/output_converters module.

Category

The bundle edit menu categorizes outputs based on the category provided in the category field. Custom/WASM events get their own separate category. At a later point users will be able to add their own custom categories.

WASM Outputs

Third-party developers might find that the provided Simconnect events only cover some of their needs. They can expose a deeper event layer in a gauge API that the connector hooks into through a WASM module. With Simconnect events, the Simconnect SDK tells us when a new update is available. The WASM logic flow is more complex than Simconnect events. We are in complete control of the entire data flow. We ask for the current value of the event -> store that value -> check if that value is more significant than the indicated threshold/epsilon and send it to the connector. Due to this polling mechanism, there is a slight chance we miss certain intervals of fast-changing values (but the current value will always reflect the latest and up-to-date value).

    {
      "id": 1000,
      "action": "(L:Generic_Master_Caution_Active)",
      "action_text": "Master caution on",
      "action_type": "output",
      "output_format": "time",
      "update_every": 0.0,
      "min": 0.0,
      "max": 100.0,
      "plane_or_category": "generic"
    },

ID ranges

The ID ranges currently are scattered everywhere, coming from the previous connector. In an attempt to organize the events, I'm working on an update that might change the current IDs of WASM events. The reserved ID range is, therefore, still being contemplated. For contributors of the FBW and PMDG sets, the below-mentioned ranges can be seen as final.

Please note the following text:

Custom WebAssembly (WASM) events can be provided as a base set by the connector or as custom events by users. The base set uses an ID range between 1000 and 7000, while IDs 7000 - 10000 are reserved for custom user events. This differentiation is important to prevent ID conflicts.

Certain default ID ranges have been reserved for event groups of popular aircraft. If you want to contribute to the event list, please open a pull request (PR) to edit the file with a reserved ID block.

  • Flybywire: 2000-2500
  • PMDG: 3000-3500

If you want to reserve a block, please update this page.

The current custom WebAssembly (WASM) set is expanding rapidly. We are designing a new interface to guarantee an intuitive flow for users when navigating all events.

Flight Companion

Drivers

In order to use this device you need to install two pieces of software. Firstly make sure to install the device drivers. This ensures your pc can recognize and communicate with your Flight Companion.

In order to connect your Flight Companion to Microsoft Flight Simulator you need to install the Bits and Droids Flight Connector.

The latest release can be retrieved using the link above. Use the setup.exe to install the connector. Updates are being pushed through the app after installation.

This software interprets the events the controller sends and transmits the game data.

Setup the controller

To make your life easier I've made it really simple to setup your Flight Companion. On the connection page of the connector you're able to load all required settings using the add partner device option. This option can be found in the top navbar, events -> partner devices.

events menu

In the window that opens you can add the device using the add to connector button.

partner device window

First run

We're almost ready to use the Flight Companion. Since you're able to use the Bits and Droids Flight Connector for more devices than your Flight Companion we need to do a minor setup. On the connection page make sure that your device is selected in the left dropdown (it should show up with Silicon Labs CP210x ... in the name). Make sure to select the Flight Companion bundle in the right dropdown.

Setup connection

This ensures the connector knows which data to send to your Flight Companion.

Unlock all features

Microsoft Flight Simulator uses multiple layers of actions. In order to unlock all features we need to install a plugin to utilize features like the pfd controls. This can be done with a single click of a button. From the connection page (the homepage) go to the top navbar -> settings -> install wasm. A popup should appear asking for the location of your community folder.

Enter community path

The default location for this folder is:

Steam

C:\Users\{USERNAME}\AppData\Roaming\Microsoft Flight Simulator\Packages\Community

Microsoft Store

C:\Users\{USERNAME}\AppData\Local\Packages\Microsoft.FlightSimulator_8wekyb3d8bbwe\LocalCache\Packages\Community

MFS 2024

%appdata%\Microsoft Flight Simulator 2024

Click confirm after selecting the community folder.

After this we are able to start our simulator and hit the green start button in the connector.

Automatically start the connector

Having to start the connector everytime you launch Microsoft Flight Simulator can be a hassle. If you want the connector to Automatically launch and start you can enable the auto launch setting. From the connection page (the home page) -> go to the top navbar -> settings -> connection settings. In this window you can enable launch when sim starts.

launch when sim starts

Controls

There are currently four modes available on your flight companion. The controls change depending on the current active mode. To Change the current mode rotate the lower encoder.

Radio

The radio mode let's you interact with the comms and ATC.

ControlAction
Upper outer encoderIncrease/decrease Khz frequency
Upper inner encoderIncrease/decrease Mhz frequency
Upper encoder pushSwap frequencies
Lower encoder pushSwap radio mode (com1/com2/nav1/nav2)
TouchscreenButtons 0-9 to communicate with ATC

Autopilot

ControlAction
Upper outer encoderSelect target ap value (alt/hdg/vs)
Upper inner encoderIncrease/decrease target ap value
Upper encoder pushEnable ap target mode (alt/hdg/vs)
Lower encoder pushINOP.
TouchscreenEnable/disable AP

PFD Controls

ControlAction
Upper outer encoderNavigate menu items when window is open (i.e. G1000 dir window)
Upper inner encoderChange values when window is open (i.e. G1000 dir window)
Upper encoder pushEnable ap target mode (alt/hdg/vs)
Lower encoder pushINOP.
TouchscreenMenu btn, Flightplan btn, zoom in, zoom out, procedure btn, dir btn, clear btn, pfd softkeys 1-12