Introduction: How to Make a Custom Control Panel for Elite Dangerous, or Any Other Game

About: Engineer, Designer, Technologist...

So you want to make a custom switch panel for Elite Dangerous, or some other game, huh? It's easier than you might think. I made one, and people like it... My original post on Reddit

If you've never used an Arduino or done any coding, this is a pretty good place to start. If you're not good at soldering now, you will be by the time you have finished. And if you've ever wanted to use the term 'matrix' in conversation without referring to an overrated Hollywood movie, then read on. You're in the right place.

First of all, there are a couple of fundamentals to understand before we continue. Have a cursory glance at these articles. Go there, understand what a matrix is, why it's useful here, and then come back..

You're back? Good. It's not rocket surgery, is it?

First of all you're going to want to draw a layout. Feel free to use the layout provided if you intend to follow my design completely. If you want to customise or completely change the layout, you should use a geometrically accurate drawing application. I used Adobe Illustrator.

The layout will be wholly dependant on your choice of buttons and switches. Research every switch fully, order samples and measure everything before committing to laser cutting or engraving.

Ok lets talk about parts...

Step 1: Parts & Tools

For my controller, I sourced almost everything through eBay. Here are links to every part I used in the build.

7 x Momentary ON/OFF Toggle Switch. SPST = Spring return. Missile/Flip covers available.

30 x Rectangular Illuminated Push-Button Switch. Removable covers.

2 x ON/OFF/EMERGENCY STOP Switch Box. I could not find the same buttons individually.

1 x Retex Sloped Console Enclosure (33020102). Panel size is 249 x 161 mm

1 x Teensy 3.2 Programmable Microcontroller. Teensy is the only Arduino compatible PMC with native USB-HID that I know of.

1 x 5V - 12V Step-Up Module. This is to power the LEDs, which in these particular switches are 12V. More on this later.

1 x 220 Ohm Resistor. This is to regulate current through the matrix. How this works is actually a mystery to me.

1 x USB-B Panel Mount Socket. To attach to the rear of the unit.

1 x USB-A to USB-B Cable. To cable to the PC.

1 x USB-MINI to USB-A Cable. To link the Teensy with the panel mount socket.

1 x Custom Engraved Front Panel. I recommend against hand drilling the front panel.

All of the above parts cost me approximately £150. That includes the laser cutting and engraving. There are many reasons why I went to a professional engraver. The accuracy of the cutting is important due to the close proximity of the buttons to one another. That weakens the panel and hand drilling would almost certainly break the plastic. The enclosure comes with a blank Aluminium panel, so feel free to hand drill that, but be prepared for a battle with button placement. Want aluminium laser/waterjet cut? Be prepared to pay for it. So I went to a professional, and he showed me a piece of Traffolyte. It's rigid, laminated, and it provides two colour engraving with lasers. Affordable and perfect for this job. Expect to pay more than the £50 that I paid though. I got a shady deal.

Now for the tools and consumables.

  • Wire
  • Cable Ties
  • Soldering Iron
  • Solder
  • Wire
  • Cutters
  • Screwdrivers
  • Printable transparency film/acetate

Depending on your choice of buttons, you might also need...

  • Drill
  • Super Glue
  • Hot Glue Gun
  • Dremel & Bits
  • Drill & Bits

Grab your parts and tools, and lets talk about labelling buttons...

Step 2: Button Assembly & Labelling

Some of your buttons will require assembly. In particular the illuminated or labelled ones. The rectangular buttons in my design come in 5 parts. Switch, LED module, button, plate, and cover. Button labels are inserted at this point so pay attention to orientation. We want all the buttons to be oriented the same way so that when we flip the board over, all of the contacts are nicely uniform, making soldering a lot easier.

Labelling buttons is super easy. Use your/my layout and add text within the boundaries of the buttons. Print this on transparency and cut to size. Slot each one into the relevant buttons and you're done.

Other buttons might require some modification in order to fit in the enclosure. You can see in the next step that the front edge of the enclosure has less clearance inside than the rear. I had to use a different contactor than the ones that came with the large round buttons, because the ones supplied were far too deep to fit inside. These were applied with super glue and hot glue for support. Be careful of this when ordering buttons. I would recommend something more like this: 22mm Stainless Push Button Switch

Step 3: Unit Assembly & Wiring

It's time to look under the old girl's dress. As you can see, the assembly of the unit itself is quite straightforward. Insert the buttons and screw them down securely. Make sure you're still considering the orientation. Don't attach the Teensy or step-up module to the plate yet. We need to solder those first.

Remember when I sent you away to read about matrices? This is where we use that knowledge. Look at the photo above. See the red wires? That's the button matrix. The blue wires are for the LEDs inside the buttons. The reason for using a matrix of buttons is simple. We will require far fewer pins on our Teensy. If all buttons were wired individually, we would need 40 pins, one for each button. By using a matrix of 6 rows and 8 columns, we can reduce that to 14 (6 + 8). Therefore a Teensy 3.1 or 3.2 will suffice.

I have provided a simplified drawing of the button matrix to help you understand how mine is connected, and where there are omissions from the matrix. You will need this to understand the code later on. Don't worry, it will all make sense soon.

Step 4: Soldering

Rule #1 of soldering - Do not be on fire.

