Jump to content
The simFlight Network Forums

Recommended Posts

Posted

I am struggling like many others with making rotary encoders perform well for turning heading indicators, obs, etc that require the ability to have coarse tuning and fine tuning. I am using a simple encoder interfaced through a Bodnar BUO836x card. It shows 2 separate button presses in the Buttons and switches tabs. 1 each for clockwise and counterclockwise.

While fiddling with my Goflight RP48, I noticed that there are four different commands sent by the encoder. Clockwise, clockwise fast, counter clockwise and counter clockwise fast. Not sure whether this is done by Goflight hardware or software.

I would love to duplicate this for my card. Is it possible through any FSUIPC programming method to duplicate this function? Macro's, Lua's?

Any help will be appreciated!

Reid

  • Replies 92
  • Created
  • Last Reply

Top Posters In This Topic

Posted

While fiddling with my Goflight RP48, I noticed that there are four different commands sent by the encoder. Clockwise, clockwise fast, counter clockwise and counter clockwise fast. Not sure whether this is done by Goflight hardware or software.

I think it's done in GFDev.DLL, the driver FSUIPC uses from GoFlight.

I would love to duplicate this for my card. Is it possible through any FSUIPC programming method to duplicate this function? Macro's, Lua's?

You could do it with a Lua plug-in. You'd need to time the gap between each signal. Check, for example, the "tripleuse" lua example provided.

However, I have doubts that FSUIPC's button polling rates and Lua load-compile-test rates would be adequate for a dial instead of a button being pushed by a finger. I'd recommend looking at the new HID facilities for joysticks, just released today. FSUIPC 4.704 or 3.992 feature these (and WideClient 6.88). Download (from "Download Links" subforum) the latest Lua plug-ins documents and examples and see the "HidDemo" lua plug-in. That does a lot more than you'd need. You'd only need to read certain "axes", those corresponding to your dials. The rest could be left to normal methods.

Of course I am assuming that the card looks like a joystick HID device? If not you'll need to tell me more.

Regards

Pete

Posted

I think it's done in GFDev.DLL, the driver FSUIPC uses from GoFlight.

You could do it with a Lua plug-in. You'd need to time the gap between each signal. Check, for example, the "tripleuse" lua example provided.

However, I have doubts that FSUIPC's button polling rates and Lua load-compile-test rates would be adequate for a dial instead of a button being pushed by a finger. I'd recommend looking at the new HID facilities for joysticks, just released today. FSUIPC 4.704 or 3.992 feature these (and WideClient 6.88). Download (from "Download Links" subforum) the latest Lua plug-ins documents and examples and see the "HidDemo" lua plug-in. That does a lot more than you'd need. You'd only need to read certain "axes", those corresponding to your dials. The rest could be left to normal methods.

Of course I am assuming that the card looks like a joystick HID device? If not you'll need to tell me more.

Regards

Pete

The card is read as a joystick. Thanks for your quick help!

Reid

Posted

Pete,

I know you are much too busy to help with beginner level LUA, but is there anyone out there that could hold my hand a little through this process? There are quite a few people on other boards who are looking for a solution to this problem, and I would like to help solve it. Unfortunately I lack the skills at the moment to make it happen. I would even be willing to pay a little for help getting this to work.

Reid

Posted

I know you are much too busy to help with beginner level LUA, but is there anyone out there that could hold my hand a little through this process? There are quite a few people on other boards who are looking for a solution to this problem, and I would like to help solve it. Unfortunately I lack the skills at the moment to make it happen. I would even be willing to pay a little for help getting this to work.

I will help, but not till Monday at the earliest. Tomorrow morning i leave with my wife for a weekend at my daughter's.

We'll need some information to start with. Run the hidscanner program and save the log file it produces. Check the Vendor and Product name of the card and edit the HidDemo.lua file accordingly (two lines near the top). Change "logging=false" to true and run that Lua in FSUIPC. (assign a keypress or button to Lua hiddemo and start it with that). Save the log (the FSUIPC log or the hiddemo.log if you've enabled Lua logging in FSUIPC). Operate the dials you want to use so that changes from them get logged.

Between those two files there will be enough information. the rest is easy. Show me them (paste in a message).

No rush. you have till Monday in any case. ;-)

Regards

Pete

Posted

I will help, but not till Monday at the earliest. Tomorrow morning i leave with my wife for a weekend at my daughter's.

