Thrustmaster TQS LED
-
I’ve asked TM for a SDK or API to create an interaction tool linked to F4ShareMemory. No answer yet.
If someone know how to sniff out “usb communication” to build a driver’s overlay, you’d make me happy ! -
@benco said in Thrustmaster TQS LED:
I’ve asked TM for a SDK or API to create an interaction tool linked to F4ShareMemory. No answer yet.
If someone know how to sniff out “usb communication” to build a driver’s overlay, you’d make me happy !Good luck with getting anything from Thrustmaster.
I have no experience of F4ShareMemory… yet. If were to (probably will) do it, I would create an app to get what you need from F4ShareMemory and write it to a file or to a TCP socket.
Target can read a file or handle TCP packet events.
-
@benco USB should be serial communication, right? So that might actually be relatively easy to reverse engineer. I’d love to help, but don’t have a TQS. Maybe try using Wireshark?
@scubapics I’ve used F4SharedMem now for two projects: the Virtual Crew Chief in VoiceAttack and to drive the panels of my simpit. Let me know if I can help with the shared memory part of the project.
-
@Ricky I’ve pretty much got it sorted. I’ll probably have it finished in a day or so with a fair wind.
-
@scubapics
Really looking forward to this! Thank you for taking on this project!
Regards,
Tomcattwo
(VoiceClone) -
@Tomcattwo wait no more. It is done.
The solution consists of Thrustmaster TARGET scripts and an executable called BMS2Target.exe.
BMS2Target.exe is a console application for 64bit Windows. I have not built a 32bit version and I would expect 99.99% of users will not be on Windows XP!
BMS2Target.exe reads the Falcon BMS shared memory and sends the relevant lamp data to the Thrustmaster TARGET software that is running the ViperTQSLEDSync.tmc script. The data is sent via TCP. Packets are only sent if the data changes and the script handles the packet through an event. Thus it is fairly efficient.
The BMS2Target.exe reads the Falcon shared memory every 100ms (0.1 seconds). Not too taxing on the system yet fast enough so that we humans won’t notice any lag.
Copy BMS2Target.exe to anywhere you like on your PC. Copy ViperTQSLEDSync.tmc wherever you keep your TARGET scripts.
If you are using a TARGET script to configure your ViperTQS, you’ll have to figure out how to merge ViperTQSLEDSync.tmc and your script yourself. Also don’t expect any support if you modify or merge ViperTQSLEDSync.tmc with your own. Ideally, you should be using the Alternative Launcher to map your ViperTQS to Falcon BMS.
You can run BMS2Target.exe before or after starting Thrustmaster Target and launching ViperTQSLEDSync.tmc script and also before or after starting BMS.
Give it a whizz. I’ve done basic testing. There is bound to be some fine-tuning to do. So let me know how you get on.
Oh, one more thing. The Threat Warning AUX lamps on the TQS have their limitations. The ACT/PWR switch has only one LED, not two as per the simulation. So I have programmed it to be off when there is no activity and on when there is. The ALTITUDE switch has two LEDs but they both illuminate the whole switch! One is red and one is green. So I have programmed it to be red when LOW is activated and green when LOW is not activated.
You can get the files from here:
https://forum.falcon-bms.com/topic/26193/bms-to-thrustmaster-vipertqs-led-controller
-
@scubapics
Fantastic Work! Based on this, I will disable Win 11 Core Memory Integrity and install TARGET Software and give it a spin! Thank you for the great work on this. Will let you know if I run into any issues.
Regards,
Tomcattwo
(VoiceClone) -
@scubapics ,
Now for the Speedbrake!F4SharedMem variable for SpeedBrake is:
CurrentFlightData.speedBrake
and it apparently reads speed brake position form 0 to 1, 0 being fully closed and 1 being 60 degrees open.
So if we can set BMS2Target to read speedBrake position = 0.2, 0.4, 0.6, 0.8 and 1.0, we can get the LEDs for speedbrakes programmed in the script to respond. Would need to code it to toggle light on if off and off if on when the changes occur.Also, is it possible to have BMS2Target work for any Block of F-16? Don’t know if that is a hard to do or easy to do…
Regards,
TC2 -
@Tomcattwo said in Thrustmaster TQS LED:
@scubapics ,
Now for the Speedbrake!F4SharedMem variable for SpeedBrake is:
CurrentFlightData.speedBrake
and it apparently reads speed brake position form 0 to 1, 0 being fully closed and 1 being 60 degrees open.
So if we can set BMS2Target to read speedBrake position = 0.2, 0.4, 0.6, 0.8 and 1.0, we can get the LEDs for speedbrakes programmed in the script to respond. Would need to code it to toggle light on if off and off if on when the changes occur.Also, is it possible to have BMS2Target work for any Block of F-16? Don’t know if that is a hard to do or easy to do…
Regards,
TC2You don’t ask for much
Speedbrake is a good idea. Someone else on DCS asked if they could be on when locked on by radar and flashing while missile warning is on.
As for other blocks… anything is possible if it is supported in the shared memory.
-
@benco Can we still use the Alt Launcher key mapping in conjuction with this? Last time I tried Target, it overroad Alt Launcher.
-
@MailMan The buttons of the TQS aren’t merged into the Thrustmaster Virtual Game Controller. This is achieved through the “MODE_KEEPENABLED” flag in ViperTQSLEDSync.tmc for the TQS (or ButtonBox if you add this one). The Alt Launcher just sees everything like if T.A.R.G.E.T. isn’t running.
-
@MailMan said in Thrustmaster TQS LED:
@benco Can we still use the Alt Launcher key mapping in conjuction with this? Last time I tried Target, it overroad Alt Launcher.
Yes
-
@r00t Man could you send your profile worging al leds a without problem wtih BMS?
-
@thunder888 There would be no benefit to the solution @scubapics already created. Any reason why you don’t give it a try? I would recommend to do so.
His solution responds to sim data by reading the shared memory Falcon holds relevant data and sending it to the Button Box. It should work for TWA, Wheels and the Gear Handle. It is easily readable and extendable because it’s well designed.
It has to be launched from the T.A.R.G.E.T. Script Editor instead of the T.A.R.G.E.T. GUI, tho. And you need to execute the .exe he provided because without doing so, nothing will ever light on or of. But because it just takes care of the LED on/of/blink status, you can map your keys and axis in the Alternative Launcher (much better user experience than doing anything in T.A.R.G.E.T GUI).
I was just testing how to illumminate the Landing Gear and the Wheels in the GUI for demo purposes. My GUI “profile” doesn’t do more than that. I did not map any other buttons or keys in the profile. I just tried to understand how T.A.R.G.E.T. GUI works. The profile is therefore useless - gaming wise. And I really do not plan to use T.A.R.G.E.T. GUI again if I have the choice.The T.A.R.G.E.T. script code snippet I posted above (the one with the two CHAIN statements) won’t help you either. You’ll reach the limits of the “builtin” functions (CHAIN, SEQ, REXEC, EXEC,…) very soon. They are not very flexible. You’ll end up writing your own functions to have more control over what happens when. The “builtin” stuff seems to be ment as a “quickwin set” to get you startet.
The T.A.R.G.E.T. Script I created for the video (which you can see enlightening TWA LEDs there) is exactly as useless as all I mentioned above - gaming wise. It just statically does LED on/off/blink with the four TWA LEDs. I created a some functions there because the builtin stuff didn’t work well for the task. My code is horrible, and it will get out of “sync with your SIM” quickly - works as designed. I think it would do more harm than good posting it here.
I like to poke around too. But I will never write anything as effective or with good coding style…let alone within any acceptable timeframe. I’m trying to get my challange done for educational purposes only. A python based equivalent of the executable above reading the shared memory and updateing the LEDs with the T.A.R.G.E.T script scubapics provided. No need to reinvent the wheel
-
@thunder888
@r00t ID spot on. @scubapics Target script and BMS2Target.exe work perfectly and are easy to use/run. I have tested them so far on F-16 CM Blk 50 and Blk 40 and they function properly, as Scubapics described above. BMS2Target.exe will become the de-facto app to use to communicate with the Viper Panel LEDs.Because the script is well designed, it only controls the LEDs and does not allow TARGET to “pollute” your joystick or MFD or throttle key assignments managed by Alternate Launcher. @scubapics created a superb solution for accessing real-time flight data from BMS to control Thrustmaster Viper Panel LEDs.
Regards,
Tomcattwo
(VoiceClone) -
@scubapics Can your BMS2Target.exe work with the TARGET Script Editor for Warthog? If so, do you think it would be possible to modify the ViperTQSLEDSync.tmc for use with the Warthog throttle?
-
@Tomcattwo said in Thrustmaster TQS LED:
Thanks for your answers.I’ll continue with @scubapics solution like you said. He made a great job.
-
@jc1 said in Thrustmaster TQS LED:
@scubapics Can your BMS2Target.exe work with the TARGET Script Editor for Warthog? If so, do you think it would be possible to modify the ViperTQSLEDSync.tmc for use with the Warthog throttle?
It was designed with expansion to the warthog in mind so yes. Although I’m not fully aware of the led capabilities of the warthog other than the columns that are not associated with any real indicators and the ability to dim the back lighting.
It’s shows just how little I have used my warthog. I bought it when they were first released!
-
@scubapics accordings to the docs, LED dim is OFF plus 5 levels of intensity. AFAIR the docs, you can’t set intensity per LED, it’s one value for all 5 LEDs . This is kind of sad because it would be cool to use one LED instead of four to reflect different states for e.g. LG/wheels state (50% dim for LG handle down, 100% as soon as wheels are locked on LED1 for example).
Until something properly done by scubapics, I’d try something like below for just the wheels and LG handle lighting up LED 1 to 4. It is based on scubapics original .tmc he posted above.
Notes on the changes I made:
Warthog LEDs call should be LED instead of LEDV. the LED syntax is slightly different. The second arg is either 0 (on/off/toggle mode) or 1 (brightness mode). The third argument can be a representation of “On”, “Off” or “Toggle” (i.e. LED_CURRENT+LEDn, LED_CURRENT-LEDn, LED_CURRENT^LEDn).I’m unsure if LED needs multiple calls just like LEDV does to trigger so I left the while loop untouched.
I threw away the blink function to keep it short. I added “Throttle” instead of “ViperTQS” to the device list, renamed the function arguments accordingly. The SetLED() funtion uses LED instead of LEDV.
Don’t know if it works because I don’t own a Warthog Throttle and thus can’t test anything. Try it or ignore it until scubapics releases something that works and is included in his original. I’m just curious about if I got the basics right:
/*------------------------------------------------------------------------------- -- -- ViperTQSLEDSync.tmc - MODIFIED FOR WARTHOG THROTTLE, DON'T USE -- ON VIPERTQS -- prototype based on the genius work of slughead/scubapics -- if you want something that works properly, wait until someone with a clue -- incorporates everything into the original code ------------------------------------------------------------------------------*/ include "target.tmh" define LED_GEAR_NOSE LED1 define LED_GEAR_LEFT LED2 define LED_GEAR_RIGHT LED3 define LED_GEAR_WARNING LED4 define LED_RWR_SEARCH 14 define LED_RWR_A_POWER 15 define LED_RWR_LOW_ALT_RED 16 define LED_RWR_LOW_ALT_GREEN 17 define LED_RWR_SYSTEM_POWER 18 define LED_STATE_OFF 0 define LED_STATE_ON 1 // GEAR NOSE (OFF/GREEN/RED/YELLOW/BLUE/LBLUE/PURPLE/WHITE) // GEAR LEFT (OFF/GREEN/RED/YELLOW/BLUE/LBLUE/PURPLE/WHITE) // GEAR RIGHT (OFF/GREEN/RED/YELLOW/BLUE/LBLUE/PURPLE/WHITE) // GEAR WARNING (OFF/RED) // SEARCH (OFF/GREEN) // A POWER (OFF/GREEN) // LOW ALT (OFF/RED) // LOW ALT (OFF/GREEN) // SYSTEM POWER (OFF/GREEN) int main() { Configure(&Throttle, MODE_KEEPENABLED); Configure(&Joystick, MODE_EXCLUDED); Configure(&JoystickF18, MODE_EXCLUDED); Configure(&LMFD, MODE_EXCLUDED); Configure(&RMFD, MODE_EXCLUDED); Configure(&HCougar, MODE_EXCLUDED); Configure(&T16000, MODE_EXCLUDED); Configure(&T16000L, MODE_EXCLUDED); Configure(&TWCSThrottle, MODE_EXCLUDED); Configure(&TFRPRudder, MODE_EXCLUDED); Configure(&TFRPHARudder, MODE_EXCLUDED); Configure(&A320Pilot, MODE_EXCLUDED); Configure(&A320Copilot, MODE_EXCLUDED); Configure(&TCAQuadrant12, MODE_EXCLUDED); Configure(&TCAQuadrant34, MODE_EXCLUDED); Configure(&TCAQBoeing12, MODE_EXCLUDED); Configure(&TCAQBoeing34, MODE_EXCLUDED); Configure(&TCAYokeBoeing, MODE_EXCLUDED); Configure(&ViperTQS, MODE_EXCLUDED); //Configure(&ViperTQS, MODE_EXCLUDED); Configure(&ViperBBox, MODE_EXCLUDED); // TODO determine which Viper device is connected // and set a device variable so that both can be // supported without modifying the code. Configure(&TCASidestickXPilot, MODE_EXCLUDED); Configure(&TCASidestickXCopilot, MODE_EXCLUDED); //Configure(&FarmStickRight, MODE_EXCLUDED); //Configure(&FarmStickLeft, MODE_EXCLUDED); if(Init(&EventHandle)) return 1; RegisterGameCallback(2323, &TCPCallback); // attach TCPCallback procedure to TCP port 1000 SetKBRate(32, 50); SetKBLayout(KB_ENG); SetShiftButton(0, 0, 0, 0, 0, 0); ResetLeds(); } int EventHandle(int type, alias o, int x) { DefaultMapping(&o, x); } int TCPCallback(int buf, int size) { int i; char packet; Map(&packet, buf); Dim(&packet, size); char packet_string; Map(&packet_string, buf); Dim(&packet_string, size+1); packet_string[size] = 0; // null terminate so can be printed printf("%s : %d bytes received\xa", &packet_string, size); if (size == 0) return 0; if (packet[0] == 'q') // simulation exit { ResetLeds(); } else if (packet[0] == 'm') { // read the aircraft type // TODO for future expansion of other aircraft and throttle controllers } else if (packet[0] == 'u') // update status of lamps { SetLedStatus( packet[1] - '0', packet[2] - '0', packet[3] - '0', packet[4] - '0', packet[5] - '0', packet[6] - '0', packet[7] - '0', packet[8] - '0', packet[9] - '0', packet[10] - '0' ); } } int ResetLeds() { // initially set LED brightness SetLED(&Throttle, 1, 255); // 1 = LED_INTENSITY_MODE, 255 = full on SetLED(&Throttle, LED_GEAR_NOSE, LED_STATE_OFF); SetLED(&Throttle, LED_GEAR_LEFT, LED_STATE_OFF); SetLED(&Throttle, LED_GEAR_RIGHT, LED_STATE_OFF); SetLED(&Throttle, LED_GEAR_WARNING, LED_STATE_OFF); } int SetLedStatus ( byte gear_nose_status, byte gear_left_status, byte gear_right_status, byte gear_warning_status, byte rwr_search_status, byte rwr_activity_status, byte rwr_a_power_status, byte rwr_alt_low_status, byte rwr_alt_status, byte rwr_system_power_status ) { SetLED(&Throttle, LED_GEAR_NOSE, gear_nose_status); SetLED(&Throttle, LED_GEAR_LEFT, gear_left_status); SetLED(&Throttle, LED_GEAR_RIGHT, gear_right_status); SetLED(&Throttle, LED_GEAR_WARNING, gear_warning_status); } int flash_led = 0; int SetLED(alias dev, int led_index, int value) { int i; int mode; int switch_led; if (value == 0) { switch_led = LED_CURRENT-led_index; mode = 0; } else if (value == 1) { switch_led = LED_CURRENT+led_index; mode = 0; } else if (value == 255) { // 255 == set brightness for all leds switch_led = value; mode = 1; } i = 0; while (i<3) { ActKey(PULSE+KEYON+LED( &dev, mode, switch_led )); i = i+1; } }
-
I have started a new thread for discussion of the tool that I have created. Please refer to that thread for updates, bugs and enhancement requests.
https://forum.falcon-bms.com/topic/26193/bms-to-thrustmaster-vipertqs-led-controller