Hi!

I recently started to create a complete set of SIOC scripts for the MCP, EFIS, Airbus Radio and XPDR for X-Plane. While working on my scripts I ran into the problem that the encodes (or rather the displays linked to the encoders) would frequently produce jumping values when quickly turning the encoder... Turning the HDG bug would yield something like 1, 2, 3, 2, 3, 4, 2, 5....

I’m not sure if this is an X-Plane only problem but my guess is that this might also be an issue for FSX/P3D. I've spent quite a bit of time experimenting on how to get encoders ‘just right’, so here is what I found out:

Implementation 1:
This was the first implementation and here the described problem occured. I had a variable linked to the simulator via IOCP that reads and writes the heading. Any changes to this variable will be directly sent to the display. The variable for the encoder directly reads and decrements/increments this variable.

Code:
Var 001, name ioc_D_HDG, Link IOCARD_DISPLAY, Device 0, Digit 6, Numbers 3
 
Var 201, name ioc_E_HDG, Link IOCARD_ENCODER, Device 0, Input 6, Aceleration 6, Type 2
{
    L0 = &ioc_E_HDG * -10000
    &sim_HDG = ROTATE 0 3600000 L0
}
 
Var 301, name sim_HDG, Link IOCP, Offset 101
{
    &ioc_D_HDG = &sim_HDG / 10000
}
The problem with this implementation is probably caused by lag! If you turn the encoder at a certain speed, then subsequent encoder function calls are executed before the value changes are acknowledged by the simulator. So while you turn the encoder the values don’t just go up but occasionally jump back again to previous values. Not very usable.

Implementation 2:
The most simple way is to avoid this is to create a variable that stores a local heading value. A script is attached to It to write the heading to the display every time the value is changed. The variable for the encoder reads and decrements/increments this local variable and also writes to the variable linked with the simulator via IOCP. This is apparently what all SIOC scripts for X-Plane published on the OC page do.

Code:
Var 001, name ioc_D_HDG, Link IOCARD_DISPLAY, Device 0, Digit 6, Numbers 3
Var 101, name loc_HDG, value 0
{
    &ioc_D_HDG = &loc_HDG / 10000
}
 
Var 201, name ioc_E_HDG, Link IOCARD_ENCODER, Device 0, Input 6, Aceleration 6, Type 2
{
    L0 = &ioc_E_HDG * -10000
    &loc_HDG = ROTATE 0 3600000 L0
    &sim_HDG = &loc_HDG
}
 
Var 301, name sim_HDG, Link IOCP, Offset 101
The obvious drawback of this is that the heading bug will always be initialized with 0 instead of using the last heading set in the simulator and any changes of the heading caused by the simulator will be ignored, which might be okay for the heading but is a problem for other controls where the plane itself may also issue changes (e.g. the FMC changing the NAV 1 frequency to a different VOR).

Implementation 3:
The most simple solution I have come up with is to combine both solutions. I use a local variable that my encoder is based on. In addition, I create another local variable where I save the value that I expect to read from the simulator. If this value is set, the code that reads the update from the simulator will discard any other values read until this value is read. If the expected value is read, this saved variable is reset so it is open for new reads. So any out of date reads caused by lag are discarded while the ability of the simulator to trigger independent changes is retained.

Code:
Var 001, name ioc_D_HDG, Link IOCARD_DISPLAY, Device 0, Digit 6, Numbers 3
Var 401, name buf_HDG, value -999999 // expected HDG, -999999 = no value
 
Var 101, name loc_HDG
{
    &ioc_D_HDG = &loc_HDG / 10000
}
 
Var 201, name ioc_E_HDG, Link IOCARD_ENCODER, Device 0, Input 6, Aceleration 6, Type 2
{
    L0 = &ioc_E_HDG * -10000
    &loc_HDG = ROTATE 0 3600000 L0
    &sim_HDG = &loc_HDG * 10000 // send to sim
    &buf_HDG = &loc_HDG * 10000 // save to block reading of different values
}
 
Var 301, name sim_HDG, Link IOCP, Offset 101
{
    if &buf_HDG <> -999999 // unacknowledged write operation to simulator in queue?
    {
        if &sim_HDG = &buf_HDG // ok, value acknowledged by simulator
        {
            &buf_HDG = -999999
        }
        else // obsolete read, discard and reset expected value
        {
            &sim_HDG = &buf_HDG
        }
    } 
    else // no write in queue, allow updates from the simulator 
    {
        &loc_HDG = &sim_HDG
    }
}
Has anyone come up with a differnet, more simple solution?

Best regards

Florian