Advanced Solutions for Flight Simulation

 

Receiving Event Notifications from Mindstar Avionics

Looking for sending events instead?  Click Here.

Overview

All Mindstar avionics products are capable of broadcasting information to notify you that certain things have occurred inside our software.  We broadcast this information using custom event numbers sent through SimConnect so that any other program connected to SimConnect can receive them.  This page will explain the C++ code necessary for you to receive these notification events.   For this example, we we will use the Mindstar G1000 gauge that works in FSX, FSX:Steam, and Prepar3D version 1-3.  (Version 4 is coming in mid-2020).

There are many notifications we broadcast out of the G1000 software, but for this example, we will use two LED lights that appear above their corresponding buttons on the G1000 Audio panel:

                   Lights used in this example
       

These LED lights illumnate or go dark based on conditions inside the Mindstar G1000 software.  Our on-screen gauge for the audio panel displays these lights as needed.   But if you are connecting hardware to our software, then your hardware needs to get a message (i.e. an "event") from our software telling you whether your hardware lights should be illuminated or not.  The event broadcast mechanism described here shows how you can listen for these events so your hardware can know whether you should be illuminating a particular LED light or turning it off.


Relationship to G1000.INI

Our event broadcast mechanism is controlled by lines that appear in the [OUTPUT] section of our G1000.INI file. That section lists all the available things the Mindstar G1000 can alert you about. 

Let's look at a highly simplified subsection of a G1000.INI below.  It is you, or your end user, who defines what hex event numbers are listed in this file.  If a hex number is entered after the '=' sign on any of these lines, then the Mindstar G1000 will broadcast that hex number through SimConnect when the associated event occurs.  But whatever event numbers you (or the end user) puts here, your hardware driver software must be programmed to listen for these exact same events. The events are just hex numbers, as shown in red below:

    [OUTPUT]
    AUDIO_COM1_MIC_LED=
0x12345
    AUDIO_COM2_MIC_LED=
0x23456


The Mindstar G1000 software reads the G1000.INI at startup in order to know if your particular installation wants us to broadcast an event numbers for any of these these conditions.   If a hex number (like those shown above in red) was entered on a line, then our G1000 software will broadcast that hex event number to SimConnect when the associated condition occurs or changes.

SimConnect Event NUMBERS vs Event DATA

When the Mindstar software sends these hex-number events to SimConnect, it also sends an additional number called event "data".   The event data is just another number, but we use this number to tell you the state of the associated item.   All events you receive from SimConnect will always come with an event data number too, even if it's zero when unused. 

When you receive any of the Mindstar [OUTPUT] events, you must look at the event data number.  If an event arrives that contains event data of 0, that means the associated light should be turned off by the hardware driver.   Similarly, if you receive an event that contains event data of 1, that means the associated light should be turned on by the hardware driver.  These two pieces of information, the event number and the event data, are all you need in order to know the status of any particular item.

 

C++ Code Example and Explanations

To listen for any of the events that Mindstar software broadcasts via SimConnect, you must write a C++ program that knows how to listen for these events.   This example uses only 4 of the numerous SimConnect function calls:

SimConnect_MapClientEventToSimEvent
SimConnect_AddClientEventToNotificationGroup
SimConnect_Open
SimConnect_CallDispatch

plus a special function you write called a DispatchProc. These are all you need in order to implement the simplest of programs to listen for Mindstar G1000 output events.
 

Your Event Enumeration

You start by coding an enumeration in your C++ program with entries that represent each of the individual events you want SimConnect to send you. If you listen for events from other vendors in addition to Mindstar, you must incorporate all the events ID's into this single enumeration.  

IMPORTANT
This must be the same enumeration you use for any events you wish to send to SimConnect as well. Sending events to SimConnect is covered in a seperate instruction page, but in order avoid cluttering this example, we'll only show the enumeration here with events we are planning to receive.

static enum MY_SIMCONNECT_EVENT_IDS {
    NO_EVENT,
    MINDSTAR_AUDIO_COM1_MIC_LED_EVENT
,
    MINDSTAR_AUDIO_COM2_MIC_LED_EVENT,
    etc,
    etc,...
};

You also need to declare a global variable 'hSimConnect' like this.

HANDLE hSimConnect = NULL;


Why do we need the enumeration?
Unfortunately, SimConnect does not simply send you the hex event number we've been talking about up to this point. Instead, SimConnect sends you one of your own enumeration IDs.  This is explained below with the concept of "event mapping".

 

Connecting Your Enumeration to the Hex Event Numbers - Event Mapping

SimConnect doesn't send the actual hex event numbers to you. Instead, SimConnect sends you one of your own enumeration IDs to you.  In order for that to work, you must create a correllation between your enumeration items and the hex numbers defined in the G1000.INI.  This is  called "mapping" a client event to a sim event.

Each of your enumeration items are a client event
Each of the hex numbers from the G1000.INI are a sim event

The correllation ("mapping") between each hex event number and its corresponding item in your enumeration is accomplished during program initialization with two functions calls for each event, as shown below:


HRESULT hr = E_FAIL;

