• Which the release of FS2020 we see an explosition of activity on the forun and of course we are very happy to see this. But having all questions about FS2020 in one forum becomes a bit messy. So therefore we would like to ask you all to use the following guidelines when posting your questions:

    • Tag FS2020 specific questions with the MSFS2020 tag.
    • Questions about making 3D assets can be posted in the 3D asset design forum. Either post them in the subforum of the modelling tool you use or in the general forum if they are general.
    • Questions about aircraft design can be posted in the Aircraft design forum
    • Questions about airport design can be posted in the FS2020 airport design forum. Once airport development tools have been updated for FS2020 you can post tool speciifc questions in the subforums of those tools as well of course.
    • Questions about terrain design can be posted in the FS2020 terrain design forum.
    • Questions about SimConnect can be posted in the SimConnect forum.

    Any other question that is not specific to an aspect of development or tool can be posted in the General chat forum.

    By following these guidelines we make sure that the forums remain easy to read for everybody and also that the right people can find your post to answer it.

Simconnect toggle switch input

Messages
204
Country
portugal
Hello all.

I got an home built console based on a MJoy16 input card fully working with something like 70 button controls.

These controls transmit button states via wired pushbuttons, toggles switches and rotary encoders.

I've been using this console for quite sometime now, but only via the ingame keyboard mapping interface.

I have to use some extra mapping software to get all controls to work as FS only accepts up to 32 (I wonder why they don't let use all the actual DirectX capabilities well beyond this number).

So, we all know that there are plenty of switches on an aircraft panel which one can access via mouse clicks, as they were left out of the ingame key mapping interface.

So I (finaly) decided to get into simconnect for the purpose of getting all controls I want at the flick of a switch on my console.

I started with the sample scripts provided with the SDK, and I got it working as it should for the pushbuttons. Great.

Now for the toggles and rotaries I got stuck with a problem.

The MJoy16 card translates changes of toggle switch position into momentary joystick button presses, but I noticed each of these presses send 2 values of the event: 1 and 0. What happens when I flick the toggle to switch the beacon lights on, they actualy switch on and off imediatly after.

Here the script I'm using:

Code:
//------------------------------------------------------------------------------
//
//  SimConnect Joystick Control Sample
//  
//	Description:
//				button 17 of joystick 1 toggles the beacon lights
//
//------------------------------------------------------------------------------

#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#include <strsafe.h>

#include "SimConnect.h"

int     quit = 0;
HANDLE  hSimConnect = NULL;


static enum GROUP_ID {
    GROUP_0,
};

static enum INPUT_ID {
    INPUT_0,
};

static enum EVENT_ID {
    EVENT_TOGGLE_BEACON_LIGHTS,
 };

void CALLBACK MyDispatchProcJ(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 EVENT_TOGGLE_BEACON_LIGHTS:
                    printf("\nEvent toggle beacon lights: %d", evt->dwData);
                    break;

                default:
                    break;
            }
            break;
        }


        case SIMCONNECT_RECV_ID_QUIT:
        {
            quit = 1;
            break;
        }

        default:
            break;
    }
}

void testInput()
{
    HRESULT hr;

    if (SUCCEEDED(SimConnect_Open(&hSimConnect, "Joystick Input", NULL, 0, 0, 0)))
    {
        printf("\nConnected to Flight Simulator!");   
        
        hr = SimConnect_MapClientEventToSimEvent(hSimConnect, EVENT_TOGGLE_BEACON_LIGHTS, "TOGGLE_BEACON_LIGHTS");

        hr = SimConnect_AddClientEventToNotificationGroup(hSimConnect, GROUP_0, EVENT_TOGGLE_BEACON_LIGHTS);

        hr = SimConnect_SetNotificationGroupPriority(hSimConnect, GROUP_0, SIMCONNECT_GROUP_PRIORITY_HIGHEST);

		hr = SimConnect_MapInputEventToClientEvent(hSimConnect, INPUT_0, "joystick:1:button:17", EVENT_TOGGLE_BEACON_LIGHTS);

        hr = SimConnect_SetInputGroupState(hSimConnect,INPUT_0, SIMCONNECT_STATE_ON);
 
        while( 0 == quit )
        {
            SimConnect_CallDispatch(hSimConnect, MyDispatchProcJ, NULL);
            Sleep(1);
        } 

        hr = SimConnect_Close(hSimConnect);
    }
}

