I finished my Teensy project I've been working on for the last week, so I figured I'd post it here to show it off, and hopefully someone will find at least part of it useful. It's a replacement controller for a nice USB joystick with a flawed MCU. The source code and necessary files are all in the zip file attached to this post.
Intro:
The Thrustmaster T.Flight Hotas X is a budget HOTAS (Hands On Throttle-And-Stick) controller. While a good value for the money, there are some shortcomings. For me, the biggest one was the large dead zone in the middle of the axes. This made control choppy and inconsistent crossing the axes, and made it very difficult to aim near the center (where you're typically aiming). While you can install software to allow gain adjustment to give more movement near the center, the underlying problem can't be fixed in software, since the joystick controller simply tells the computer that it's _at_ 0 anytime it's _near_ 0 (approximately the center 17%!).
Thrustmaster has recently released a HOTAS called the Hotas 4, which looks nearly identical, but has a new controller board that greatly improved the deadzone... so I'd recommend purchasing that, even though it's about $30 more (this mod should work similarly on the Hotas 4, though not really necessary). In my case, I already had the Hotas X, so rather than let it sit unused, I started working on this mod.
Moving forward:
I decided that I should replace the stock controller with my own microcontroller... and from a quick search, found that the Teensy would be a very good match, with lots of analog and digital pins. I already had a Teensy 3.1 that I bought as an add-on to an OSH Park PCB order, and within a couple hours, I had my first prototype up and running. EASY!
I needed to make changes from the available joystick examples to make it exactly how I wanted, so after a few frustrating hours of figuring out the details of USB descriptors, I got it to show up as an 8-axis, 32-button + hat joystick. I tweaked the back-end code to actually support those, and then made the main Arduino sketch, which actually set up and read the hardware, and reported the proper values.
Hardware:
Making this work requires removing the wires from the original controller board and connecting them to the corresponding pins on the Teensy. I used a Teensy 3.1, though it should work on a 3.0, 3.1, or 3.2. You can see the original wire connections for the Hotas X in hotasx_wires.jpg , and described with wire colors in hotasx_wires.txt (you should verify that your wire colors are the same). Then connect the wires to the corresponding Teensy pins referenced in teensy_hotasx.pdf .
You also need to connect your GND wires to the AGND (analog ground) pin on the Teensy, as they're the GND of the analog pots, and connect the 3.3V wires to the Teensy's 3.3V pins. As there are a lot of wires, and not a lot of holes on the Teensy, and connected all of my GND wires together and 3.3V wires together, then connected them to the Teensy with short jumper wires (so I only needed to put a single wire into the Teensy's AGND and 3.3V holes).
If you want to use the buttons, switch, and LED soldered to the original PCB, you need to cut the traces going to them (so the original unpowered controller doesn't interfere), and solder a wire from them to the Teensy (shown in orig_pcb_wires.jpg ). You also need to connect GND between the Teensy and the original board. The LED on the original board is wired with the series resistor connected to 3.3V, so I rotated the LED 180 degrees, cut the connection to 3.3V, jumpered it to GND, and connected the other side to the Teensy I/O (so I could reuse the original series resistor and not have to connect 3.3V to the board).
You also need to connect the USB cable. I wanted to reuse the original cable, but needed a little bit more length inside the case, so I slid the rubber boot up the cable a bit, and soldered the USB cables to the pads on the bottom of the Teensy. Sliding the rubber boot isn't easy, as it's glued to the cable... so it took a lot of effort to break it free. The normal way would be to just use your own Micro USB cable plugged into the Teensy, and fed through the USB cable hole in the case.
Finally, you need to find a place for the board inside the joystick There's plenty of room, so I picked a spot along the curved side with the tail ( teensy_inside.jpg ), as the cables seemed to naturally reach easily there. For now, it's just sitting in there. With all the wires, it's not going anywhere and is well insulated from any metal... but once I'm done for good I'll probably just zip tie it to a screw post.
Unrelated to the Teensy mod, but I also didn't like the large detent in the throttle at 50%, so I opened it up, used a Dremel to grind off the bump on the throttle, used very course sandpaper to rough up both sides (to make sure it had some friction to stay in place), then used Nyogel to re-lubricate it ( throttle_center_mod.jpg ).
Software:
Once everything is wired up, you need to load the code to the Teensy. There were several files changed from the default Teensy code. Under the Arduino hardware\teensy\avr\cores\teensy3 directory, you need to put the .c, .cpp, and .h files. Under the Arduino hardware\teensy\avr directory, you need the boards.txt file. You should back up your original files as my files may affect compatibility with other existing code.
Once those files are in place, load HotasX.ino (thanks to Paul Stoffregen for the code I based it off of!), and under Tools, select the Teensy board you're using and USB type of HotasX. Then click upload and it'll send the program to the joystick, and it should show up on your computer as an 8-axis, 32-button + hat joystick.
Future:
While this is fully working, there is room for improvement/expansion in the future, which I expect to do once I put some time into using this and determining my needs. I have code to drive the LEDs, but I don't currently use them for anything. I expect that I'll use them with future button mappings to show the user what the current mode is (i.e. Button 5 is mapped to 5 when the home LED is off, but 18 when in Green mode and 24 when in Red mode)... or as feedback to special modes, such as blinking the Preset LED during recalibration, setting a dead zone, etc.
There are also extra inputs that I've both assigned and not yet assigned. I have 3 more axes for Rudders and Toe Brakes. These are enabled when the pedal enable pin is grounded (so they can be added/removed without changing code), but without them being connected, they're reported as fixed values. There are also misc. I/O pins that can be used for more switches, buttons, talking to external hardware, etc.
Lastly, at some point I'd like to add the ability to have rumble motors in the joystick. I tentatively assigned the PWM pins to rumble functionality, though I haven't figured out exactly how to make the PC see the joystick as a rumble capable joystick.
Using:
Once everything is done, you're ready to simply use the joystick. When you plug it in, make sure all axes are centered, except the throttle which should be at 100% (since I no longer have the 50% detent to find the middle). Other than that, enjoy playing games with a joystick that is extremely responsive, and fully customizable and open source, and best of all... made by you!
DogP
Intro:
The Thrustmaster T.Flight Hotas X is a budget HOTAS (Hands On Throttle-And-Stick) controller. While a good value for the money, there are some shortcomings. For me, the biggest one was the large dead zone in the middle of the axes. This made control choppy and inconsistent crossing the axes, and made it very difficult to aim near the center (where you're typically aiming). While you can install software to allow gain adjustment to give more movement near the center, the underlying problem can't be fixed in software, since the joystick controller simply tells the computer that it's _at_ 0 anytime it's _near_ 0 (approximately the center 17%!).
Thrustmaster has recently released a HOTAS called the Hotas 4, which looks nearly identical, but has a new controller board that greatly improved the deadzone... so I'd recommend purchasing that, even though it's about $30 more (this mod should work similarly on the Hotas 4, though not really necessary). In my case, I already had the Hotas X, so rather than let it sit unused, I started working on this mod.
Moving forward:
I decided that I should replace the stock controller with my own microcontroller... and from a quick search, found that the Teensy would be a very good match, with lots of analog and digital pins. I already had a Teensy 3.1 that I bought as an add-on to an OSH Park PCB order, and within a couple hours, I had my first prototype up and running. EASY!
I needed to make changes from the available joystick examples to make it exactly how I wanted, so after a few frustrating hours of figuring out the details of USB descriptors, I got it to show up as an 8-axis, 32-button + hat joystick. I tweaked the back-end code to actually support those, and then made the main Arduino sketch, which actually set up and read the hardware, and reported the proper values.
Hardware:
Making this work requires removing the wires from the original controller board and connecting them to the corresponding pins on the Teensy. I used a Teensy 3.1, though it should work on a 3.0, 3.1, or 3.2. You can see the original wire connections for the Hotas X in hotasx_wires.jpg , and described with wire colors in hotasx_wires.txt (you should verify that your wire colors are the same). Then connect the wires to the corresponding Teensy pins referenced in teensy_hotasx.pdf .
You also need to connect your GND wires to the AGND (analog ground) pin on the Teensy, as they're the GND of the analog pots, and connect the 3.3V wires to the Teensy's 3.3V pins. As there are a lot of wires, and not a lot of holes on the Teensy, and connected all of my GND wires together and 3.3V wires together, then connected them to the Teensy with short jumper wires (so I only needed to put a single wire into the Teensy's AGND and 3.3V holes).
If you want to use the buttons, switch, and LED soldered to the original PCB, you need to cut the traces going to them (so the original unpowered controller doesn't interfere), and solder a wire from them to the Teensy (shown in orig_pcb_wires.jpg ). You also need to connect GND between the Teensy and the original board. The LED on the original board is wired with the series resistor connected to 3.3V, so I rotated the LED 180 degrees, cut the connection to 3.3V, jumpered it to GND, and connected the other side to the Teensy I/O (so I could reuse the original series resistor and not have to connect 3.3V to the board).
You also need to connect the USB cable. I wanted to reuse the original cable, but needed a little bit more length inside the case, so I slid the rubber boot up the cable a bit, and soldered the USB cables to the pads on the bottom of the Teensy. Sliding the rubber boot isn't easy, as it's glued to the cable... so it took a lot of effort to break it free. The normal way would be to just use your own Micro USB cable plugged into the Teensy, and fed through the USB cable hole in the case.
Finally, you need to find a place for the board inside the joystick There's plenty of room, so I picked a spot along the curved side with the tail ( teensy_inside.jpg ), as the cables seemed to naturally reach easily there. For now, it's just sitting in there. With all the wires, it's not going anywhere and is well insulated from any metal... but once I'm done for good I'll probably just zip tie it to a screw post.
Unrelated to the Teensy mod, but I also didn't like the large detent in the throttle at 50%, so I opened it up, used a Dremel to grind off the bump on the throttle, used very course sandpaper to rough up both sides (to make sure it had some friction to stay in place), then used Nyogel to re-lubricate it ( throttle_center_mod.jpg ).
Software:
Once everything is wired up, you need to load the code to the Teensy. There were several files changed from the default Teensy code. Under the Arduino hardware\teensy\avr\cores\teensy3 directory, you need to put the .c, .cpp, and .h files. Under the Arduino hardware\teensy\avr directory, you need the boards.txt file. You should back up your original files as my files may affect compatibility with other existing code.
Once those files are in place, load HotasX.ino (thanks to Paul Stoffregen for the code I based it off of!), and under Tools, select the Teensy board you're using and USB type of HotasX. Then click upload and it'll send the program to the joystick, and it should show up on your computer as an 8-axis, 32-button + hat joystick.
Future:
While this is fully working, there is room for improvement/expansion in the future, which I expect to do once I put some time into using this and determining my needs. I have code to drive the LEDs, but I don't currently use them for anything. I expect that I'll use them with future button mappings to show the user what the current mode is (i.e. Button 5 is mapped to 5 when the home LED is off, but 18 when in Green mode and 24 when in Red mode)... or as feedback to special modes, such as blinking the Preset LED during recalibration, setting a dead zone, etc.
There are also extra inputs that I've both assigned and not yet assigned. I have 3 more axes for Rudders and Toe Brakes. These are enabled when the pedal enable pin is grounded (so they can be added/removed without changing code), but without them being connected, they're reported as fixed values. There are also misc. I/O pins that can be used for more switches, buttons, talking to external hardware, etc.
Lastly, at some point I'd like to add the ability to have rumble motors in the joystick. I tentatively assigned the PWM pins to rumble functionality, though I haven't figured out exactly how to make the PC see the joystick as a rumble capable joystick.
Using:
Once everything is done, you're ready to simply use the joystick. When you plug it in, make sure all axes are centered, except the throttle which should be at 100% (since I no longer have the 50% detent to find the middle). Other than that, enjoy playing games with a joystick that is extremely responsive, and fully customizable and open source, and best of all... made by you!
DogP