We'll need some information to start with. Run the hiscanner program and save the log file it produces. Check the Vendor and Product name of the card and edit the HidDemo.lua file accordingly (two lines near the top). Change "logging=false" to true and run that Lua in FSUIPC. (assign a keypress or button to Lua hiddemo and start it with that). Save the log (the FSUIPC log or the hiddemo.log if you've enabled Lua logging in FSUIPC). Operate the dials you want to use so that changes from them get logged.

Between those two files there will be enough information. the rest is easy. Show me them (paste in a message).

No rush. you have till Monday in any case. ;-)

Regards

Pete

Thanks so much Pete! Enjoy your weekend!

Posted

I am struggling like many others with making rotary encoders perform well for turning heading indicators, obs, etc that require the ability to have coarse tuning and fine tuning. I am using a simple encoder interfaced through a Bodnar BUO836x card. It shows 2 separate button presses in the Buttons and switches tabs. 1 each for clockwise and counterclockwise.

While fiddling with my Goflight RP48, I noticed that there are four different commands sent by the encoder. Clockwise, clockwise fast, counter clockwise and counter clockwise fast. Not sure whether this is done by Goflight hardware or software.

I would love to duplicate this for my card. Is it possible through any FSUIPC programming method to duplicate this function? Macro's, Lua's?

Any help will be appreciated!

Reid

Hey.

I also use the Bodnar BUO836x card and just finished a very small portable little control panel. It has 6 rotaries on it. I had the same problem. What I did to fix it was to assign (using FSUIP) the switch (eg VS increase) to both the button and the release. This seemed to work for speed. I also changes the ms until i found a speed that I liked.

I am brand new to this, but it seemed to work for me.

If you have found a better way to fix this please let me know.

Thanks

Posted

Pete,

Here is the information you requested.

HIDScanner file detail:

"********* HidScanner, Version 2.00 by Pete Dowson *********

Device at "\\?\hid#vid_068e&pid_00f2#7&388afcf0&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}"

Vendor=068E, Product=00F2 (Version 0.0)

Manufacturer= CH PRODUCTS

Product= CH PRO PEDALS USB

Serial Number=

Usage Page: 1

Input Report Byte Length: 4

Output Report Byte Length: 0

Feature Report Byte Length: 0

Number of Link Collection Nodes: 2

Number of Input Button Caps: 0

Number of InputValue Caps: 3

Number of InputData Indices: 3

Number of Output Button Caps: 0

Number of Output Value Caps: 0

Number of Output Data Indices: 0

Number of Feature Button Caps: 0

Number of Feature Value Caps: 0

Number of Feature Data Indices: 0

Value Z at index 0, range 0 -> 255, using 8 bits

Value Y at index 1, range 0 -> 255, using 8 bits

Value X at index 2, range 0 -> 255, using 8 bits

**************************************************************************

Device at "\\?\hid#vid_068e&pid_c000#3&341d71af&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}"

Vendor=068E, Product=C000 (Version 0.0)

Manufacturer= CH Products AuxDev 1

Product= CH Products AuxDev 1

Serial Number= CH Products AuxDev 1

Device is a keyboard

Usage Page: 1

Input Report Byte Length: 9

Output Report Byte Length: 2

Feature Report Byte Length: 0

Number of Link Collection Nodes: 1

Number of Input Button Caps: 2

Number of InputValue Caps: 0

Number of InputData Indices: 110

Number of Output Button Caps: 1

Number of Output Value Caps: 0

Number of Output Data Indices: 5

Number of Feature Button Caps: 0

Number of Feature Value Caps: 0

Number of Feature Data Indices: 0

**************************************************************************

Device at "\\?\hid#vid_068e&pid_c001#3&30d5bc81&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}"

Vendor=068E, Product=C001 (Version 0.0)

Manufacturer= CH Products AuxDev 2

Product= CH Products AuxDev 2

Serial Number= CH Products AuxDev 2

Device is a mouse

Usage Page: 1

Input Report Byte Length: 5

Output Report Byte Length: 0

Feature Report Byte Length: 0

Number of Link Collection Nodes: 2

Number of Input Button Caps: 1

Number of InputValue Caps: 3

Number of InputData Indices: 6

Number of Output Button Caps: 0

Number of Output Value Caps: 0

Number of Output Data Indices: 0

Number of Feature Button Caps: 0

Number of Feature Value Caps: 0

Number of Feature Data Indices: 0

Buttons range 1 -> 3 at indices 0 -> 2

Value Wh at index 3, range -127 -> 127, using 8 bits

Value Y at index 4, range -127 -> 127, using 8 bits

Value X at index 5, range -127 -> 127, using 8 bits

**************************************************************************

Device at "\\?\hid#vid_1532&pid_000c&mi_00#8&20964c5d&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}"

