Jump to content
The simFlight Network Forums

LUA and Rotary Buttons


Recommended Posts

Hi Pete,

I had assigned Go Flight MCP Pro dials (buttons in FSUIPC) to activate certain LUA scripts, however when the dial was rotated fast, activity seems to slow down e.g. the hdg did not turn as fast. I had assigned some code to accomdate the "fast" button on the rotary dial which did work, but I guessed the LUA scripts was being killed off each time the button was activated and thus the slow down in activity. I upgraded to the latest FSUIPC beta but this still seems to occur.

Reading the beta release notes you recommend:

"Note that, if a Lua plug-in is really intended to be used repetitively, it may be much more efficient to actually program it with a loop in the Lua code and have it checking the state of the relevant button or key itself."

I have therefore done this:

local function buttonpressed(joynum, btn)

return ipc.testbutton(joynum, btn)

end

joynumdial = 157

joynumbutt = 158

bincaltslow = 10

bincaltfast = 11

bsynchdg = 12

while 1 do

if buttonpressed(joynumdial, bincaltslow) then

-- Increase Alt slow

rotateALTKnob("R", 0)

changeALT(100)

end

if buttonpressed(joynumdial, bincaltfast) then

rotateALTKnob("R", 1)

changeALT(2500)

end

if buttonpressed(joynumbutt, bsynchdg) then

SyncHDG()

end

sleep(100)

end

The first two "if" statements are MCP Pro rotary dials and turn continously whilst the third "if" statement works correctly. The program is much longer and tests all buttons and rotary dials. The buttons work fine, but the rotary dials are always "on" and thus the code for those always activates regardless of whether I'm turning the dial or not. Any ideas what is wrong?

Thanks

Steve

Link to comment
Share on other sites

I had assigned Go Flight MCP Pro dials (buttons in FSUIPC) to activate certain LUA scripts, however when the dial was rotated fast, activity seems to slow down e.g. the hdg did not turn as fast.

When you use a Lua script you need to understand that each time it is activated, the Lua file is read by the Lua interpreter, compiled into an intermediate language, then interpreted and actioned. ON top of that, so that no Lua program can bring FS to its knees by monopolising the FS process, FSUIPC imposes a small (1 millisecond) delay between each line being executed.

Furthermore, if you start a Lua program which is already running, the earlier one is forcibly terminated, so it may not have finished whatever it is doing.

I had assigned some code to accomdate the "fast" button on the rotary dial which did work, but I guessed the LUA scripts was being killed off each time the button was activated and thus the slow down in activity. I upgraded to the latest FSUIPC beta but this still seems to occur.

Yes, there's nothing changed there except that REPEATED actions (Lua program executions instigated by a button or keypress being held and thus repeated) now simply refuse to start an already-running Lua program, so don't forcibly terminate things. This wouldn't be happening with a rotary -- that looks like a button going on and off repeatedly, not one being held down.

Reading the beta release notes you recommend:

"Note that, if a Lua plug-in is really intended to be used repetitively, it may be much more efficient to actually program it with a loop in the Lua code and have it checking the state of the relevant button or key itself."

Yes, exactly.

I have therefore done this:

local function buttonpressed(joynum, btn)

return ipc.testbutton(joynum, btn)

end

Why have such a function, which simply equates "buttonpressed" with "ipc.testbutton"? Why not just use the latter directly? Much faster & smaller code.

The first two "if" statements are MCP Pro rotary dials and turn continously whilst the third "if" statement works correctly. The program is much longer and tests all buttons and rotary dials. The buttons work fine, but the rotary dials are always "on" and thus the code for those always activates regardless of whether I'm turning the dial or not. Any ideas what is wrong?

Sorry, I don't understand what you are saying. If the rotary dial "pseudo-buttons" always appear to be "on", they cannot be used at all, even directly in FSUIPC, as they will not be recognised. FSUIPC only sees them when they change from "off" to "on".

Maybe you could try using the Button logging in FSUIPC to check what is happening?

BTW, how are you starting this program? In the "ipcReady.lua", so it runs from the session start?

Regards

Pete

Link to comment
Share on other sites

Hi Pete,

I enabled button logging and it shows continuous "FS Control Sent:" enteries which is my script detecting invalid button presses on the rotaries and sending the ipc.control commands.

When I actually turn a rotary dial the stream of FS Control Sent's is interrupted with "Joystick Values" enteries so it is picking up the rotaries being moved.

It does appear that LUA is seeing the rotaries as always on.

