Pete Dowson Posted September 7, 2012 Report Posted September 7, 2012 A trim wheel, such as that sold by Saitek, is very nice, but unless it is motorised so that when the autopilot is controlling trim the wheel can be automatically moved to its correct position, it poses difficulties unless you fly under manual control all of the time. With the autopilot operating the trim for vertical flight control modes, the wheel's position will not often match the actual trim position in FS. This doesn't matter if you don't move it, as axes are not read until moved. But as soon as you move it, the actual setting for the wheel position is immediately applied, resulting in a sudden trim change. FSUIPC does have an option to disconnect the trim axis when the autopilot is using it (see the DisconnTrimForAP option in the Advanced User's guide), but this doesn't get over the discrepancy in the position when the A/P is disconnected. Really the only satisfactory way of having a trim wheel operate through the trim axis control is to have it motorised so that is always goes to the currently set FS position when the A/P adjusts it, or when you load a new flight. An alternative, which can work but which does spoil some of the advantages of having a realistic trim wheel, is to revert it to sending elevator trim up and trim down commands to FS, instead of using the value directly as the trim vale. This effectively makes it similar to the NumPad 1 and 7 keys, or the spring-loaded two way toggle switches or levers fitted to many commercial yokes. The way to do this is to use a Lua plug in which converts the change in axis value to a trim Inc or Dec. Here's an example: function checkvalue(val) if prev ~= nil then if val > prev then ipc.control(65615) elseif val < prev then ipc.control(65607) end end prev = valendevent.param("checkvalue")[/CODE]Save this as, say, "trimwheel.lua", in the Modules folder and add this to your INI file:[Auto]1=Lua trimwheelRun FS and assign your axis, in the normal FS controls assignment on the left, to "Luavalue trimwheel".RegardsPete
JessicaZ Posted November 13, 2017 Report Posted November 13, 2017 This appears to be an ideal solution to using my Saitek Pro Trim Wheel, but I ran into some caveats. 1) At least with the Saitek trim wheel, I had to reverse the values in the Lua script, which is an easy fix. I did: function checkvalue(val) if prev ~= nil then if val > prev then ipc.control(65607) elseif val < prev then ipc.control(65615) end end prev = val end event.param("checkvalue") 2) If I turn the trim wheel too quickly, I do not get the full range of movement in the sim trim indication. When I move the trim wheel quickly from its' lowest to highest positions, on the sim it is only moved about half way through its' range of motion. If I move it slowly, I can get the full range of motion. I suspect the trim wheel is sending the nose up/nose down commands too quickly and some of the commands are being ignored. Is there anyway to fix this? 3) The last issue is something that is a limitation with the Saitek Trim Wheel, and cannot be fixed FSUIPC, but I am mentioning it as it is unexpected. The issue is that the trim wheel has limits to the values it can send nose up or down, but turning the wheel there is no indication you have reached full nose up or down, or where you are in the range. That means, if trim wheel is physically at nose up (or down), before you start the simulator, then in the sim you cannot trim more nose up (or down). In this case having a trim wheel that does not have physical limits would be ideal. I wonder if the Saitek can be modified. Internally it uses a optical rotary position sensor. This can somewhat worked around by going into FSUIPC and seeing what the position of the trim wheel is at and setting it to roughly what sim trim position you want to start with. I am using Prepar3d v4.1 and FSUIPC v5.121b Jessica
ThomasAH Posted November 14, 2017 Report Posted November 14, 2017 I adjusted Pete's script to solve all three of your issues: The script writes directly to offset 0x0BC0 For larger movements of the wheel the script makes larger changes the offset. If the wheel is near the end of its range (upper or lower 1/16th) a warning popup will appear and suggest disconnecting and reconnecting the wheel (I have connected it to the USB hub of my Saitek yoke, so this is easily reachable) Additionally I have configured the trim wheel to set AP vertical speed or pitch or attitude hold if the AP is enabled instead of acting as a trim wheel. And for the times I use only a joystick instead of the full setup, I have assigned two joystick buttons to act as trim, with increasing speed if the buttons are hold for a longer time. Maybe you can adjust it for your own needs: -- Using a trim wheel axis to operate with trim INC and DEC instead -- http://forum.simflight.com/topic/72492-using-a-trim-wheel-axis-to-operate-with-trim-inc-and-dec-instead/ -- -- [Auto] -- 1=Lua trimwheel -- assign your axis, in the normal FS controls assignment on the left, to "Luavalue trimwheel". boundary = 16384-2048 joystick = "J" -- Saitek Aviator Stick button_dn = 4 -- T1 button_up = 5 -- T2 function trimbutton(joynum, button, downup) factor = 20 direction = (button == button_up) and -1 or 1 trimwheel(factor*direction) ipc.sleep(100) while ipc.testbutton(joynum, button) do if factor < 200 then factor = factor+2 end trimwheel(factor*direction) ipc.sleep(30) end trimwheel(0) end function trimwheel_trim(change) trim = ipc.readSW(0x0BC0) - change if trim < -16384 then trim = -16384 elseif trim > 16383 then trim = 16383 end ipc.writeSW(0x0BC0, trim) end function trimwheel_ap_vs(change) if ipc.readUW(0x07BC) == 0 then -- AP disabled trimwheel_trim(change) elseif change > 0 then ipc.control(65895) -- AP_VS_VAR_DEC elseif change < 0 then ipc.control(65894) -- AP_VS_VAR_INC end end function trimwheel_ap_pitch(change) if ipc.readUW(0x07BC) == 0 then -- AP disabled trimwheel_trim(change) elseif change > 0 then ipc.control(66584) -- AP_PITCH_REF_INC_DN elseif change < 0 then ipc.control(66583) -- AP_PITCH_REF_INC_UP end end function trimwheel_ap_pitch_atthold(change) if ipc.readUW(0x07BC) == 0 then -- AP disabled trimwheel_trim(change) elseif change > 0 then if ipc.readUW(0x07D0) > 0 then -- AP alt lock ipc.control(65804, 1) -- AP_ATT_HOLD_ON end ipc.control(66584) -- AP_PITCH_REF_INC_DN elseif change < 0 then if ipc.readUW(0x07D0) > 0 then -- AP alt lock ipc.control(65804, 1) -- AP_ATT_HOLD_ON end ipc.control(66583) -- AP_PITCH_REF_INC_UP end end function trimwheel_ap_pitch_althold(change) if ipc.readUW(0x07BC) == 0 then -- AP disabled trimwheel_trim(change) elseif change > 0 then if ipc.readUW(0x07D0) > 0 then -- AP alt lock ipc.control(65816, 1) -- AP_ALT_HOLD_OFF end ipc.control(66584) -- AP_PITCH_REF_INC_DN elseif change < 0 then if ipc.readUW(0x07D0) > 0 then -- AP alt lock ipc.control(65816, 1) -- AP_ALT_HOLD_OFF end ipc.control(66583) -- AP_PITCH_REF_INC_UP end end function trimwheel_c182(change) if ipc.readUW(0x07BC) == 0 then -- AP disabled trimwheel_trim(change) elseif change > 0 then ipc.writeLvar("kap140_dn_button", 1) elseif change < 0 then ipc.writeLvar("kap140_up_button", 1) else ipc.writeLvar("kap140_dn_button", 0) ipc.writeLvar("kap140_up_button", 0) end end function aircraftchange(eventtype) if ipc.readSTR(0x3D00, 14) == "C337 Skymaster" then trimwheel = trimwheel_ap_pitch_atthold elseif ipc.readSTR(0x3D00, 5) == "C182_" then trimwheel = trimwheel_c182 elseif ipc.readSTR(0x3D00, 10) == "Cessna 441" then trimwheel = trimwheel_ap_vs elseif ipc.readSTR(0x3D00, 20) == "Boeing Stratocruiser" then trimwheel = trimwheel_ap_pitch_althold else trimwheel = trimwheel_trim end end aircraftchange(nil) -- initialize at least once function checkvalue(val) if prev ~= nil and val ~= prev then -- axis moved if math.abs(val) > boundary then ipc.display(string.format( "Warning:\n\n" .. "Trim wheel value near boundary: %d\n" .. "Reconnect to restore full range.\n", val), 10) else ipc.display("") end trimwheel(val - prev) end prev = val end event.sim(AIRCRAFTCHANGE, "aircraftchange") event.param("checkvalue") event.button(joystick, button_dn, "trimbutton") event.button(joystick, button_up, "trimbutton")
JessicaZ Posted November 15, 2017 Report Posted November 15, 2017 Thank you so much! This really works well! I modified the script slightly, but this really is an idea solution. Jessica -- Using a trim wheel axis to operate with trim INC and DEC instead -- http://forum.simflight.com/topic/72492-using-a-trim-wheel-axis-to-operate-with-trim-inc-and-dec-instead/ -- -- [Auto] -- 1=Lua trimwheel -- assign your axis, in the normal FS controls assignment on the left, to "Luavalue trimwheel". boundary = 16384-2048 function trimwheel_trim(change) trim = ipc.readSW(0x0BC0) - change if trim < -16384 then trim = -16384 elseif trim > 16383 then trim = 16383 end ipc.writeSW(0x0BC0, trim) end function trimwheel_ap_vs(change) if ipc.readUW(0x07BC) == 0 then -- AP disabled trimwheel_trim(change) elseif change > 0 then ipc.control(65895) -- AP_VS_VAR_DEC elseif change < 0 then ipc.control(65894) -- AP_VS_VAR_INC end end function trimwheel_ap_pitch(change) if ipc.readUW(0x07BC) == 0 then -- AP disabled trimwheel_trim(change) elseif change > 0 then ipc.control(66584) -- AP_PITCH_REF_INC_DN elseif change < 0 then ipc.control(66583) -- AP_PITCH_REF_INC_UP end end function trimwheel_ap_pitch_atthold(change) if ipc.readUW(0x07BC) == 0 then -- AP disabled trimwheel_trim(change) elseif change > 0 then if ipc.readUW(0x07D0) > 0 then -- AP alt lock ipc.control(65804, 1) -- AP_ATT_HOLD_ON end ipc.control(66584) -- AP_PITCH_REF_INC_DN elseif change < 0 then if ipc.readUW(0x07D0) > 0 then -- AP alt lock ipc.control(65804, 1) -- AP_ATT_HOLD_ON end ipc.control(66583) -- AP_PITCH_REF_INC_UP end end function trimwheel_ap_pitch_althold(change) if ipc.readUW(0x07BC) == 0 then -- AP disabled trimwheel_trim(change) elseif change > 0 then if ipc.readUW(0x07D0) > 0 then -- AP alt lock ipc.control(65816, 1) -- AP_ALT_HOLD_OFF end ipc.control(66584) -- AP_PITCH_REF_INC_DN elseif change < 0 then if ipc.readUW(0x07D0) > 0 then -- AP alt lock ipc.control(65816, 1) -- AP_ALT_HOLD_OFF end ipc.control(66583) -- AP_PITCH_REF_INC_UP end end function trimwheel_c182(change) if ipc.readUW(0x07BC) == 0 then -- AP disabled trimwheel_trim(change) elseif change > 0 then ipc.writeLvar("kap140_dn_button", 1) elseif change < 0 then ipc.writeLvar("kap140_up_button", 1) else ipc.writeLvar("kap140_dn_button", 0) ipc.writeLvar("kap140_up_button", 0) end end function aircraftchange(eventtype) if ipc.readSTR(0x3D00, 5) == "C182_" then trimwheel = trimwheel_c182 elseif ipc.readSTR(0x3D00, 12) == "Carenado A36" then trimwheel = trimwheel_ap_vs else trimwheel = trimwheel_trim end end aircraftchange(nil) -- initialize at least once function checkvalue(val) if prev ~= nil and val ~= prev then -- axis moved if math.abs(val) > boundary then ipc.display(string.format( "Warning:\n\n" .. "Trim wheel value near boundary: %d\n" .. "Reconnect to restore full range.\n", val), 10) else ipc.display("") end trimwheel(val - prev) end prev = val end event.sim(AIRCRAFTCHANGE, "aircraftchange") event.param("checkvalue")
Alan Phillips Posted December 21, 2017 Report Posted December 21, 2017 (edited) Please forgive me I am new to Lua and the finer areas of FSUIPC. I am using Prepar3d v4.1 and FSUIPC v5.122 I attempted to set this up and I'm a little confused. Is 'Luavalue trimwheel' supposed to be seen as an Event in the Axis Controls Section of the P3d Controls menu, then you assign the Axis Control you want to use to that Event ? I'm not seeing it for some reason in the list of events. I have attached the FSUIPC and also the trimwheel log files. Would be grateful if someone could offer me some guidance. Regards, Alan Phillips FSUIPC5.log trimwheel.log Edited December 21, 2017 by Alan Phillips Wrong FSUIPC version in text.
ThomasAH Posted December 22, 2017 Report Posted December 22, 2017 You won't see the axis because you have no trim wheel, at least your log only shows joystick and rudder. You can still use the buttons part of my script above though and ignore everything related to the trim axis. Here you have to set the joystick letter and button numbers in the script.
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