Vendor=1532, Product=000C (Version 33.0)

Manufacturer= Razer

Product= Razer Lachesis

Serial Number=

Device is a mouse

Usage Page: 1

Input Report Byte Length: 9

Output Report Byte Length: 0

Feature Report Byte Length: 0

Number of Link Collection Nodes: 2

Number of Input Button Caps: 1

Number of InputValue Caps: 4

Number of InputData Indices: 11

Number of Output Button Caps: 0

Number of Output Value Caps: 0

Number of Output Data Indices: 0

Number of Feature Button Caps: 0

Number of Feature Value Caps: 0

Number of Feature Data Indices: 0

Buttons range 1 -> 7 at indices 0 -> 6

Value 0x40 at index 7, range -127 -> 127, using 8 bits

Value Wh at index 8, range -127 -> 127, using 8 bits

Value Y at index 9, range -32768 -> 32767, using 16 bits

Value X at index 10, range -32768 -> 32767, using 16 bits

**************************************************************************

Device at "\\?\hid#vid_1532&pid_000c&mi_01#8&33c6689b&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}"

Vendor=1532, Product=000C (Version 33.0)

Manufacturer= Razer

Product= Razer Lachesis

Serial Number=

Device is a keyboard

Usage Page: 1

Input Report Byte Length: 9

Output Report Byte Length: 0

Feature Report Byte Length: 0

Number of Link Collection Nodes: 1

Number of Input Button Caps: 2

Number of InputValue Caps: 0

Number of InputData Indices: 264

Number of Output Button Caps: 0

Number of Output Value Caps: 0

Number of Output Data Indices: 0

Number of Feature Button Caps: 0

Number of Feature Value Caps: 0

Number of Feature Data Indices: 0

**************************************************************************

Device at "\\?\hid#vid_1dd2&pid_1001#7&316a37fa&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}"

Vendor=1DD2, Product=1001 (Version 1.35)

Manufacturer= Leo Bodnar

Product= BU0836X Interface

Serial Number= B15796

Usage Page: 1

Input Report Byte Length: 6

Output Report Byte Length: 0

Feature Report Byte Length: 18

Number of Link Collection Nodes: 3

Number of Input Button Caps: 1

Number of InputValue Caps: 1

Number of InputData Indices: 33

Number of Output Button Caps: 0

Number of Output Value Caps: 0

Number of Output Data Indices: 0

Number of Feature Button Caps: 0

Number of Feature Value Caps: 1

Number of Feature Data Indices: 1

Buttons range 1 -> 32 at indices 0 -> 31

Value POV at index 32, range 0 -> 7, using 4 bits

**************************************************************************

"

HidDemo Log file:

"********* LUA: "HidDemo" Log [from FSUIPC version 4.704] *********

18846578 System time = 05/05/2011 21:15:29, Simulator time = 21:09:57 (05:09Z)

18846578 LUA: beginning "C:\Program Files\Microsoft Games\Microsoft Flight Simulator X\Modules\HidDemo.lua"

18846672 LUA: Device has 1 x Hat axis, Max= 7

18904078 LUA: ended "C:\Program Files\Microsoft Games\Microsoft Flight Simulator X\Modules\HidDemo.lua"

18904078 System time = 05/05/2011 21:16:27, Simulator time = 21:16:02 (05:16Z)

********* LUA execution terminated: Log Closed *********

********* LUA: "HidDemo" Log [from FSUIPC version 4.704] *********

243313 System time = 09/05/2011 12:35:46, Simulator time = 12:32:09 (20:32Z)

243313 LUA: beginning "C:\Program Files\Microsoft Games\Microsoft Flight Simulator X\Modules\HidDemo.lua"

243360 LUA: Device has 1 x Hat axis, Max= 7

243453 LUA: Hat = 15 0 0 0

249703 LUA: Buttons= 80000000 0 0 0 0 0 0 0

249750 LUA: Buttons= 0 0 0 0 0 0 0 0

250360 LUA: Buttons= 80000000 0 0 0 0 0 0 0

250391 LUA: Buttons= 0 0 0 0 0 0 0 0

251328 LUA: Buttons= 80000000 0 0 0 0 0 0 0

251375 LUA: Buttons= 0 0 0 0 0 0 0 0

252610 LUA: Buttons= 40000000 0 0 0 0 0 0 0

252625 LUA: Buttons= 0 0 0 0 0 0 0 0

253203 LUA: Buttons= 40000000 0 0 0 0 0 0 0

253266 LUA: Buttons= 0 0 0 0 0 0 0 0

