Has anyone gotten SimConnect to repeatedly get data?

Hi there,

I am a C++ novice, but I am trying to get data such as altitude, lat/lon, ground speed etc… constantly from SimConnect. I am able to get data after the first loop of calling the dispatch method, but after that I get data with all zeros and then the dispatch method stops getting called.

I believe it has something to do with the setup of my project as I read somewhere that when using the SimConnect.dll, it sends data only once (or something like that). However, I followed the steps in the documentation of adding the header file then adding the existing property sheet within the SDK. I then start my app using the generated .exe file.

Any help would be greatly appreciated!

Thank you for your time

Look in the SDK: D:\Program Files\FlightSimulator\sdk\Samples\SimvarWatcher. That has code that gets variables from SimConnect.

1 Like

Maybe consider an easier language to start with. Python is very beginner friendly. This is a SimConnect library for Python

1 Like

Ok great! I’ll take a look! Thanks!

Oh cool! I didn’t know that was available, thank you!

1 Like

Hey buddy, if you figured anything out give let me know on discord. Im having the same problem right now. Qua Qua#7981

yes it works fine for me. I oriented my self using the P3D SimConnect examples. There you will find more C++ examples.

That’s in C# not C++

It’s important to know SimvarWatcher is a VERY BAD example of a simconnect program (well, ok, at least it compiles).

Fundamentally you should NOT be spamming the sim with data requests for the same property.

You should request the data ONCE and provide a callback and the sim will send you the data on an agreed period (e.g. once per visual frame, once per second…).

The clue is in the comment in the SimvarWatcher code:
// May not be the best way to achive regular requests.
// See SimConnect.RequestDataOnSimObject

Writing a timer loop and polling for data is the classic rookie way of misunderstanding how to propagate real-time data. This is sometimes made worse by using a timer inside the SimConnect client instead of Simulator Time.

E.g. if you want aircraft position, maybe you’re doing calculations on it, then you would subscribe to latitude, longitude and “E:ABSOLUTE TIME, seconds”.

The wrong code is so widespread I can’t find an example of using RequestDataOnSimObject properly. The guys that designed the SimConnect API knew what they were doing, here’s their example in the SDK
```
static enum DATA_DEFINE_ID {
DEFINITION_1,
DEFINITION_2
};

      static enum DATA_REQUEST_ID {
          REQUEST_1,
          REQUEST_2,
      };
      
      struct Struct1
      {
          double  kohlsmann;
          double  altitude;
          double  latitude;
          double  longitude;
      };
      
       
      
      
      
      hr = SimConnect_AddToDataDefinition(hSimConnect, DEFINITION_1, "Kohlsman setting hg", "inHg");
      hr = SimConnect_AddToDataDefinition(hSimConnect, DEFINITION_1, "Indicated Altitude", "feet");
      hr = SimConnect_AddToDataDefinition(hSimConnect, DEFINITION_1, "Plane Latitude", "degrees");
      hr = SimConnect_AddToDataDefinition(hSimConnect, DEFINITION_1, "Plane Longitude", "degrees");
      
      
      
      ....
      hr = SimConnect_RequestDataOnSimObject(hSimConnect, REQUEST_2, DEFINITION_1, SIMCONNECT_OBJECT_ID_USER, SIMCONNECT_PERIOD_SECOND);
      ....
      
      
      case SIMCONNECT_RECV_ID_SIMOBJECT_DATA:
      {
        SimConnect_RECV_SIMOBJECT_DATA *pObjData = (SimConnect_RECV_SIMOBJECT_DATA*) pData;
      
        switch(pObjData->dwRequestID)
        {
          case REQUEST_2:
      
            Struct1 *pS = (Struct1*)&pObjData->dwData;
          
            
      
            break;
        }
      break;
      }
      ....
```
3 Likes

You should still be able to understand the C# example and translate its logic into an equivalent C++ application :wink:

But yes, if you are new to programming… we‘ve all started somewhere :wink:

Except that this example is only half the logic that is required to continuously fetch sim vars. I assume you took it from here, too (like I did, and most other developers as well):

http://www.prepar3d.com/SDKv4/sdk/simconnect_api/references/simobject_functions.html#SimConnect_RequestDataOnSimObject

The code we‘re all interested in is here:

// Sections of code in DispatchProc

Yes, that‘s right. The examples hides the most crucial parts with „…“, namely how to register our callback, and how to make SimConnect call it automatically.

Well, it seems we have to help SimConnnect a little to „remember“ to call our callback. Enter all the examples and tutorials that use… a „polling loop“!

E.g. the above API doc leads us to a working example, like „Tagged Data“:

http://www.prepar3d.com/SDKv4/sdk/simconnect_api/samples/tagged_data.html

Lo and behold, here is our „polling loop“:

    while( 0 == quit ) 
    { 
        SimConnect_CallDispatch(hSimConnect, MyDispatchProcPDR, NULL); 
        Sleep(1); 
    } 

Yes, that‘s right. Unless we call „CallDispatch“ ourselves our callback won‘t be called. So we use either a loop with some „sleep“ interval, or a timer. Polling at its best.

Here is another example, „Request Data“ (I believe that is the one from which the above example code with the „kohlsmann“ variable as taken):

http://www.prepar3d.com/SDKv4/sdk/simconnect_api/samples/request_data.html

And again the same polling loop which repeatedly calls CallDispatch.

Now there is an interesting addendum in the API docs given for this CallDispatch:

http://www.prepar3d.com/SDKv4/sdk/simconnect_api/references/general_functions.html#SimConnect_CallDispatch