int __cdecl _tmain(int argc, _TCHAR* argv[])
{
    testInput();
	return 0;
}

I can read the following data event showing the values 1 and 0 each time I flick the switch:

Connected to flight SImulator!
Event toggle beacon lights: 1
Event toggle beacon lights: 0

It should show only 0 as I suppose.

I'd appreciate someone could sort this out.

Thanks in advance.
 
Hello Joao,

I ran into this issue also, and noted from the SDK that joystick buttons have an up and down message - hence the two events. You need to add a private event and then trigger the toggle event based on the up OR down value returned.

Here is parts of your code - modified.

Code:
static enum EVENT_ID {
    EVENT_TOGGLE_BEACON_LIGHTS,
	EVENT_PRIVATE_BEACON_TOGGLE,
 };

void CALLBACK MyDispatchProcJ(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 EVENT_PRIVATE_BEACON_TOGGLE:
                    printf("\nEvent private toggle beacon lights: %d", evt->dwData);
                                        // Up or Down = 0 or 1
					if(evt->dwData == 1)
					{
					SimConnect_TransmitClientEvent(hSimConnect, 0, EVENT_TOGGLE_BEACON_LIGHTS, 0, GROUP_0, SIMCONNECT_EVENT_FLAG_GROUPID_IS_PRIORITY);
                    printf("\nTrigger Event toggle beacon lights: %d", evt->dwData);
					}
                    break;

                case EVENT_TOGGLE_BEACON_LIGHTS:
                    printf("\nEvent toggle beacon lights: %d", evt->dwData);
					break;

                default:
                    break;
            }
            break;
        }


        case SIMCONNECT_RECV_ID_QUIT:
        {
            quit = 1;
            break;
        }

        default:
            break;
    }
}

void testInput()
{
    HRESULT hr;

    if (SUCCEEDED(SimConnect_Open(&hSimConnect, "Joystick Input", NULL, 0, 0, 0)))
    {
        printf("\nConnected to Flight Simulator!");   
        
        hr = SimConnect_MapClientEventToSimEvent(hSimConnect, EVENT_TOGGLE_BEACON_LIGHTS, "TOGGLE_BEACON_LIGHTS");
        hr = SimConnect_MapClientEventToSimEvent(hSimConnect, EVENT_PRIVATE_BEACON_TOGGLE,"My.PrivateBeacon");

        hr = SimConnect_AddClientEventToNotificationGroup(hSimConnect, GROUP_0, EVENT_TOGGLE_BEACON_LIGHTS);
        hr = SimConnect_AddClientEventToNotificationGroup(hSimConnect, GROUP_0, EVENT_PRIVATE_BEACON_TOGGLE);

        hr = SimConnect_SetNotificationGroupPriority(hSimConnect, GROUP_0, SIMCONNECT_GROUP_PRIORITY_HIGHEST);

		hr = SimConnect_MapInputEventToClientEvent(hSimConnect, INPUT_0, "joystick:0:button:3", EVENT_PRIVATE_BEACON_TOGGLE );

        hr = SimConnect_SetInputGroupState(hSimConnect,INPUT_0, SIMCONNECT_STATE_ON);
 
        while( 0 == quit )
        {
            SimConnect_CallDispatch(hSimConnect, MyDispatchProcJ, NULL);
            Sleep(1);
        } 

        hr = SimConnect_Close(hSimConnect);
    }
}
 
Thanks a lot, I guess that will do the trick.

And hows about getting to read the button controls state when the flight starts and send them to the simutalor so to synchronize the toggles with the ac panel?

For example: the state of the aircraft as per the .FLT file defines the beacon lights are on; when the flight starts, if the beacon toggle is off, this would switch the beacon lights off on the aircraft right at the start.

Is this too hard to code?

My card has an opitional button from which I can manualy send a pulse signal of all button controls to synchronize panels, but I never tested it, I thought this could be automated by script.

I'm sure sim builders have come across this one too, any ideas?

Thanks again.
 
I suggest you look at the Tagged data example - change the "pitot heat" to any of the following and even ALL of them.

These sim variables can be queried to see their state.