253672 LUA: Buttons= 40000000 0 0 0 0 0 0 0

253735 LUA: Buttons= 0 0 0 0 0 0 0 0

254156 LUA: Buttons= 40000000 0 0 0 0 0 0 0

254219 LUA: Buttons= 0 0 0 0 0 0 0 0"

The log was done with three clicks clockwise and three counter clockwise.

Please let me know if this is what you needed, and I hope you had a great weekend with family.

Reid

Posted

********* LUA: "HidDemo" Log [from FSUIPC version 4.704] *********

243313 System time = 09/05/2011 12:35:46, Simulator time = 12:32:09 (20:32Z)

243313 LUA: beginning "C:\Program Files\Microsoft Games\Microsoft Flight Simulator X\Modules\HidDemo.lua"

243360 LUA: Device has 1 x Hat axis, Max= 7

243453 LUA: Hat = 15 0 0 0

249703 LUA: Buttons= 80000000 0 0 0 0 0 0 0

249750 LUA: Buttons= 0 0 0 0 0 0 0 0

250360 LUA: Buttons= 80000000 0 0 0 0 0 0 0

250391 LUA: Buttons= 0 0 0 0 0 0 0 0

251328 LUA: Buttons= 80000000 0 0 0 0 0 0 0

251375 LUA: Buttons= 0 0 0 0 0 0 0 0

252610 LUA: Buttons= 40000000 0 0 0 0 0 0 0

252625 LUA: Buttons= 0 0 0 0 0 0 0 0

253203 LUA: Buttons= 40000000 0 0 0 0 0 0 0

253266 LUA: Buttons= 0 0 0 0 0 0 0 0

253672 LUA: Buttons= 40000000 0 0 0 0 0 0 0

253735 LUA: Buttons= 0 0 0 0 0 0 0 0

254156 LUA: Buttons= 40000000 0 0 0 0 0 0 0

254219 LUA: Buttons= 0 0 0 0 0 0 0 0"

The log was done with three clicks clockwise and three counter clockwise.

Looks like 4 clicks counter-clockwise, actually.

Please let me know if this is what you needed, and I hope you had a great weekend with family.

Yes and yes, thank you.

However, on my return I find my development PC is playing up a bit so I'm going to be a bit delayed. I'll try and show you a solution before the end of the week, though.

Regards

Pete

Posted

At your convenience sir! really appreciate the help, and you are correct of course about the four clips.

Okay. Found a bit of time so knocked this up. I've put in a load of comments (something I never do for my own code! ;-) ), because I want you to read it and hopefully understand it. Then you can extend it or alter it to your specific needs - eg add more rotaries or whatever.

Save the whole lot as "ipcReady.lua" into your FS modules folder.

Vendor = "Bodnar"
Product = "BU0836X"
Device = 0  -- Multiple devices of the same name need increasing Device numbers.

cwise = 31  --Button number for clockwise turn
ccwise = 30 --Button number for counter-clockwise turn

dev, rd, wrf, wr, init = com.openhid(Vendor, Product, Device, Report)

if dev == 0 then
   ipc.log("Could not open HID")
   ipc.exit()
end


-- Set the boundary time in milliseconds between
-- "fast" (shorter) and "slow" (longer) signalling
FastTimeLimit = 60 -- Adjust to taste

-- Polling time in milliseconds: should be much shorter than 
-- the boundary time
Pollrate = 20  -- same as 50 times per second


-- Initialise variables used to keep track of things
LastTimecwise = 0
LastTimeccwise = 0
Lastcwise = false
Lastccwise = false

-- This function will be called by a time event, set at the end of the program before exit.
function poll(Time)
  -- read any data available from the device (only need most recent report)
	data, n = com.readlast(dev, rd)

	if n ~= 0 then
       -- Data was returns, so get the status of two two "buttons" we are using
 	Thiscwise = com.TestHidButton(dev, cwise, data)
 	Thisccwise = com.TestHidButton(dev, ccwise, data)

	     -- See if they've changed since last time
	     if Thiscwise ~= Lastcwise then
			-- Clockwise button changed
			-- See if changed in less than the "boundary" time
			fast = 0
			if (Time - LastTimecwise) < FastTimeLimit then
	       	fast = 1
			end
			LastTimecwise = Time

			-- Toggle a virtual button accordingly
			ipc.togglebitsUB(0x3340, 1 + fast) -- Joy 64, Buttons 0 (slow) or 1 (fast)
	     end

	     -- Same for counter-clockwise
	     if Thisccwise ~= Lastccwise then
			-- Clockwise button changed
			-- See if changed in less than the "boundary" time
			fast = 0
			if (Time - LastTimeccwise) < FastTimeLimit then
	       	fast = 4
			end
			LastTimeccwise = Time

			-- Toggle a virtual button accordingly
			ipc.togglebitsUD(0x3340, 4 + fast) -- Joy 64, Buttons 2 (slow) or 3 (fast)
	     end
  end