If I change the value in my program for the MCP Pro rotaries joystick number for an invalid joystick the stream of "FS Control Sent:" enteries stop, so it is pointing to some oddity in seeing these rotary buttons as always active.

I'm starting the program with a button at the moment, not from ipcReady.lua - is that a problem?

Thanks

Steve

Link to comment
Share on other sites

It does appear that LUA is seeing the rotaries as always on.

Hmm. That's strange. I'll get a GoFlight unit hooked up here and check it -- I might not be able to get to it till the weekend thoguh. I'll see when I can fit it in.

I'm starting the program with a button at the moment, not from ipcReady.lua - is that a problem?

No, provided it isn't a button you reuse. You might want to instigate it by a call in the ipcReady.lua, or you can use the new facilities for Automatically running macros or Lua plugins when aircraft are loaded -- the [Auto ...] feature added recently.

I'll get back to you about GoFlight rotaries when I've had a look here. Can you give me the version number of FSUIPC you are using please?

Regards

Pete

Link to comment
Share on other sites

I'm using version 4.551 of FSUIPC and GFDev.DLL v1.90.0.2 which was released in July this year and is a later version than the one on your web site - not sure if that will be a problem or not?

Well, it shouldn't be, but I'd better get a copy to check, and maybe replace the one above.

Is it easy to find, on its own? Can you give me a link? Else perhaps you could ZIP it and send it as an email attachment to me at petedowson@btconnect.com ?

Thanks,

Pete

Link to comment
Share on other sites

I'll get to it before the weekend.

Still not tested this here -- probably this afternoon or tomorrow morning. However, I have some thoughts which I think are relevant.

First, you are testing buttons in a loop. You act when they are pressed. For any given press you will be acting a variable number of times which is not regulated by the button repeat setting in FSUIPC's INI file. Since you don't check for the button being released you cannot regulate it yourself.

Second, you need to understand how the rotary switches operate. Most of those I know provide pulse when turnedf - on, off, on, off. Usually one of these per 'click'. So when you stop turning, the current state may be 'on' or 'off' -- you can't tell from the switch position.

So, question: are you perhaps thinking they are always 'on' in the Lua testing simply because, after turning, they are being left parked in the 'on' position? Can you try a single click turn ansd see if that turns them off?

If so, then there's your answer. If not then I suspect the particular way the rotaries work (or are wired) on the GoFlight units are such that it only pulses "off" when turned, and always parks in an "on" position. If this is the case you could perhaps reverse your logic -- only act when it is off, rather than on. There wouldn't be any difference in the outcome. I wil check this myself when I get my RP48 connected.

Really, the answer is to do it a different way. Use the event facilities in FSUIPC's Lua libraries so that you only act when the buttons change instead of sitting in a loop polling them. In fact it was fpr applications such as yours that the event system was devised.

Here's a re-working of your code using events (untested):

joynumdial = 157
joynumbutt = 158
bincaltslow = 10
bincaltfast = 11
bsynchdg = 12

function joyaltslow(joy, btn, downup)
    -- Increase Alt slow
    rotateALTKnob("R", 0)
    changeALT(100)
end

function joyaltfast(joy, btn, downup)
    rotateALTKnob("R", 1)
    changeALT(2500)
end

function joysynchdg(joy, btn, downup)
    SyncHDG()
end

-- Replace '1's in these lines by 3 for action on both "on" and "off":
event.button(joynumdial, bincaltslow,  1, "joyaltslow")
event.button(joynumdial, bincaltfast,  1, "joyaltfast")
event.button(joynumbutt, bsynchdg,  1, "joysynchdg")

See? No loops, just actions on button presses. If you want twice the speed, act on both presses and releases (downs and ups) -- change the "downup" parameter in the event calls.

I will check the behaviour of the GF rotaries, though, to confirm my suspicions (or otherwise). :-)

Regards

Pete

Link to comment
Share on other sites

I will check the behaviour of the GF rotaries, though, to confirm my suspicions (or otherwise). :-)

Okay. Done.

It is exactly as I thought, and the same as other rotaries I've met. Each click turns the "switch" on or off. If you leave it in a position where it is "on" your original code will repeat its action forever.

Really, with a rotary, it is the CHANGE from on to off and off to on which should be used, not its current state which is really unpredictable and therefore unusable.

To prove that this was how it worked, and that this is correctly reflected in the Lua detection too, here is a little Lua test I used:

while 1 do
	 if ipc.testbutton(174,10) then
	    rslow = 1
	 else
	 	  rslow = 0
	 end

	 if ipc.testbutton(174,11) then
	    rfast = 1
	 else
	 	  rfast = 0
	 end

	 if ipc.testbutton(174,9) then
	    lslow = 1
	 else
	 	  lslow = 0
	 end

	 if ipc.testbutton(174,8) then
	    lfast = 1
	 else
	 	  lfast = 0
	 end

   ipc.log("Dial1 State = " .. 
   						rslow .. "," .. rfast .. "," ..
   					  lslow .. "," .. lfast )
   ipc.sleep(100)
end

and here's an extract of the FSUIPC log which I obtained when moving the rotary a bit one way or the other (I've deleted most of the repeated lines at 100 mSec intervals). I also had Button logging enabled so you could see exactly where I turned the rotary:

  3264266 LUA: Dial1 State = 1,0,0,1
  3264375 LUA: Dial1 State = 1,0,0,1
  3264469 LUA: Dial1 State = 1,0,0,1
  3264578 LUA: Dial1 State = 1,0,0,1
  3264672 LUA: Dial1 State = 1,0,0,1
  3264703 JoystickValues joynum=0, dwCount=1, data[2]={000000ae 00000700}
  3264781 LUA: Dial1 State = 1,0,1,1
  3264875 LUA: Dial1 State = 1,0,1,1
  3264984 LUA: Dial1 State = 1,0,1,1
  3265078 LUA: Dial1 State = 1,0,1,1
   ...
  3266094 LUA: Dial1 State = 1,0,1,1
  3266203 LUA: Dial1 State = 1,0,1,1
  3266250 JoystickValues joynum=0, dwCount=1, data[2]={000000ae 00000300}
  3266297 LUA: Dial1 State = 0,0,1,1
  3266406 LUA: Dial1 State = 0,0,1,1
  3266500 LUA: Dial1 State = 0,0,1,1
  ...
  3267312 LUA: Dial1 State = 0,0,1,1
  3267375 JoystickValues joynum=0, dwCount=1, data[2]={000000ae 00000700}
  3267422 LUA: Dial1 State = 1,0,1,1
  3267516 LUA: Dial1 State = 1,0,1,1
  3267625 LUA: Dial1 State = 1,0,1,1
  ...
  3268234 LUA: Dial1 State = 1,0,1,1
  3268328 LUA: Dial1 State = 1,0,1,1
  3268375 JoystickValues joynum=0, dwCount=1, data[2]={000000ae 00000300}
  3268406 JoystickValues joynum=0, dwCount=1, data[2]={000000ae 00000b00}
  3268437 LUA: Dial1 State = 0,1,1,1
  3268437 JoystickValues joynum=0, dwCount=1, data[2]={000000ae 00000300}
  3268469 JoystickValues joynum=0, dwCount=1, data[2]={000000ae 00000b00}
  3268500 JoystickValues joynum=0, dwCount=1, data[2]={000000ae 00000300}
  3268531 LUA: Dial1 State = 0,0,1,1
  3268641 LUA: Dial1 State = 0,0,1,1
  ...
  3271078 LUA: Dial1 State = 0,0,1,1
  3271109 JoystickValues joynum=0, dwCount=1, data[2]={000000ae 00000100}
  3271141 JoystickValues joynum=0, dwCount=1, data[2]={000000ae 00000000}
  3271172 LUA: Dial1 State = 0,0,0,0
  3271187 JoystickValues joynum=0, dwCount=1, data[2]={000000ae 00000100}
  3271219 JoystickValues joynum=0, dwCount=1, data[2]={000000ae 00000000}
  3271250 JoystickValues joynum=0, dwCount=1, data[2]={000000ae 00000100}
  3271281 LUA: Dial1 State = 0,0,0,1
  3271312 JoystickValues joynum=0, dwCount=1, data[2]={000000ae 00000000}
  3271375 LUA: Dial1 State = 0,0,0,0
  3271484 LUA: Dial1 State = 0,0,0,0
  3271578 LUA: Dial1 State = 0,0,0,0

So, my conclusion is that everything works as intended, and your results were basically arising from a misinterpretation, plus bad luck in always leaving the rotaries in an "on" position.

I think you should be fine using the "event" system instead, though it may depend how fast those routines you are using are. If you continue using a loop instead you will have to make it check for off so you know when the on means something (and vice versa if you want action on every click).

Oh, this also means that, for rotaries, in the event solution, you should realy use the parameter "3" instead of "1" so that you get something happening on every click, not only on the "off-to-on" clicks.

Regards

Pete

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use. Guidelines Privacy Policy We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.