LIGHT STROBE Light switch state Bool N All aircraft
LIGHT PANEL Light switch state Bool N All aircraft
LIGHT LANDING Light switch state Bool N All aircraft
LIGHT TAXI Light switch state Bool N All aircraft
LIGHT BEACON Light switch state Bool N All aircraft
LIGHT NAV Light switch state Bool N All aircraft
LIGHT LOGO Light switch state Bool N All aircraft
LIGHT WING Light switch state Bool N All aircraft
LIGHT RECOGNITION Light switch state Bool N All aircraft
LIGHT CABIN Light switch state Bool N All aircraft

You probably want to have a way that when you press the control state button, the FS switches set to what you have in the MJoy16. I don't have the Mjoy16 card so I don't know what the reply is from that device. You may have to write your own dll/function to get the state of the MJoy16 card - write to a file and have your simconnect read and set/toggle the state.

What reply do you get from the card after the control state pulse?

But you know as a pilot you always shut down all (most) the electricals in the A/C before engine start :D so they should be set to off.
 
Thanks very much for your help Ronh.

I just tested your modified code and it works as it should! God job!

But I'd like to go a bit further:

As it is now this script transmits the event TOGGLE_BEACON_LIGHTS to the sim whenever I switch my panel toggle switch to the on position; when I switch it to the off position nothing happens (there is no event transmission); when I turn it on again it transmits the event again and the beacon lights turn off. Not the way we'd want a panel toggle switch to be implemented.

Ok, there's two solutions here:

1) as my panel toggle switches are two way (ON,ON), I can use the other pole and map it to other button change using the same method but with the events BEACON_LIGHTS_ON and BEACON_LIGHTS_OFF (I don't have the event list at hand but I think these events exist); or

2) use only one switch pole and keep the TOGGLE_BEACON_LIGHTS event, but provide the OFF event by some "on release" coding, ex: joystick:1:button:18 would send a 0 value on press, and another 0 value on release - can this be done? I suppose so, but I don't know how to code it.

Obviously I'd prefer the 2nd solution, and use only one button control per panel toggle. Can you help?

About the variables state question, I can't help to much for now, because I don't have the MJoy16 "reset" button wired, but I'll report back as soon as I can test it.

Cheers.
 
the Mjoy manual states about toggles the separate buttons are used to represent on and off.
Toggle switch support is an enhanced MJoy16-C1 feature. It translates changes of toggle switch position into momentary joystick button presses. There might be two ways of performing this translation. One way is generating the same button press when toggle switch is switched “ON” or “OFF”. The other way is generating different button presses when switch is toggled “ON” and “OFF”. And guess what - this way is used in MJoy16-C1 controller. That’s why their type is called “double-action”.
Toggle switches are arranged in rows by 8. As each toggle switch generates different button presses for “ON” and “OFF” flip. 8 toggle switch rows generate up to 16 different button presses. These button positions are arranged in such a way that lower 8-position row buttons are momentary activated when toggles switches are flipped to “ON” position. Whereas the upper row is activated when they are flipped “OFF”.
To illustrate: Suppose we flip toggle switch 1 to “ON” position. It generates a brief Button 17 press. Then we flip it back to “OFF”. It generates Button 25 press. It’s like Gear Up / Down.
MJoy16-C1 has support for up to 16 toggle switches. Exact mapping which toggle switches generate which button presses is described in Controls Mapping chapter.
Please read about “Init” button to learn more about toggle switches.

I don't have this device so I can't test it. Since it seems a single button is not responding in your case - try looking for a button 26 (18+8)
 
I understand perfectly how the MJoy16 works. And you're right about 18+8, that's the way they should be connected (and in fact I wired them that way).

I just want to save the other button for something else (8 buttons controls in fact).

Some keyboard mappers can actualy send button states "on release" - one single button can send two keys, one for press and another for release, I just though we could connect to the FSX that way - that was my solution 2 on the previous reply.

And you might ask: why would you want to be savy about buttons when you have 112 of them? Well, because de 32 limit. Beyond that number we got to map... or use another input card.

But don't worry, your code trick can solve my problem for the toogles and encoders (thank you!), so I think I can live with a little mapping.

Now I'll try to figure out how to synchronize things :confused:

Keep in touch.
 
Last edited:
Back
Top