end

event.timer(Pollrate, "poll")

This assumes the "buttons" are 30 and 31 as shown in the log you submitted. The parts you'll probably want to adjust to achieve decent results are:

FastTimeLimit: this determines the time between button changes (there are two for each of your "clicks") below which the turn should be considered "fast".

Pollrate sets the interval between the checks into the state of the buttons. It needs to be a lot shorter (i.e. faster) than the "fast time", but not so fast that it affects the performance of your FS.

The "togglebits" functions do the job of toggling "virtual buttons" in FSUIPC, which can be assigned in its Buttons tab. Offset 3340 has 32 such buttons. I'm toggling button 0 for clockwise, 1 for fast clockwise, 2 for counter cw, 3 for fast ccw. In FSUIPC's buttons dialogue you'll probably see the buttons 30 and 31 first, on whatever joystick the card is on, then you should get the joystick 64 buttons -- that's these.

Ask questions about anything you don't understand.

I might move much of this thread over to "User Contributions" sub-forum when we're done so it remains in view for others.

Regards

Pete

Posted

This assumes the "buttons" are 30 and 31 as shown in the log you submitted. The parts you'll probably want to adjust to achieve decent results are:

FastTimeLimit: this determines the time between button changes (there are two for each of your "clicks") below which the turn should be considered "fast".

Pollrate sets the interval between the checks into the state of the buttons. It needs to be a lot shorter (i.e. faster) than the "fast time", but not so fast that it affects the performance of your FS.

The "togglebits" functions do the job of toggling "virtual buttons" in FSUIPC, which can be assigned in its Buttons tab. Offset 3340 has 32 such buttons. I'm toggling button 0 for clockwise, 1 for fast clockwise, 2 for counter cw, 3 for fast ccw. In FSUIPC's buttons dialogue you'll probably see the buttons 30 and 31 first, on whatever joystick the card is on, then you should get the joystick 64 buttons -- that's these.

Ask questions about anything you don't understand.

I might move much of this thread over to "User Contributions" sub-forum when we're done so it remains in view for others.

Regards

Pete

Thanks! I have tried it and it looks very promising. I am indeed getting 4 different "presses" now. 2 attributed to the Bodnar card, and 2 associated with "Joy #64". I will play around with the settings.

Will I need to restart FSX each time I make a change to the variables you mentioned to re-run the Lua?

Reid

EDIT: Just noticed that sometimes the impulses register as joy 4 button 31 for slow clockwise and sometimes joy 64 button 1. Sometimes joy 64 button 1 is read for fast CW and sometimes 64 button 0. CCW slow is registering as joy 64 button 3, joy 64 button 2 or joy 4 button 30. I will mess with the Pollrate and FastTimeLimit to see if I can remove some of the inconsistencies.

Posted

Thanks! I have tried it and it looks very promising. I am indeed getting 4 different "presses" now. 2 attributed to the Bodnar card, and 2 associated with "Joy #64". I will play around with the settings.

You should be getting 4 different button indications for Joy#64, depending on how fast you turn the knob. 0 and 2 for slow turns, 1 and 3 for fast turns. If you are only getting 0 and 2 then you will need to try a lower time for the max value for fast turns. If you asre only getting 1 and 3 then it needs increasing instead. Without the device here I can't set that for you.

You don't want to assign anything to the 2 button indications for the card itself, because those will occur all the time no matter how fast or slow you turn it.

Will I need to restart FSX each time I make a change to the variables you mentioned to re-run the Lua?

No. Assign a key combination, eg Tab+1, to "LuaKill ipcReady" and another key combo (e.g. Tab+2) to "Lua ipcReady". Then after making changes you can kill it and start it again.

EDIT: Just noticed that sometimes the impulses register as joy 4 button 31 for slow clockwise and sometimes joy 64 button 1. Sometimes joy 64 button 1 is read for fast CW and sometimes 64 button 0. CCW slow is registering as joy 64 button 3, joy 64 button 2 or joy 4 button 30. I will mess with the Pollrate and FastTimeLimit to see if I can remove some of the inconsistencies.

Yes, it's all based on times -- mainly "FastTimeLimit". Ignore the Joy 4 indications -- I can't get rid of those, though for clarity it might be a good idea to add an "ignore" line in the [buttons] section of your FSUIPC INI file, thus:

IgnoreThese=4.30,4.31

Then those won't get in the way.

Note that even with ideal values you'll still get a mix of fast and slow . This certainly occurs with the GoFlight knobs. The important thing is that you need to be always assured of getting a consistent "slow" so you can do precise settings. The fast will occasionally register as slow simply because the computer is doing other things too, and the last click, as you stop turning will always look like a "slow" of course because there's nothing following.

One question: do you understand the Lua program? Are my comments helpful? If not, please ask questions so I can raise the level a bit before posting in the FAQ sub-forum.

Regards

Pete

Posted

One question: do you understand the Lua program? Are my comments helpful? If not, please ask questions so I can raise the level a bit before posting in the FAQ sub-forum.

Regards

Pete

With my lack of LUA experience, the comments are the only thing that make sense.

I will not have a chance to fully get into this program, tweak the settings and add additional encoders until the weekend. Can I get back to you then with more questions?

I am sure this would be helpful in the current state for those with more experience. Most people who will run across it probably do not have that experience though. I will do whatever I can to ask the stupid questions though so others won't bug you with them!

Reid

Posted

With my lack of LUA experience, the comments are the only thing that make sense.

But they are there to explain the code. Do you mean the code is utterly meaningless to you even with the explanation? Have you looked at it? It uses common symbols, as in normal school arithmetic and so on.

I will not have a chance to fully get into this program, tweak the settings and add additional encoders until the weekend. Can I get back to you then with more questions?

Time is not of the essence. ;-)

Regards

Pete

Posted

Pete,

Here we go with the stupid questions...

1. It seems to me as if this script is running 50 times per second. It is checking the status of the encoders to see if they have moved. If they have then it is deciding whether they have moved fast or slow and then assigning virtual joystick buttons . What I am not understanding is how it is gauging speed. Is it counting the number of button presses/ms and then setting it as button x or y? Or is it seeing if the impulses are continuous for longer than the boundary time, and then deciding it is slow or fast? I am guessing the latter, but am confused about what I am changing with boundary time(FastTimeLimit). The script works fine, I am just trying to learn more about the process.

2. How does poll rate relate to FSX speed? Is this little program enough to drag down FS performance?

3. To add more encoders, will I just need to copy and paste the existing script, and change the buttons and virtual buttons before the end command?

Posted

1. It seems to me as if this script is running 50 times per second. It is checking the status of the encoders to see if they have moved. If they have then it is deciding whether they have moved fast or slow and then assigning virtual joystick buttons . What I am not understanding is how it is gauging speed. Is it counting the number of button presses/ms and then setting it as button x or y? Or is it seeing if the impulses are continuous for longer than the boundary time, and then deciding it is slow or fast? I am guessing the latter, but am confused about what I am changing with boundary time(FastTimeLimit).

The check is being done at a higher frequency than the slow/fast boundary, and it should be fast enough, easily, to see all changes (i.e. it cannot miss a complete on-off-on cycle). Therefore simply noting the time between detected changes and seeing if that is less than or greater than the "FastTimeLimit" will do the job. It doesn't need to know the exact time between the rising and falling edges, only how long it is between it noticing the changes. (The "Time" value being given to the poll function is a system supplied elapsed time in milliseconds).

2. How does poll rate relate to FSX speed? Is this little program enough to drag down FS performance?

The poll rate is independent of other threads and activities in FSX, but it is subject to getting processor time. On a multicored PC this shouldn't be a problem, though some activities on a PC can lock out the processors. Certainly when FS is loading a new flight it could be starved of processing time because FS will be using as many cores as it can get then. But really nothing should affect normal rotary operation in any significant way.

It can only "drag down" FS performance a touch (probably unnoticeably) if you make the poll rate ridiculously high. Don't make it more than 200 times a second, for instance. 50 or 100 should be fine. 50 should be far faster than you can turn the knob and that's all that is needed to stop it missing changes on the incoming signals.

3. To add more encoders, will I just need to copy and paste the existing script, and change the buttons and virtual buttons before the end command?

Well, yes, sort of. But you can only have one "ipcReady.lua" plug-in. There are two ways to do this, one more efficient than the other:

1. Rename this one something like "Rotary3031.lua" (for button numbers 30/31), and create a new ipcReady.lua containing only this line:

ipc.runlua("Rotary3031")

Then for any other rotaries, make a copy of the Rotary3031.lua, changing the name appropriately, and the button numbers within, and adding another ipc.runlua line to the ipcReady.lua.

