FORUM Forums Software CLS2SIM Software API, Interface control documentation Sending button presses remotely via PowerShell.

Tagged: , ,

Viewing 7 posts - 1 through 7 (of 7 total)
  • Author
    Posts
  • #4238
    Howard
    Participant

    Hi,

    I’ve just ordered a CLS-E Mk II yoke, and while awaiting delivery I started some tinkering with the API.

    What I would like to do is send data to CLS2Sim to emulate the elevator trim up, and down buttons. From reviewing the API documentation that looks doable, but I want to sanity check what I’m trying with those that actually know what they are doing.

    The documentation indicates that trim up is ID 1002, and down is ID 1003. It wasn’t clear to me how that should be formatted as elsewhere in the documentation it indicates things should be a UInt32, so I’m assuming that would be 0x0b,0xeb,0x00,0x00.

    Further down it mentions that the command for Input Control is 0xd5, so that would be 0xd5,0x00,0x00,0x00.

    What I came up with was this:

    $client = new-object net.sockets.udpclient(0)
    
    $peerIP = "127.0.0.1"
    $peerPort = "15090"
    $command = $args[0]
    If ($command.GetType().Name -like "String") { $command = $command.Split(",")}
    Write-Host $command
    [Byte[]] $command
    [void] $client.send($command, $command.count, $peerIP, $peerPort)
    $client.close()

    What I can then do is run the script with the following arguments:

    0xd5,0x00,0x00,0x00,0x0b,0xeb,0x00,0x00

    I ran Wireshark, and the packets in that sequence were sent, but I don’t have any hardware to interact with yet, so I’m unsure if I am well clear of the mark.

    I used the PS2Exe module to turn that script into an EXE, and I can execute that from SPAD. The plan would be to run that command, with arguments, to emulate pressing the trim up down switch when I roll my trim wheel up or down.

    #4239
    Howard
    Participant

    I re-read the document page, and noticed the ID should be formatted as UInt16, so that would be 0xea,0x03 for trim up, and 0xeb,0x0b for trim down, making the entire commands:

    0xd5,0x00,0x00,0x00,0xea,0x03
    0xd5,0x00,0x00,0x00,0xeb,0x03

    Or do those commands need to be sent as separate packets? The documentation below explains Command then Input Ids, but the documentation above states:

    So if you want to enable the autopilot, you will send 2 packets.
    The first contains the id 9003.
    The second should arrive about 100ms later, to give CLS2Sim enough time to update the value in the simulation.

    So the Id is sent first, but it doesn’t explain what the “second” actually is. The command?

    #4241
    Diego BĂĽrgin
    Keymaster

    Hi Howard

    The first packet contains the id 9003, to tell CLS2Sim, that this button is pressed.
    0xD5, 0x00, 0x00, 0x00, 0x2B, 0x23

    The second packet should contain no id, only the 0xD5 command, to tell CLS2Sim that no button is pressed.
    0xD5, 0x00, 0x00, 0x00
    This effectively presses and releases the button again.
    Updated the online help. (Delete your browser cache)

    Example: I want to press “Trim up”, and while keeping trim up pressed, I press “Flaps Down” and release it, then later I release “Trim Up” again.

    At start of my script, I release all buttons: 0xD5, 0x00, 0x00, 0x00

    Now I press “Trim up”: 0xD5, 0x00, 0x00, 0x00, 0xEA, 0x03

    Now while keeping “Trim up” pressed, I also press “Flaps Down” : 0xD5, 0x00, 0x00, 0x00, 0xEA, 0x03, 0x03, 0x04

    Now I release “Flaps Down” button, while keeping “Trim up” pressed: 0xD5, 0x00, 0x00, 0x00, 0xEA, 0x03

    Now I release “Trim up”, no button is pressed now: 0xD5, 0x00, 0x00, 0x00

    Now a very important caveat!
    If you have mapped a button to a physical control (i.e. you mapped trim up to a button in CLS2Sim, you must first interdict this button with Input interdiction control commands, or CLS2SIm will immediately overwrite your button state.

    Hope that helps.
    Regards
    Diego

    #4244
    Howard
    Participant

    Ah, that makes sense. I was just sending the button press, but no release. I’ve created a C# version of this, and just added the code to send the button release datagram. The difference here is the bytes are separated by spaces rather than commas.

    using System;
    using System.Linq;
    using System.Net.Sockets;
    
    class Program
    {
         static void Main(string[] args)
        {
            string udpIp = "127.0.0.1";
            int udpPort = 15090; // Choose any available port
    
            byte[] data = args.Select(arg => Convert.ToByte(arg, 16)).ToArray();
            byte[] up = { 0xd5, 0x00, 0x00, 0x00 };
            //byte[] data = { 0xd5, 0x00, 0x00, 0x00, 0xea, 0x03 };
    
            using (UdpClient udpClient = new UdpClient())
            {
                udpClient.Send(data, data.Length, udpIp, udpPort);
                udpClient.Send(up, up.Length, udpIp, udpPort);
            }
        }
    }

    Wireshark indicates that the two packets are sent.

    #4245
    Howard
    Participant

    Regarding the interdiction of buttons, the plan is to use the trim switch on the yoke, but also be allowed to use my trim wheel to send relevant up/down trim packets as well.

    So I would want to interdict those buttons only during the remote code being sent. So that would be either:

    0xd11,0x00,0x00,0x00,0x03,0xea – Trim up
    0xd11,0x00,0x00,0x00,0x03,0xeb – Trim down
    0xd11,0x00,0x00,0x00 – Remove interdiction

    I assume then that the trim switch is a three state switch, and it detects that neither trim up or down is set, and the rocker remains centred.

    #4249
    Howard
    Participant

    I’ve looked through the documentation again, and the interdiction command is the only one that I can find that has three characters, being 0xd11. Is that correct or a typo? I can see that 0xd1 already exists, being override control.

    So if it’s really 0xd11, I would send the following?

    0x11 0x0d 0x00 0x00 + Input ID to override, and just that to clear the interdiction?

    #4250
    Howard
    Participant

    Updated the script with some assumptions. It includes lines to perform the interdiction, picking out bytes 5, and 6 to build that.

    
    using System;
    using System.Linq;
    using System.Net.Sockets;
    
    class Program
    {
         static void Main(string[] args)
        {
            string udpIp = "127.0.0.1";
            int udpPort = 15090; // Choose any available port
    
            if (args.Length != 0 && args.Length >= 6)
            {
    
                byte[] data = args.Select(arg => Convert.ToByte(arg, 16)).ToArray();
                byte[] up = { data[0], 0x00, 0x00, 0x00 };
                byte[] interdict_on = { 0x11, 0x0d, 0x00, 0x00, data[4], data[5] };
                byte[] interdict_off = { 0x11, 0x0d, 0x00, 0x00 };
                Console.WriteLine(data[0]);
                using (UdpClient udpClient = new UdpClient())
                {
                    udpClient.Send(interdict_on, interdict_on.Length, udpIp, udpPort);
                    udpClient.Send(data, data.Length, udpIp, udpPort);
                    udpClient.Send(up, up.Length, udpIp, udpPort);
                    udpClient.Send(interdict_off, interdict_off.Length, udpIp, udpPort);
                    udpClient.Close();
                }
            }
        }
    }
    
Viewing 7 posts - 1 through 7 (of 7 total)
  • You must be logged in to reply to this topic.

BRUNNER Forum​

In the BRUNNER forum you will find various discussions on different topics, such as setup, software use or general questions and concerns. 

Discuss with forum mebers, share your knowledge and experience or find answers to frequently asked questions that are answered directly by our Brunner team.

Go to BRUNNER Forum.

BRUNNER Helpdesk​

Do you have questions about a product you have already purchased or are you facing technical issues? 

Check our FAQs for quick help. The most common questions or problems are described there, including instructions.

If you are still stuck, please contact our BRUNNER Helpdesk. Open a ticket here.

BRUNNER Simulation​

BRUNNER is a leading manufacturer of flight simulation devices for the professional as well as the enthusiast sector.

Unlike other manufacturers, Brunner offers a realistic flight experience with the help of Force Feedback Technology and Control Loading System.

Discover the BRUNNER Shop.

BRUNNER Simulation

Industriestrasse 27
8335 Hittnau


+41 (0)44 953 10 10
in**@****************on.swiss