But first of all:

„ It is important to call this function sufficiently frequently that the queue of information received from the server is processed (typically it is coded within a while loop that terminates when the application is exited).“

So this seems to confirm that „polling“ is the intended usage of this SimConnect API (despite a callback!).

But here comes the interesting part:

„ However, if the project involves developing a library (DLL) rather than an application (EXE) then only one call to this function is necessary. This call will store the name of the callback in a cache, and whenever a packet is sent to the client, the callback function will be run“

So if you develop your SimConnect logic in a DLL there seems to be a way to register your callback such that it is actually called whenever messages arrive.

The problem: you need to connect (to the flight simulator) and register your callback in int __stdcall DLLStart(void), which is called when your DLL is loaded (started). Or in other words: the flight simulator must already be running (ready to accept connections) at that point in time.

And whether that DLL voodoo magic also works with the SimConnect implementation of FS 2020 is yet another question… (the doc refers to Prepar3D).

So if anyone has a recipe / design pattern to avoid „polling loops“ and timers… I am curious to know :slight_smile:

In my (currently very early) code I’m running on the “1sec” system event and calling RequestDataOnSimObjectType to fetch the user’s lat/lon/altitude, and it works repeatedly just fine.

This is an .exe, in C#. Using win32 event to route incoming events to ReceiveMessage. My callbacks are called as expected as long as this is set up properly.

Seems to work fine for me so far, but I haven’t hooked it up to anything fancy yet.

Update: I’ll try switching to a period parameter with RequestDataOnSimObject and see if it works or not!

Well, that‘s polling. And what we try to avoid in the first place :wink: Every 1 second you fetch data (with RequestDataOnSimObjectType) - regardless whether it has changed or not. That‘s polling :wink:

Yes, that’s why I said I’m going to change it based on the recommendation in this thread, see if it works, and report back. :slight_smile: Thanks!

Ok, using RequestDataObSimObject with a 1-second period and no need to subscribe to the system timer event also works fine for me.

So I’m not having OP’s problem; it works exactly as recommended.

But those recommendations won‘t change the fact that you would still need to „poll“: if your switch your call from SimConnect_RequestDataOnSimObjectType (which is indeed a „one shot call“: it returns you the data exactly once) to the above suggested SimConnect_RequestDataOnSimObject (which allows to specify a period, per frame, every second…) then you still need to repeatedly call the „dispatch“ function! Possibly less frequently than SimConnect_RequestDataOnSimObjectType (the incoming messages are stored, or so I understand), but still (quote API doc) „ sufficiently frequently that the queue of information received from the server is processed (typically it is coded within a while loop that terminates when the application is exited)“.

And that is - kind of - polling as well.

Don‘t get me wrong: I did the exact same „mistake“ and was also using SimConnect_RequestDataOnSimObjectType initially (and then wondering why I received the requested data only once in my callback ;)), so the suggested SimConnect_RequestDataOnSimObject (with the possibility to specify a period!) is the way to go if you want to repeatedly query sim vars (typically the aircraft‘s position, which is expected to change often anyway),

But this approach still requires that you also „poll“ the incoming messages, by repeatedly calling „dispatch“. Unless that „DLL voodoo magic“ is applied (which might not even work for FS 2020)…

I don’t understand you; I am not calling the Dispatch function in my C# code at all.

I am calling the ReceiveMessage function when the incoming win32 message from the simulator arrives, is that what you mean?

This is most likely because the C# implementation of SimConnect („wrapper“) already does this for you, and provides easy to use callbacks. But I am pretty sure that inside this C# wrapper they must also have some sort of event loop running which polls for incoming messages.

So if you‘re a C# developer: be happy :slight_smile: Nothing to worry about.

So presumably that’s the same thing wrapping the same calls via the C# method, then. :slight_smile:

As I understand it, this is just the SimConnect library going through its list of incoming events and dispatching callbacks. This doesn’t mean it’s polling data over a live connection necessarily; I would’ve assumed SimConnect’s communications are implemented with a ring buffer in a shared memory segment, so writing into it from the sender and then reading out of it in the receiver dispatching callbacks sounds like a pretty normal way of handling it.

No need to invoke “polling” here! :slight_smile:

Steeler there’s a crucial additional step which does make it work the way intended:

The RequestDataOnSimObject(…) call includes a reference to a callback function as a parameter (unlike the RequestDataOnSimObjectType call). This means the sim can call your callback function without you polling the sim. This is exactly the same as registering a mouseclick callback in javascript - your code gets called “when appropriate”. With RequestDataOnSimObject you also specify when you’d like to have your callback called, e.g. once-per-second, once-per-display-frame, when-the-data-changes etc.

With this method you could worry about how it works… surely there’s code somewhere polling something to get the computer to work? But by deferring the decision to call the callback to the sim (i.e. game), this can be handled in the core processing loop of the game (of course it has one) and is designed to have the minimum impact on the game. Even the transfer of the ‘event’ (your data is ready) to your separate program thread is handled efficiently, e.g. all ‘socket’ and ‘pipe’ code is asynchronously calling callbacks at as low a level as possible so the application thread only does any material processing when the data is ready.

The DispatchCall callback is a bit different and although I’m not recommending it for an application just subscribing to simvars I think the Simconnect developers have implemented it in an efficient way, in that it is called in the main game loop and you are expected as the programmer to make your handling of the result quick enough to not impact the main game loop. The problem with it is crap code will impact the core of the sim.

@Vibstronium any chance of you posting your complete working RequestDataOnSimObject example? Examples are almost impossible to find so yours might be “it”.