Note that there are several lines needing a change for each rotary:

First, the pair of button numbers signalled from the device:

  cwise = 31  --Button number for clockwise turn
  ccwise = 30 --Button number for counter-clockwise turn

then the "virtual" buttons being signalled to FSUIPC affects these lines:

fast = 1

ipc.togglebitsUD(0x3340, 1 + fast)

fast = 4

ipc.togglebitsUD(0x3340, 4 + fast)

Those values are for virtual buttons 0-3, for one rotary, and use bit values 1,2,4,8. Correct the "B" to a "D" where highlighted first (that was a typo in the original). The main changes would be as follows, for each of up to 3 extra rotaries. Replace the red parts by:

Virtual buttons 4-7 (bit values 16,32,64,128):

fast = 16

16 + fast

fast = 64

64 + fast

Virtual buttons 8-11 (bit values 256,512,1024,2048):

fast = 256

256 + fast

fast = 1024

1024 + fast

Virtual buttons 12-15 (bit values 4096,8192,16384,32768):

fast = 4096

4096 + fast

fast = 16384

16384 + fast

This will work and is easy enough, but it is a bit inefficient as you'll have as many separate timers running and Lua threads running as you have rotaries.

I wouldn't use this method for more than 4 rotaries if I were you. Too many timers, and an unnecessary number of threads.

OR

2. Change the current program to handle as many rotaries as you wish, using tables of numbers and loops. More complicated, but more compact and efficient than lots of little plug-ins.

If you plan on having more than, say, 3 or 4, then let me know and i'll knock up the more advanced version. I'm going on holiday Wednesday eve and won't be back till June 1st or 2nd, so whilst i can probably make one for you before I go I probably won't be able to test it. Best done when I get back really.

Regards

Pete

  • 3 weeks later...
Posted

2. Change the current program to handle as many rotaries as you wish, using tables of numbers and loops. More complicated, but more compact and efficient than lots of little plug-ins.

If you plan on having more than, say, 3 or 4, then let me know and i'll knock up the more advanced version. I'm going on holiday Wednesday eve and won't be back till June 1st or 2nd, so whilst i can probably make one for you before I go I probably won't be able to test it. Best done when I get back really.

Regards

Pete

Pete,

I think it would be more useful to many to have the unlimited option. My pit only needs 5 more rotaries, but someone starting out a GA pit will need 6 for instruments, and 10 or 12 for the radio stack and/or GPS. Quite a few more with the Heavy Iron.

Reid

Posted

I think it would be more useful to many to have the unlimited option. My pit only needs 5 more rotaries, but someone starting out a GA pit will need 6 for instruments, and 10 or 12 for the radio stack and/or GPS. Quite a few more with the Heavy Iron.