Prepare your workspace. Make sure there are no flammable materials nearby. Have good ventilation and take breaks. Clean your tip regularly. Just the tip, mind. It's pretty arduous but very satisfying when complete. This is not a soldering tutorial, so I won't tell you how to do everything here. Just follow the schematic and prepare small lengths of wire to speed up the process. Multiple pins will require two wires to be soldered together. That is the most challenging part of the whole build.

I soldered pins onto my Teensy, and inserted it into a breadboard. However, I recommend soldering the 14 primary matrix wires directly to the Teensy, along with the power output to the LED step-up module.

This is also a good time to solder the 220 Ohm resistor in line with the first column wire. This can be seen on my breadboard above. I'm not sure why it needs it, but without it the matrix will not behave. Using a resistor prevents a whole row or column from being triggered by a single button press. Trust me, use one.

The LEDs are soldered together in parallel. This ensures that the same voltage is applied to all. However different colour LEDs have different current draws. Expect brightness uniformity issues with this design. Alternatively use 5V LEDs, but I could not find 5V LED modules for these particular buttons. Every single one would have to be de-soldered and re-soldered manually. Ain't nobody got time for that. So, a 12V step-up is necessary.

I lied to you earlier, for simplicity's sake. All of the button matrix wires are red. All except for the 8 main column wires. I made these blue so that it was clear to see which were for the rows, and which were for the columns.

One last point. Surely by now you have realised that the panel is upside-down. Therefore follow the drawings from left to right, but work from right to left.

It's time to talk about the code...

Step 5: The Code

I have provided the code that I am using in my CF-1 controller. Scroll through it in the Arduino editor software and read the comments in grey. If it all makes sense to you then great! If not, stick around. I'll go into a little more detail.

The first thing at the top is the inclusion of the Keypad library.

#include <Key.h>
#include <Keypad.h>

This is an off-the-shelf bit of code that guides the Teensy to understand our references to key presses and instructions. The Keypad library has a lot of built in functionality for things like press, hold, release and idle. We will only be using the press and release commands.

Then we define the rows and columns in our matrix, and a character to each of our desired button presses.

const byte ROWS = 6; // Six rows
const byte COLS = 8; // Eight columns
char keys[ROWS][COLS] = {
  {'0', '1', '2', '3', '4', '5', '6', '7'},
  {'8', '9', 'A', 'B', 'C', 'D', 'E', 'F'},
  {'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N'},
  {'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V'},
  {'W', 'X', 'Y', 'Z', '[', ']', ';', '#'},
  {',', '.', '/', '`', '-', '=', '*', '+'},

This does not relate to the key that the PC will receive when buttons are pressed. You can see that there are numbers, followed by letters, followed by punctuation. Using the char variable restricts us to using a single character. So for 48 buttons, we need 48 different characters. This allows us to separate the code from the output, so editing the output is easier later on. The actual output keystrokes come later.

The next part is to define the pins that the matrix is connected to.

byte colPins[COLS] = { 0, 1, 2, 3, 4, 5, 6, 7 };
byte rowPins[ROWS] = { 14, 15, 16, 17, 18, 19, };

Now we start defining instructions.

if ( kpd.key[i].kchar == '0' ) // SRV TURRET
         switch (kpd.key[i].kstate) {
            case PRESSED:
              msg = " PRESSED.";
            case HOLD:
              msg = " HOLD.";
            case RELEASED:
              msg = " RELEASED.";
            case IDLE:
              msg = " IDLE.";

My code loops indefinitely. It scans the keypad for changes, then ascertains whether it was a press or a release. Then it calls an instruction based on which key it was, what state it is now in, and outputs the corresponding key press, or release, to the PC via USB, just like a regular keyboard. When it's done that, it breaks the loop and starts again, scanning for more changes. You can press up to 10 buttons simultaneously.

These are the press and release commands.;

If you want to edit the keystrokes, you might need this:

Be aware that the USB keyboard output in the provided code, is based on my arbitrary and completely ass backwards as f**k control method. Please feel free to change the keystrokes to your own control method within this code. Or be as backwards as me. Your call. Don't change the keypad layout at the top though. That will cause all manner of hell for you. Edit the (KEY_?) within each set of instructions lower down in the code. They're all commented well.

Upload to the Teensy.


Step 6: Final Assembly

We're on the home stretch. If you have followed the schematic correctly, and uploaded the code successfully, connecting the Teensy to a PC should light all of the LEDs and button presses should be sending a single keystroke to the PC. Just open a word processor and start hitting buttons. Do they correspond to the layout? If not, go back and check your matrix first. That's the easiest part to cock up.

If all is well, we can make the final USB connections and close the case. Take the USB parts and connect them all up. It is worth noting at this point that multiple in-line connectors and couplings can cause voltage drop and prevent the unit from operating. The way I have done it is merely a matter of resources. A better way would be to have a standard USB-MINI cable directly between the Teensy and the PC. You would need an appropriate cable gland for the rear of the unit, as opposed to a panel mount USB socket.

Step 7: Play Games

Congratulations! You have just made yourself a fully custom controller for your favourite game. Or a really disorientating keyboard. You choose.

Assign controls in the game the usual way.

Microcontroller Contest 2017

Second Prize in the
Microcontroller Contest 2017