Pete Dowson Posted December 10, 2011 Report Posted December 10, 2011 Although the rotary speed is just fine when using GoFlight software, the rotary speed is terribly slow when working with Lua. Sorry, I've no idea what you are doing now what you want to see or do. Maybe if you showed what it is you've done and what you are trying to do I might be able to advise. There is no reason why a Lua program accessing devices can't be as efficient as you need it to be. It doesn't need to be fast. Even if it only operated at 1000 Lua lines per second (though it is never anywhere near that slow), with the typically small number of lines needing executing can outpace any dial you are trying to adjust. So it must be all in the way you are programming it. BTW "GFDev.DLL" is used by FSUIPC for GF button assignments, and is accessed by the Lua gfd library. But the "HidDemo" you refer to is all about accessing USB HID devices directly, via the Lua com library. There's no GFDev.DLL involved then, it is bypassed. If you are only wanting to program GF devices I'm not sure why you want to go down that route. You can, but I don't think there's any big advantages. The HID facilities were mainly added to access other USB HID devices, which either could not be seen directly in FSUIPC (not being joystick or GF), or have more facilities than can be accessed using the normal methods. Regards Pete
Delta14Sierra Posted December 10, 2011 Report Posted December 10, 2011 Pete, If you are only wanting to program GF devices I'm not sure why you want to go down that route. Using Lua, my goal is to use several GF-166 radios and have them more accurately model the function and displays of several instruments in the RealAir Beech Duke. Thus far, I have accomplished replicating the DME and XPDR. I am currently working on the ADF w/Timer. Maybe if you showed what it is you've done and what you are trying to do I might be able to advise. By way of example, the following is a short Lua script I am using to control/display the Altimeter on a GF-166. It is launched via ipc.ready and, via FSUIPC, the rotaries are assigned either Kohlsman Dec/Inc. unit = 1function AltDisp(offset, value) value = value / 16 value = value * 0.0295302 gfd.SetDisplay(GF166, unit, 0, string.format("%2.2f ",value))endevent.offset("0330", "UW", "AltDisp")[/CODE]My issue is that the rotaries can only go so fast before they bog down in making adjustments. I know that the encoders can make significantly faster adjustments because there seems to be no limit to their speed when designating the function of a GF-166 via GFconfig.In trying to research and solve this issue, I came across this current thread on the forum and thought that it might prove helpful to me in this matter.HidScanner has provided me with the following info for one of my GF-166 radios:[CODE]Device at "\\?\hid#vid_09f3&pid_0050#7&2870454e&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}" Vendor=09F3, Product=0050 (Version 1.4) Manufacturer= GoFlight Product= GF-166 Serial Number= Usage Page: 14 Input Report Byte Length: 4 Output Report Byte Length: 0 Feature Report Byte Length: 7 Number of Link Collection Nodes: 8 Number of Input Button Caps: 1 Number of InputValue Caps: 1 Number of InputData Indices: 9 Number of Output Button Caps: 0 Number of Output Value Caps: 0 Number of Output Data Indices: 0 Number of Feature Button Caps: 2 Number of Feature Value Caps: 5 Number of Feature Data Indices: 14 Buttons range 1 -> 8 at indices 1 -> 8 Value Dial at index 0, range -128 -> 127, using 8 bits[/CODE]Using this info, I made adjustments to HidDemo.lua to reflect the respective GF-166.Vendor = "GoFlight"Product = "GF-166"Device = 0Logging = trueI launched HidDemo from a button assignment in FSUIPC and made adjustments in both directions using each of the rotary encoders. However, when I went to look for the HidDemo.log in the Modules folder, it had not been generated. I tried several times in doing this step with no results.Recalling that GF modules interact with GFDev.dll, I thought that maybe I was heading down a dead end street, and that is when I posed the question to you whether or not what I was attempting was even possible.Your insight and direction at this point would be most appreciated.DanFYI...Concerning HidDemo.lua: When I "Syntax Checked" in the LuaEdit program, it claimed that the following lines had errors. I could not see where the errors were, but thought that this might be of interest to you.99 ipc.writeUW(0x3ba8 + ((i-1) * 2), val) -- Error Message: ')' expected near 'x3ba8'130 ipc.writeUD(0x3340 + ((i-1) * :cool:, buttons[i]) -- Error Message: ')' expected near 'x3340'
Pete Dowson Posted December 10, 2011 Report Posted December 10, 2011 By way of example, the following is a short Lua script I am using to control/display the Altimeter on a GF-166. It is launched via ipc.ready and, via FSUIPC, the rotaries are assigned either Kohlsman Dec/Inc. I've programmed lots of hardware devices like radios and so on, and there are rules I always follow: 1. When adjusting the value, stop processing changes from FS and display the update directly, locally. 2. Only display a new value from FS after n milliseconds has passed since the last change was sent. If you don't do this you will ALWAYS have lag. In order to do what you want you need to process both the input and output in your Lua. My issue is that the rotaries can only go so fast before they bog down in making adjustments. Yes, exactly. I know that the encoders can make significantly faster adjustments because there seems to be no limit to their speed when designating the function of a GF-166 via GFconfig. Because they program it the way I suggest. Using this info, I made adjustments to HidDemo.lua to reflect the respective GF-166. ... I launched HidDemo from a button assignment in FSUIPC and made adjustments in both directions using each of the rotary encoders. However, when I went to look for the HidDemo.log in the Modules folder, it had not been generated. I tried several times in doing this step with no results. The HidDemo logging uses "ipc.log" to log the data. The logging goes to the FSUIPC log unless, in the FSUIPC logging options, you check the Lua log option -- that makes each Lua write to its own log when ipc.log is used. FYI...Concerning HidDemo.lua: When I "Syntax Checked" in the LuaEdit program, it claimed that the following lines had errors. I could not see where the errors were, but thought that this might be of interest to you.99 ipc.writeUW(0x3ba8 + ((i-1) * 2), val) -- Error Message: ')' expected near 'x3ba8' 130 ipc.writeUD(0x3340 + ((i-1) * :cool:, buttons) -- Error Message: ')' expected near 'x3340' Well, your line 130 has an error now, with :cool: in there, but both the original lines are fine. I don't know this "LuaEdit" (is that from the Lua website?), but it evidently doesn't check syntax correctly! Maybe you should send them a bug report? Regards Pete
Delta14Sierra Posted December 11, 2011 Report Posted December 11, 2011 1. When adjusting the value, stop processing changes from FS and display the update directly, locally.2. Only display a new value from FS after n milliseconds has passed since the last change was sent. Pete, What you are making me aware of is of great interest to me. However, it is also new territory for me. I am more than eager to learn, but I am not quite sure where to start. I will dig into the LUA script examples that are included with FSUIPC to see what I can glean from there. But any direction, insight or examples that you can provide to help me on my way would be most appreciated. Dan
Pete Dowson Posted December 12, 2011 Report Posted December 12, 2011 I am more than eager to learn, but I am not quite sure where to start. I will dig into the LUA script examples that are included with FSUIPC to see what I can glean from there. I don't think there's anything in Lua very usefully related to this. I've used the methods I described in C programs, not Lua -- all the hardware I've ever programmed were programmed long before I had even heard of Lua. But you can still do it in Lua, there's no difference from any other programming. What is it you don't understand? Don't assign the dial "button" returns in FSUIPC. Instead use the event.gfd function to get your function called when something changes on the device, then gfd.GetValues and gfd.Dial to read the dial to see if that changed. Use the change to update a value you are reading for the radio (event.offset for the radio offset) and send that back to FS ipc.writeUW to the same offset) and also send it to the GF display (gfd.setdisplay), as you are doing now. Also read the time (ipc.elapsedtime) and store that in a variable which you can check in the event.offset function for the radio -- simply do not update the display if the time now is withing N milliseconds of the last write by a dial change. The value for 'N' will bed to be determined by experiment, but something in the order of 300 - 700 is normal. You want to be reasonably sure that either the user has stopped turning the dial, or at least has definitely hesitated. Regards Pete
Delta14Sierra Posted December 12, 2011 Report Posted December 12, 2011 Pete, Thank you for the direction. It is most appreciated! I will be back in touch to let you know what I have learned. Dan
Delta14Sierra Posted December 15, 2011 Report Posted December 15, 2011 Pete, Thank you for your direction!!!! Below is what I have come up with and it is functioning more to my liking. Just like you said, using the event.gfd made a HUGE difference. However, I am certain that I did not properly implement ipc.elapsedtime because my milliseconds value (0.5) is nowhere near what you said it would be (300-700). If you could give me some further direction concerning this, I would appreciate it. Also, while I could get a value (1) identifying the inner rotary using gfd.GetValues and gfd.Dial, I could not get any value at all so as to identify (and utilize) the outer rotary. When I have a little more time, I intend to experiment with event.button to see if I can identify and utilize the outer rotary that way. Any insight you might provide would be most appreciated. Again, thank you for your coaching. I have learned a lot in the last couple of days and I appreciate it so much! (Concerning the multiple ipc.control() commands...the way it displays on my GF-166 is more to my liking than with a single ipc.control() command.) -- launched from ipc.runluatime1 = ipc.elapsedtime()function AltDisp(offset, value)gfd.SetDisplay(GF166, 1, 0, string.format("%2.2f ",(value/16)*0.0295302))endfunction AltRotary(model, unit)gfd.GetValues(GF166,1)Dial1 = gfd.Dial(1)if Dial1 == -1 then time2 = ipc.elapsedtime() if (time2 - time1) < 0.5 then ipc.control(65884) ipc.control(65884) ipc.control(65884) ipc.control(65884) ipc.control(65884) ipc.control(65884) ipc.control(65884) ipc.control(65884) ipc.control(65884) ipc.control(65884) else ipc.control(65884) end time1 = ipc.elapsedtime()endif Dial1 == 1 then time2 = ipc.elapsedtime() if (time2 - time1) < 0.5 then ipc.control(65883) ipc.control(65883) ipc.control(65883) ipc.control(65883) ipc.control(65883) ipc.control(65883) ipc.control(65883) ipc.control(65883) ipc.control(65883) ipc.control(65883) else ipc.control(65883) end time1 = ipc.elapsedtime()endendevent.gfd("GF166",1,"AltRotary")event.offset("0330", "UW", "AltDisp")[/CODE]
Pete Dowson Posted December 16, 2011 Report Posted December 16, 2011 However, I am certain that I did not properly implement ipc.elapsedtime because my milliseconds value (0.5) is nowhere near what you said it would be (300-700). If you could give me some further direction concerning this, I would appreciate it. I'm afraid your code bears little resemblance to anything I have suggested. To start with, since the return from ipc.elapsedtime() is always an integer, a number of milliseconds, the lines like this if (time2 - time1) < 0.5 then[/CODE]will only be true if time2 actually equals time1, which is hardly ever likely to be true, or nearly always true. I can't tell. Your code might actually be equivalent to:[CODE]function AltDisp(offset, value)gfd.SetDisplay(GF166, 1, 0, string.format("%2.2f ",(value/16)*0.0295302))endfunction AltRotary(model, unit)gfd.GetValues(GF166,1)Dial1 = gfd.Dial(1)if Dial1 == -1 then ipc.control(65884)endif Dial1 == 1 then ipc.control(65883)endendevent.gfd("GF166",1,"AltRotary")event.offset("0330", "UW", "AltDisp")[/CODE]If you are happy with the results you are getting you might as well simplify it like that. Either way you might as well strip out the timers and elapsedtime calls and either include your many incs and decs or only one as you wish.You seemed to have missed the points I was making entirely. Recall what i said. Here, I break it down a bit:[b]"Don't assign the dial "button" returns in FSUIPC. Instead use the [b]event.gfd[/b] function to get your function called when something changes on the device, then [b]gfd.GetValues[/b] and [b]gfd.Dial[/b] to read the dial to see if that changed."[/b]Okay, you've done that well.[b]"Use the change to update a value you are reading for the radio ([b]event.offset[/b] for the radio offset) and send that back to FS [b]ipc.writeUW[/b] to the same offset) and also send it to the GF display ([b]gfd.setdisplay[/b]), as you are doing now."[/b]You aren't doing any of that. You are simply sending a single INC or DEC to FS and letting it change the radio value, not you. The method I'm talking about requires your code to maintain the radio value, work the increments and decrements yourself, and update the display AND the FS offset, yourself. You are not doing any of that.[b]"Also read the time ([b]ipc.elapsedtime)[/b] and store that in a variable which you can check in the event.offset function for the radio -- simply do not update the display if the time now is withing N milliseconds of the last write by a dial change."[/b]Instead of this you are setting time2 on entry to your dial change detection and setting time1 at the end. What do you think the difference in those times is supposed to indicate? At best it tells you how fast your PC is at executing the intervening lines.The point of having times at all was to stop your other routine, the one setting the display, from updating the display at all when you, the user, are supposedly updating it directly on the dial changes -- which you are not. You aren't even testing the time in the display routine!I'm thinking this is far too complicated for you. Is that right?Also, while I could get a value (1) identifying the inner rotary using [b]gfd.GetValues[/b] and [b]gfd.Dial[/b], I could not get any value at all so as to identify (and utilize) the outer rotary.You are using gfd.Dial(1) at present. Why '1'? Have you tried other numbers? The logical first one would be 0, as in gfd.Dial(0), of course. Surely if there's a 1 there must have been a 0 as they are numbered 0-7 as documented.(Concerning the multiple [b]ipc.control()[/b] commands...the way it displays on my GF-166 is more to my liking than with a single [b]ipc.control()[/b] command.)I really doubt they are being executed. Or, possibly, they are always being executed. I'm not sure if the two times are always the same or always different, but it could be a near random chance.Pete
Ryan Aerospace Posted June 21, 2012 Report Posted June 21, 2012 Hi everyone. I'm looking for some help with rotary encoders and I'm happy to pay. Here's my current situation: * I am using a Leo Bodnar BU0386X Joystick controller (with the rotary encoder plug in); * I have a registered copy of FSUIPC; * I'm running a commercial version of Prepar3D. I have developed a multi-function display for an EHSI that has two rotary encoders installed. The one of the left is the course selector knob which is set to the VOR1 OBI Inc / Dec variables. The one on the right is the Heading Select Knob and is set to the Heading Bug Inc / Dec variables. When you click (rotate) the rotary encoder once, it will move the Heading Bug (for example) one increment / one degree. This is extremely frustrating for the user who might want to rotate through 180 degrees as it takes forever. I need to make it such that when the rotary encoder is turned faster, the Heading Bug (for example) moves quicker. I notice in FSUIPC, there's a variable to do these rotations at 10 degree increments and can see from the forums that I can create a plugin / driver to swap between the variables depending on how fast the knob is being rotated by using the virtual buttons / virtual joystick. I also see that (from this forum) many other people have had the same problem and share my frustrations. I've looked right through the forums and even tried a few things but since I have zero programming knowledge, all my attempts have been futile and I know that it's time to call the experts in. So here's what I need: I just need someone that really knows what they're talking about (and has actually done this in the past) to do this for me from start to finish. Ie, they will need to write the program and give me simple, step-by-step instructions on how to install. Given my lack of ability to program, what I'm able to offer is going to be limited. Ie, I can get your files and install them etc. but I can't do any of the programming. As mentioned, I'm happy to pay the right person to do this job for me but it has to be from start to finish! (Sorry to badger this point but I can't be dealing with anyone saying "have you tried this or have you tried that".... I just need someone to do this as a paid job for me.) Thanks and I hope to hear from anyone that can do this for me soon. Kind regards, Chris
alaxus Posted June 21, 2012 Report Posted June 21, 2012 So here's what I need: I just need someone that really knows what they're talking about (and has actually done this in the past) to do this for me from start to finish. Ie, they will need to write the program and give me simple, step-by-step instructions on how to install. Given my lack of ability to program, what I'm able to offer is going to be limited. Ie, I can get your files and install them etc. but I can't do any of the programming. As mentioned, I'm happy to pay the right person to do this job for me but it has to be from start to finish! (Sorry to badger this point but I can't be dealing with anyone saying "have you tried this or have you tried that".... I just need someone to do this as a paid job for me.) Thanks and I hope to hear from anyone that can do this for me soon. Kind regards, Chris I did something like this a while ago with Leo's card and 5 rotary encoders for my MCP. If you read this post here: I will tell you however that most encoders only have 16 de-tents per revolution. This is not nearly enough for what you want. In the end I went back to my Phidgets setup. Personally I don't think you will get want you want with Leos card. You need to use a more efficient setup that writes directly to the fsuipc offsets.
Pete Dowson Posted June 21, 2012 Report Posted June 21, 2012 I've looked right through the forums and even tried a few things but since I have zero programming knowledge, all my attempts have been futile and I know that it's time to call the experts in. There's already a few Lua plug-in solutions for this which work reasonably well. They use accelerated increment/decrement controls when the rotary is turned faster. Take a look at these threads: http://forum.simflight.com/topic/70537-rotarieslua-with-leo-bodnars-card/page__hl__rotaries.lua http://forum.simflight.com/topic/68260-rotary-encoder-input-speed/page__p__426533__hl__rotaries.lua#entry426533 These are just two of the more useful ones I think, found by a quick search. There are also threads on this subject over in http://www.mycockpit.org/forums/. Regards Pete
Ryan Aerospace Posted June 21, 2012 Report Posted June 21, 2012 Thanks Pete (as always) for the quick response. I'll take a look and see how I go! Cheers, Chris
Ryan Aerospace Posted July 12, 2012 Report Posted July 12, 2012 Hi Alaxus Thanks for the advice. However, I'm afraid it's still well beyond me. What I really need is for someone to do this for me as a paid job. Are you interested? Also, if you think the Leo card is not the most efficient way of doing it, do you have any recommendations as to other options? I'm happy to consider using a whole different card and driver if necessary to achieve the goal. Thanks again, Chris
alaxus Posted July 15, 2012 Report Posted July 15, 2012 Hi Alaxus Thanks for the advice. However, I'm afraid it's still well beyond me. What I really need is for someone to do this for me as a paid job. Are you interested? Also, if you think the Leo card is not the most efficient way of doing it, do you have any recommendations as to other options? I'm happy to consider using a whole different card and driver if necessary to achieve the goal. Thanks again, Chris Currently I am using 5 of these in my MCP http://www.phidgets.com/products.php?category=7&product_id=1052_0 with this software: fs2phidgets http://www.mycockpit.org/forums/downloads.php?do=cat&id=20 Its pretty straight forward. The other one you can look at is the goflight module: http://www.goflightinc.com/collections/modules/products/gf-rp48-push-button-rotary Again pretty straight forward. Have a look in to those first as I think it will work better for your situation.
saxbill Posted January 13, 2014 Report Posted January 13, 2014 Pete (or anyone would might be able to help), I've used this lua to get two rotary controllers up and working perfectly. However, when I go to add a third rotary the alternate joystick (64) never shows up. For instance, I have the following entry: Rotaries = {6,7,2,3,0,1} Only 6,7,2,3 work, not 0,1. I've tried it in a different order and the same happens, the last pair doesn't work. I've also tried a number of different rotary controllers that are attached the same BU0836X board, but it doesn't matter which I use only the first two show up. Any help you can give would be appreciated. Bill
Pete Dowson Posted January 13, 2014 Report Posted January 13, 2014 Pete (or anyone would might be able to help), I've used this lua to get two rotary controllers up and working perfectly. However, when I go to add a third rotary the alternate joystick (64) never shows up. For instance, I have the following entry: Rotaries = {6,7,2,3,0,1} Only 6,7,2,3 work, not 0,1. I've tried it in a different order and the same happens, the last pair doesn't work. I've also tried a number of different rotary controllers that are attached the same BU0836X board, but it doesn't matter which I use only the first two show up. Any help you can give would be appreciated. Sorry, what Lua are we talking about here? Do you mean the one supplied as an example in the Lua package installed with FSUIPC? Or do I have to search back in this rather long (and very old) thread you've resurrected and appended to? And how are you testing to see that the last two (one rotary) doesn't work? If its my exmple rotary code than please note that there is an error in line 69: ipc.togglebitsUB(offset, thisbutton) should be ipc.togglebitsUD(offset, thisbutton) UB = Unsigned Byte (8 bits = 2 rotaries) UD = Unsigned Dword (32 bits = 8 rotaries) Odd this hasn't been discovered before! Pete
saxbill Posted January 13, 2014 Report Posted January 13, 2014 Pete, Sorry for resurrecting such an old thread. Upon a search, this lua was exactly what I was looking for so I went with it. I'm pretty new to this, so I read the entire thing and got it up and running. I'm happy to say that the code fix you supplied above (UB to UD) fixed my problem. I used the lua from post #25 in this thread. You might want to go back and edit that post so no one else runs into this problem. Thanks for your help (and quick reply!) Bill
Pete Dowson Posted January 13, 2014 Report Posted January 13, 2014 Pete, Sorry for resurrecting such an old thread. Upon a search, this lua was exactly what I was looking for so I went with it. I'm pretty new to this, so I read the entire thing and got it up and running. I'm happy to say that the code fix you supplied above (UB to UD) fixed my problem. I used the lua from post #25 in this thread. You might want to go back and edit that post so no one else runs into this problem. Thanks for your help (and quick reply!) Bill I've corrected the original, which is the one in the Lua package downloadable from the Download Links subforum and also which will be installed into your FSUIPC Documents folder. If there are pasted copies in threads I'm not going to find them all in any case -- I would expect folks to use the ones installed. Thanks, Pete
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now