Oh! So no one else volunteered to do this Lua programming whilst I was away? :-(

Can you remind me in about a week. From tomorrow till next Wednesday I've involved in a re-built of my 737NG cockpit and I really can't get into any other programming stuff till after.

Regards

Pete

Posted

Oh! So no one else volunteered to do this Lua programming whilst I was away? :-(

Can you remind me in about a week. From tomorrow till next Wednesday I've involved in a re-built of my 737NG cockpit and I really can't get into any other programming stuff till after.

Regards

Pete

Of course! Have fun with your rebuild!

This is a fairly inactive forum without you to helm it Captain.

Reid

  • 2 weeks later...
Posted

Pete,

Hope your rebuild is going easily. Watching the number of threads you reply to each day, I am embarrassed to even ask for your help with the complex solution. You are committed to supporting your software well beyond most authors!

That being said, is there a regular around here that may have the skills to do what you proposed that I can ask to assist me and lighten your load? If all else fails I can certainly go the multiple LUA route to get the rotaries all working.

Any thoughts?

Reid

Posted

Hope your rebuild is going easily.

Yes, nearly there.

Watching the number of threads you reply to each day, I am embarrassed to even ask for your help with the complex solution.

I'll definitely get to it this week.

[LATER]

Just looking at the problem now, some questions arise which will make it easier for you to adapt:

1. How many, maximum, rotaries can be fitted to one BUO836X card?

2. Is is possible to ensure that they are altogether in termis of the indications they send -- like your example sent bits 31 and 30 (shown as x80000000 and x40000000)?

If so it makes it much easier to generalise, simply scanning the bits in order. Otherwise you'd have to list every bit in a table, much messier.

Regards

Pete

Posted

Yes, nearly there.

I'll definitely get to it this week.

Very grateful to you sir!

[LATER]

Just looking at the problem now, some questions arise which will make it easier for you to adapt:

1. How many, maximum, rotaries can be fitted to one BUO836X card?

One card will support 16 encoders.

2. Is is possible to ensure that they are altogether in termis of the indications they send -- like your example sent bits 31 and 30 (shown as x80000000 and x40000000)?

If so it makes it much easier to generalise, simply scanning the bits in order. Otherwise you'd have to list every bit in a table, much messier.

Inputs on the card are listed as buttons 1-32. I am using 31 and 32, so I guess that corresponds to bits 30 and 31, although I am not sure how that works. Does the software see those inputs as bits 0-31?

The card must be set up with the encoders on adjacent pairs, so the easier route should work. It would be handy if the program would allow inputs to not be configured as encoders. The card can also handle digital inputs on each of those 32 stations, but only assigns them as rotaries if specifically set that way. Normally they are switches, buttons, etc. Having the flexibility to do both off the same card would be best.

Ideally the LUA would scan only specified pairs, not all 32 inputs so that buttons and switches could be used normally.

I hope I am making sense.

Reid

Posted

One card will support 16 encoders.

Oh, is that all? that's easy then ... I was looking at supporting the max FSUIPC could handle in the virtual Buttons, which would be 72 (72 x 4 = 288 button inputs).

Inputs on the card are listed as buttons 1-32. I am using 31 and 32, so I guess that corresponds to bits 30 and 31, although I am not sure how that works. Does the software see those inputs as bits 0-31?

Yes, according to the tests we did and the Lua code I supplied.

Ideally the LUA would scan only specified pairs, not all 32 inputs so that buttons and switches could be used normally.

With it limited to only 16, that is okay. It just wasn't nice for the generalised case of up to 72.

Regards

Pete

Posted

Try this one and let me know. If it's okay I'll probably add it to the examples I supply.

[LATER EDIT: The code is now fixed and tested, and will appear in the examples pack]

See if my comments tell you enough on how to use it. If not I'll try to clarify more.

Regards

Pete

Vendor = "Bodnar"
Product = "BU0836X"
Device = 0  -- Multiple devices of the same name need increasing Device numbers

-- Use separate Lua plug-ins for separate cards!

-- NOTE: this can handle up to 16 rotaries only, using the first 64 "virtual buttons"
-- List the pairs here:

Rotaries = {} 

-- Example { 31, 30, 25, 22 } would be 31+30 for one, 25+22 for the next, and so on
-- Which is clockwise and which counterclockwise doesn't matter -- you'll get
-- fast and slow of each in any case

dev, rd, wrf, wr, init = com.openhid(Vendor, Product, Device, Report)

if dev == 0 then
   ipc.log("Could not open HID")
   ipc.exit()
end

-- Set the boundary time in milliseconds between
-- "fast" (shorter) and "slow" (longer) signalling

FastTimeLimit = 100 -- Adjust to taste

-- Polling time in milliseconds: should be much shorter than 
-- the boundary time

Pollrate = 20  -- same as 50 times per second

-- Initialise variables used to keep track of things
LastTimes = {}
Buttons = 0
PrevButtons = 0
Diff = 0

-- This function will be called by a time event, set at the end of the program before exit.
function poll(Time)
   -- read any data available from the device (only need most recent report)
  data, n = com.readlast(dev, rd)

  if n ~= 0 then
  	-- Data was returned, so get the status of all the possible "buttons" we are using
 	-- one value of 32 bits
 	Buttons = com.gethidbuttons(dev, data)        	

 	-- See if any changes occurred:
 	Diff = logic.Xor(Buttons, PrevButtons)
 	PrevButtons = Buttons

 	if Diff ~= 0 then 
    	offset = 0x3340
    	buttonbit = 1
    	j = 1
        while Rotaries[j] ~= nil do
           mask = logic.Shl(1, Rotaries[j])   			
           if logic.And(Diff,mask) ~= 0 then
          	-- This one changed
      		-- See if changed in less than the "boundary" time
      		thisbutton = buttonbit
      		if (LastTimes[j] ~= nil) and ((Time - LastTimes[j]) < FastTimeLimit) then
             	thisbutton = buttonbit + buttonbit  -- Use next higher button for fast
         	end
         	LastTimes[j] = Time

         	-- Toggle a virtual button accordingly
     		ipc.togglebitsUB(offset, thisbutton)
  		end

  		j = j + 1
 		buttonbit = 4 * buttonbit
     	if logic.And(j,15) == 0 then
    		buttonbit = 1
    		offset = offset + 4
         end
      end
    end
  end
end

event.timer(Pollrate, "poll")

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.