FSX Problems with SimConnect OnRecvSimobjectData to retrieve engine count and pitot chang

#1
I am using FSX with SimConnect to develop an application. I can connect and disconnect with SimConnect. I can also retrieve the latitude/longitude/altitude via the RequestDataOnSimObjectType().

Code:
    enum DEFINITIONS
    {
        PlaneLocationDR,
        EnginesDR,
        PitotHeatDR
    }

    enum DATA_REQUESTS
    {
        RequestLocation,
        RequestEngines,
        RequestPitotHeat
    }
And my Engine structure looks like this

Code:
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
    struct EnginesDR
    {
          public int EngineCount;
    }
Now, I am also trying to retrieve the number of engines via RequestDataOnSimObject and get reports on the change of the pitot heat switch status (change only).

I have two problems here. The first being with the engine count. I have my C172 flying on the sim and when the application connects it reports ZERO engines instead of one. Here are the snippets I use to register my interest in the engine count ("NUMBER OF ENGINES" in SimVars)

Code:
        public static void Register(SimConnect simconnect)
        {
            simconnect.AddToDataDefinition(DEFINITIONS.EnginesDR, SimVars.NUMBER_OF_ENGINES, SimUnits.NUMBER, SIMCONNECT_DATATYPE.FLOAT64, 0.0f, SimConnect.SIMCONNECT_UNUSED);

            simconnect.RegisterDataDefineStruct<EnginesDR>(DEFINITIONS.EnginesDR);
        }

        // this snippet is what triggers the request
       simconnect.RequestDataOnSimObject(DATA_REQUESTS.RequestEngines, DEFINITIONS.EnginesDR, SimConnect.SIMCONNECT_OBJECT_ID_USER, SIMCONNECT_PERIOD.ONCE, SIMCONNECT_DATA_REQUEST_FLAG.DEFAULT, 0, 1, 1);
The other problem is with the Pitot Heat change notification, as soon as I request it I receive a response and in the handler I get an Invalid Cast Exception indicating that it is wrong to cast to PitotHeatDR and the value returned on data.dwData[0] is zero.

Code:
// snippet that registers my interest in the Pitot Heat swithc notification
        public static void Register(SimConnect simconnect)
        {
            simconnect.AddToDataDefinition(DEFINITIONS.PitotHeatDR, SimVars.PITOT_HEAT, SimUnits.BOOLEAN, SIMCONNECT_DATATYPE.FLOAT64, 0.0f, SimConnect.SIMCONNECT_UNUSED);

            simconnect.RegisterDataDefineStruct<EnginesDR>(DEFINITIONS.EnginesDR);
        }

// snippet that triggers the request
simconnect.RequestDataOnSimObject(DATA_REQUESTS.RequestPitotHeat, DEFINITIONS.PitotHeatDR, SimConnect.SIMCONNECT_OBJECT_ID_USER, SIMCONNECT_PERIOD.SECOND, SIMCONNECT_DATA_REQUEST_FLAG.CHANGED, 0, 0, 0);
And my Pitot structure looks like this

Code:
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
    struct PitotDR
    {
          public Boolean PitotHeatActive;
    }

The handler for these two requests is:

Code:
        private void simconnect_OnRecvSimobjectData(SimConnect sender, SIMCONNECT_RECV_SIMOBJECT_DATA data)
        {
            switch ((DATA_REQUESTS)data.dwRequestID)
            {
                case DATA_REQUESTS.RequestEngines:
                    EnginesDR engines = (EnginesDR)data.dwData[0];
                    // THE FOLLOWING LINE REPORTS a ZERO VALUE
                    System.Diagnostics.Debug.WriteLine("Nr. of engines: {0}", engines.EngineCount);
                    break;

                case DATA_REQUESTS.RequestPitotHeat:
                    PitotDR pitot = (PitotDR)data.dwData[0]; // EXCEPTION HERE
                    System.Diagnostics.Debug.WriteLine("Pitot Heat active: {0}", pitot.PitotHeatActive);
                    break;

                default:
                    System.Diagnostics.Debug.WriteLine("Unknown request ID: {0}", data.dwRequestID);
                    break;
            }
        }
 

ddawson

Resource contributor
#2
You are requesting that both variables be returned as SIMCONNECT_DATATYPE.FLOAT64
You will need to ensure that the variables declared to receive them are of type FLOAT64.
Also, this stuff is coming back as pointers, so
EnginesDR engines = (EnginesDR)data.dwData[0];
probably needs to be
EnginesDR *engines = (EnginesDR*)&data->dwData[0];

Doug
 
#4
I am using managed code not C++, that's why the pointer notation is not used and also the same reason why the StructLayout metatag has to be used.

As for the data type, interesting point but while SimVariables indicates the type of unit, it says absolutely nothing about which data type has to be used. Nor there is any SimConnect documentation how to map the SIMCONNECT_DATATYPE enumeration items to a particular type. In fact SIMCONNECT_DATATYPE does not even has BOOL, it does have INT32, INT64, FLOAT64 and a bunch others.

I will try with INT32 for the Engine Count as well as the Pitot Heat and see how that goes.
 
#5
The Engine COunt is now returned correctly but the Pitot Heat (bool) is still causing an invalid cast exception. There is no simconnect bool type, not even byte, the smallest is INT32
 
#7
The problem is not with managed code but at how POOR the original documentation is. It is made almost exclusively for C++ while they tried to promote .NET. It is made by programmers with little insight on the fact that OTHER people would be reading it.

The managed code examples are few. Anyway, the problem was making bool an Int32. With MC is it just a matter of trial and error due to the poor documentation.
 
Top