if (hSimConnect)
{
   // --------------------------------------------------------------------------------------------
   // Tell SimConnect you want to listen for event 0x12345, and that you want to be notified of
   // this event by SimConnect sending you a message that contains the ID value:
   // MINDSTAR_AUDIO_COM1_LED_EVENT
   // --------------------------------------------------------------------------------------------
   hr = SimConnect_MapClientEventToSimEvent(hSimConnect, MINDSTAR_AUDIO_COM1_LED_EVENT, "#0x12345");
   if (hr == S_OK)
      hr = SimConnect_AddClientEventToNotificationGroup(hSimConnect, 0, MINDSTAR_AUDIO_COM1_LED_EVENT, FALSE);

   // --------------------------------------------------------------------------------------------
   // Tell SimConnect you want to listen for event 0x23456, and that you want to be notified of
   // this event by SimConnect sending you a message that contains the ID value:
   // MINDSTAR_AUDIO_COM2_LED_EVENT
   // --------------------------------------------------------------------------------------------
   hr = SimConnect_MapClientEventToSimEvent(hSimConnect, MINDSTAR_AUDIO_COM2_LED_EVENT, "#0x23456");
   if (hr == S_OK)
      hr = SimConnect_AddClientEventToNotificationGroup(hSimConnect, 0, MINDSTAR_AUDIO_COM2_LED_EVENT, FALSE);

}

Be very careful to format the hex event number into the string exactly as shown.   The string must contain a single pound sign # (or hashtag, depending on your age), followed by 0x and the 5 hex digits.  Don't add any more characters to that string or else SimConnect will not interpret it as a hex number.

That's really all there is to setting up a "subscription" to these events.  You have told SimConnect what hex event numbers you are interested in, and you have told SimConnect what enumeration ID to send you as a notification when each event occurs.   But now, how do we receive the notifications about these events?   That happens in the next section below.
  

Receiving the Events

The code above created a correllation between (or "mapped") the hex event numbers from the G1000.INI to the enumeration in your program.  But now we have to set up the code for you to receive alerts when these events occur. This is done when you first open SimConnect during your program's initialization.
 

Initializing SimConnect

When you first initialize SimConnect in your program, you have the option to tell it the name of a function inside your program that SimConnect can call when certain things occur. This function is called a DispatchProc. Let's assume the name of your DispatchProc function will be "MyDispatchProc".

This is how you would open SimConnect during your program's initialization.  Notice that one of the parameters identifies your MyDispatchProc function.

if (SUCCEEDED(SimConnect_Open(&hSimConnect, "Your Program Name or any string you want", NULL, 0, NULL, 0)))
{
    // since this example is for a DLL, we only need to call SimConnect_CallDispatch one time.
    // If we were in an EXE, we would need a processing loop that calls this function repeatedly.


    hr = SimConnect_CallDispatch(hSimConnect, MyDispatchProc, NULL);
}

The DispatchProc named MyDispatchProc must be written into your code.  The example below shows what the DispatchProc should look like. Pay close attention to where the two events of this example are located below. Remember, this example is monitoring for the events we mapped to the enumeration IDs named:

MINDSTAR_AUDIO_COM1_MIC_LED_EVENT and,
MINDSTAR_AUDIO_COM2_MIC_LED_EVENT

The DispatchProc

This is where all the magic happens.   Any time an event occurs that you have mapped for yourself in SimConnect, this function gets called, and you can take action based on the event that occurred, and its associated eventData. 

The item from your event enumeration will arrive in evt->uEventID.
The event data arrives in the same evt structure in evt->dwData.

void CALLBACK MyDispatchProc (SIMCONNECT_RECV* pData, DWORD cbData, void *pContext)
{
   switch (pData->dwID)
   {
      case SIMCONNECT_RECV_ID_EVENT:

         SIMCONNECT_RECV_EVENT *evt = (SIMCONNECT_RECV_EVENT*)pData;

         switch(evt->uEventID)
         {
             case MINDSTAR_AUDIO_COM1_MIC_LED_EVENT:

                 // you are being notified about a change of condition
                 // for the COM1 MIC light.

                 if (evt->dwData == 1)
                 {
                     // the hardware should illuminate the COM1 MIC light here
                 }
                 else
                 {
                     // the hardware should turn off the COM1 MIC light here
                 }
                 break; // end of case MINDSTAR_AUDIO_COM1_MIC_LED_EVENT

             case MINDSTAR_AUDIO_COM2_MIC_LED_EVENT:

                 // you are being notified about a change of condition
                 // for the COM2 MIC light.


                 if (evt->dwData == 1)
                 {
                     // the hardware should illuminate the COM2 MIC light here
                 }
                 else
                 {
                     // the hardware should turn off the COM2 MIC light here
                 }
                 break; // end of case MINDSTAR_AUDIO_COM2_MIC_LED_EVENT

        } // end of switch statement for your enumeration event IDs

        break; // end of case SIMCONNECT_RECV_ID_EVENT

    } // end of switch statement for pData->dwID

} // end of MyDispatchProc function

Additional References

The SimConnect SDK is well-documented online on the Microsoft and Lockheed-Martin websites, or in the Help file delivered with the FSX or Prepar3D SDKs.   Our gauges are currently being modified to support Prepar3D V4, but until those modifications are complete, you must use either FSX, or Prepar3D versions 1 thru 3.   The SimConnect SDK functions used in these examples are practically the same in all those versions of the sim.  

Here are some useful links to the Lockheed-Martin website that show more information about the functions used in our examples on this page.

General SimConnect SDK Overview
SimConnect API Reference

SimConnect_MapClientEventToSimEvent
SimConnect_AddClientEventToNotificationGroup
SimConnect_Open
SimConnect_CallDispatch
DispatchProc

SIMCONNECT_RECV_ID Enumeration
SIMCONNECT_RECV_ID_EVENT Enumeration Member
SIMCONNECT_RECV_EVENT Structure