Introduction: Custom Macro Mechanical Keypad

About: Good projects, badly executed

In this Instructable I will be taking you through the basics of creating your own 6 keyed macropad, controlled by an Arduino. I will be taking you through what you need, how to assemble it, how to program it, and how to improve it or make it your own.

After much research, I couldn't really find a great guide on how to make a macro keypad, or a hand wired keyboard in general. So I decided to do it myself, in the simplest way possible, without diodes, resistors, or anything else. I also wanted to have a unique modular keyboard, where I could grab any parts that I needed, this is the first of many other parts. This module's inspiration was from arrow keys on a keyboard, being able to fit it in your pocket, and taking it anywhere if you needed a few extra buttons on the go.

Due to how this keypad was made, I highly recommend that you read all of the Instructable before you make any purchasing decisions.

I also tried to make the Instructable in a logical order, but I don't build logically, so it might be better to skip around in the order of the steps depending on how you build.

Step 1: Getting the Parts

The longest step is right here, buying the parts and waiting for them to ship. Amazon links will be Canadian Amazon. The parts that you are going to need are:

  1. Mechanical Key switches
    • I choose the Gateron switches with clear tops from here (Clear tops make the next step easier, most common types of switches are covered there too)
    • Other places to buy can be found here under your favorite switch section
      • I also highly recommend doing some research here on what switch you would like here under the 'Feels' section
  2. Mechanical Keycaps
    • Make sure that they are compatible with your switch that you choose!
      • Also make sure that they are back light compatible so you can change the colour
    • Vendors can be found here under the 'Novelty Keys (standard manufacturing)' section, unless you want a full Keycap set
  3. Addressable RGB LED strips (Optional, but highly recommended)
    • I bought something similar to these from Amazon
      • Make sure that the LEDs are WS2812B LEDs, they can accept a lower voltage.
      • You could also buy 3mm regular LEDs of your favorite colour to use, but you'd need resistors
  4. An HID compatible micro controller (I used a Pro Micro)
    • I bought these from Amazon for the best deal
      • You can buy other micro controllers, but make sure that they are both Arduino and HID (human input device) compatible
  5. A 128x32 I2C OLED display
    • I bought this from Amazon
  6. Access to a 3D printer
    • Try with local libraries or schools around you and see if they have a 3D printer
    • I've personally never used an online service, but you could use those too (something like this)
  7. Thin Wire
  8. General Tools Needed
    • Soldering Iron and Solder
    • Side Cutter Pliers
    • Small Files (Somewhat optional)
    • Hot Glue Gun and Glue
    • Screwdriver and screws of your choice

Step 2: Keyswitch Modifications

Start to disassemble the switches that you bought. We are doing this to allow the light to shine through better to reach our keycaps. If you have chosen keycaps that don't support RGB, skip this step.

Take 2 small wedges (I used 2 flathead screwdriver bits) and push under the tabs on the side of the switch. Then put something in between the top and bottom so it doesn't close. Proceed to push the tabs of the other side, so no tabs should still be holding the top on. After that, finish up and pop off the top of the switch. There usually is four parts, the top and bottom of the casing, the spring, and the stem (sliding part of the switch that holds the keycap).

Start to cut small little pieces out of the bottom of the case to allow more light to pass. Cut the tab that holds the switch on the plate first. Then cut a bit of the original LED pass through, (the part with the 4 holes, those are for the legs of the LEDs). Slowly cut down on that tab inside to get down to the bottom. Then proceed to cut up to the cylindrical center of the switch that holds the spring. We don't need to go further than that. After that, widen the hole a bit, by slowly cutting off both sides with the pre-molded supports. Another optional step is to file it down, to make it nicer, and less jagged. Make sure that there are little to none plastic bits inside of the casing from this, as you don't want the switch to get stuck. Make sure to do these cuts slow and small, as I've broken a few cases from the width of the side cutters forcing the case apart.

If the top half of your switch isn't clear as well, try to modify it to allow the light to shine through. Try little by little without breaking the switch, because you don't want the stem to fall out. A possible solution may be to cut out the piece of plastic that would hold a normal LED, and leave the plastic that keeps the stem enclosed, and only file it down.

Step 3: 3d Printing

You will need to download one of the zip files below, and 3d print them. There will be different versions depending on what you want. There will be a folder with all of the normal stl files in it (KeybArrowSTLFiles), and one with the Autodesk inventor files (KeybArrowSourceFiles), so that you could modify the files and change them to your own needs. The files are slightly different from what I printed, this was because there were some design flaws, and I felt I could improve them. Example would be the sides of the case, mine were a bit too high so the keycaps wouldn't push all the way down, the new files should fix that.

The design of them was pretty complicated, with over 30+ steps. All I will say is that if you want to design a case for a different size, you should make sure that you have experience with somewhat complicated 3d designs. It's not really for people who are new to 3d design.

Note that both of the casing files are at a 3 degree angle, and you should angle them flat on the bed.

Step 4: Assembling What You Have So Far

Now that we have all of our parts, and we have the 3d printed parts, it's time to assemble it a bit!

Place all 6 of the switches into the plate, and glue them in place. We need to glue them because we cut off the tabs that hold it in place. I suggest waiting to put in the OLED because you don't want it slanted.

Next, cut 6 LEDs off and place them on the LED plate. The squares on the plate are to help you align the LEDs. The square LEDs will fit into them, so you could 3d print another to help alignment, or just line it from the back. Make sure that the arrows point to the other LEDs, as DO would be soldered to DI. Use those squares to glue on the LEDs with hot glue, and hold them in place and wait for the glue to hold.

I used a prototype plate for the switches to hold the LEDs (in the images) because I don't like to waste filament, and decided to reuse. The new file won't affect anything, just make it simpler to align.

Step 5: Setting Up the OLED

I recommend using this Instructable for a thorough walk through. They did a really well job of explaining it.

You will need to download and import this library and this library for the code to work.

First wire it up. Wire VCC to VCC, and GND to GND. Then wire the SDA and SCL pins. The SDA and SCL pins may vary from each Arduino, but on the pro micro, SDA is wired up to pin 2, and SCL is wired up to pin 3. Look up a pinout of your micro controller if you are unsure of what pins SDA and SCL are wired to.

Next is to get it displaying and making images. There will be files below of how to get it working. The first step is to use the ScreenScan code (originally provided by Arduino here). Upload the code onto the Pro Micro and open the Serial reader (under the tools tab at the top). It will read you back and address of the OLED. If your address is 0x3C, then you don't need to change anything. If it isn't, then you need to go and change the address in the ssd1306_128x32_i2c code and the final code (named ArrowKeypad) so that it works properly.

Now test out the example code that was included with the Adafruit ssd1306 library that for the 128x32 i2c code (named ssd1306_128x32_i2c)

After that, keep the Arduino on, and try to line up the OLED on the switch plate, then turn it off and try to glue it in place. You will most likely not get this first try, but keep adjusting to try to get it aligned, so that it isn't angled when it is completed. I suggest gluing one side a bit, and checking before you glue the other side to make sure that it isn't slanted.

Download the code now, and use the other files of code in Step 8 later in this Instructable.

Step 6: Soldering

A Fritzing file will be available below. This will allow you to interact with the circuitry and if you left click and hold, you can see what wires are all connected (highlighted in yellow dots) files that need to be imported to Fritzing before you open the file will be down below (for the Pro Micro and LEDs).

Make sure the pins labled "MOSI, MISO or SCLK" are UNUSED or it will cause glitches with the OLED.

After cutting the 6 LEDs into single strips, and gluing them onto the plate. Place the soldering iron on the copper pads, and add solder to each of the pads. Cut small pieces of wire and strip half of it, twist it, then take the other half off and twist the wire. The wire will need to be held with pliers or some soldering helping hands, while you get it held in place by the solder. Add more solder to hold it there nicely. Solder all of the LEDs in the row together. Cut a wire, and solder it to the end of the LED on the first row, with the label 'DO' or 'D-', and connect it to the first LED on the second row with the label 'DI' or 'D+'. You can do this with the 5v and GND too, but it's easier if the first LEDs 5v and GND on each row are wired together. Wire the 5v wire to VCC, Data pin to any digital pin (code has it set as 10) and GND to a GND on the Arduino.

To get the Arduino to recognize an input, the switches need to connect ground to a data pin. So, you can solder one wire to connect all 6 switches to ground. Solder one wire to each switch, and if possible, try to change the colours of wire to keep track of what switch is what wire. Feed the wires through the LED plate and wire them to a data pin on the Arduino (I used data pins 5-9 for this)

The two switches on the side have different functions, one is a reset switch for programming, while the other is a function switch, which will switch between layers of the Keypad to quickly change functions of the buttons. The top switch, is wired to reset (RST) and GND, when connected, it causes the reset. The bottom switch is wired up to pin 18, which is labeled as A0 on the Pro Micro.Give yourself some slack with the switch wires, as you still need to slide in the plates, and too little of a wire won't allow the plates to inset through the top.

Step 7: Introduction to Programming

Before you want to close the case, you want to test it and make sure it works. You could skip to step 11 to assemble it now. I just find that testing it beforehand helps to reduce the amount of times you open and close it. Even though it shouldn't affect it much, I used the Arduino IDE version 1.8.3, so if you have issues, try to use this version. The code is on Step 5, it is a zip file that you will need to extract and upload through Arduino.

There will be multiple pieces of code below. One will be the final code, two will be to test the OLED (One to test, one to find the address), and one will be to test the RGB. Use the final code to test the switches.

If you want to design your own code, I'm teaching that in the next 3 steps, but it's totally fine if you want to use my code, or take it and modify it.

Some basics of programming this

  • Under the "Tools" tab, then the "Board" tab, set it to an Arduino Leonardo (Unless you have a micro controller that is different from the Pro Micro)
  • Use the reset switch every time you upload code to the Pro Micro. I've found that once the compiling bar is full, and is still uploading, it is a good time to flick the switch on and off to program. (If you don't do this, the upload will just fail to upload.)
  • All Libraries used must be installed and imported
    • To import, go to the tools tab and click include library. (Note also, my code examples on the webpage need to have the <> around the library name, I couldn't enter them in the example code section on the next few steps)
  • The LED and OLED libraries will be initialized as objects, you can name them whatever, but for the sake of demonstration I will name them 'strip' and 'display'
    • Call functions from a object by typing the object name, putting a period, then typing the function you want to use

Next test the LEDs, upload the code, and make sure that they all work. If none work, your missing a pin going to them, check your soldering of the first LED.

Lastly, use the final code to test your switches. This should be the easiest to do. Note that now, after uploading some HID code, you will need to reset the Arduino every time that you upload code to it. Just reset it halfway through uploading it and it should work.

Step 8: Programming the Switches

Out of all of the programming, the switches are the least complicated. To get it recognized as a keyboard, all you need to use is the Arduino Keyboard library, and conditional statements. Make sure that under the Tools tab, the Board is set to an Arduino Leonardo if you are using a Pro Micro like me.

Before we start with the conditional statements, we need to setup the pins. We only need this to run once, so put this into the void setup. Start with pinMode(PinNum, INPUT_PULLUP); This tells the Arduino that the PinNum is expecting an input, and that it adds a pullup resistor (so that we don't need to wire any in the hardware)

The input pullup has 2 states, LOW and HIGH. The Arduino will read LOW on a pin when it is connected to Ground (GND) and will read HIGH when it is disconnected. To find what the pin is reading, we use digitalRead(PinNum).

Starting with the basics, we use conditional if statements to find if the key was pressed. We want this to run over and over so we want this to be put the void loop. If the key was registered as "LOW" then we want the key to be pressed, and the key to be released when the input is "HIGH". So to do this, we code if(digitalRead(PinNum)==LOW){ [Code for when the button is pressed] } and code if(digitalRead(PinNum)==HIGH){ [Code for when the button is released] }

For the code for the keyboard, import the Keyboard library. Put a keyboard.begin(); in the void setup. Then inside of our conditional statements, we use keyboard.press([key]); and keyboard.release([key]); or keyboard.releaseAll(); if you had multiple keys pressed. You could also use keyboard.print([String]); and keyboard.println([String]) to print strings, like a password. print and println are similar, but println just adds an ENTER, so it automatically goes to the next line.

Step 9: Programming the OLED

Starting with programming the OLED, you will need to have basic setup code. This basically tells the computer where your OLED is located, the size of it, and how it is programmed. Once you have the setup code for the OLED, assuming you're only displaying text, it should be pretty simple to program. First include the Wire and SSD1306 libraries.

Define the OLED_RESET as 4, and include the SSD1306 library in your code. Put Adafruit_SSD1306 display(OLED_RESET); in your code to begin the use of the Adafruit SSD1306 library.

Start with Serial.begin(9600); then display.begin(SSD1306_SWITCHCAPVCC, 0x3C); to initialize the i2C display with the address of 0x3C (unless it changed in step 5). Put both of these in void setup because they only need to run once.

Before you program the display, you should make sure you use display.clearDisplay. If you don't what was inputted will overlap, and depending on what was changed, won't be legible. You also want to set the origin, so use display.setCursor(0,0); to set it on a point on your display, put (0,0) to reset it back to the beginning. To set the size of the text, use display.setTextSize(1); I wouldn't go much bigger than 1, it's much larger than expected.

Even though our display is monochrome, we need to set the text colour, so we program it like display.setTextColor(WHITE);

Now that you have your library imported and your display object, you can start to program it. To add text, use display.print(); and display.println(); to print strings. Again, print doesn't add a return while println automatically returns to the next line when something is printed again.

Before you get anything to display, you need to update the OLED, and tell it to update, you use display.display(); with no parameters and it will update.

The code should look something like this now:

//Code Made by Foster Phillips
#include Adafruit_SSD1306.h
#include Wire.h
#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);

void setup() {
pinMode(SWITCH,INPUT_PULLUP);
Serial.begin(9600);
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
display.display();
delay(2000);
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
}
void loop() {
display.display();
delay(2000);
display.clearDisplay();
display.setTextSize(1);
display.setCursor(0,0);
display.println("Hello World!");
display.println("Hello Instructables!");
}

This Instructable and this Github link are both very good references for troubleshooting, and learning more on programming the display respectively.

Step 10: Programming the LEDs

The LEDs are reasonably simple too. We will be using the Adafruit Neopixel library. Personally, the NeoPixel library is very similar to programming in Processing, if you've ever programmed in that.

There is first setup code, addressing what library we are using, and setting up an array that basically says how many LEDs are on the pin, what pin is for data, and how it is programmed. This is done with an example like Adafruit_NeoPixel strip = Adafruit_NeoPixel(6, 10, NEO_GRB + NEO_KHZ800); This explains that there are 6 LEDs, the pin is pin number 10, and that is uses the NEO_GRB + NEO_KZH800 type of addressable strips. Usually the last argument doesn't need to be touched, the LED strips that I used didn't need that changed.

After that you need the strip.begin(); function showing that you are ready to start using them. Nothing needs to be in the brackets.

Once you have that, you can call different functions with the strip.[function]

One that you will need to know is strip.setPixelColour. This has 4 functions in the brackets. You have the LED in the 'array' of LEDs (remember, Arrays start at 0) and the corresponding Red, Green, and Blue values from 0-255. This will allow you to mix the desired Red Green and Blue values to get a colour that you want. The code should look like: strip.setPixelColour(0,0,255,255); if you wanted a cyan colour on the first LED.

The LED also needs to be sent that data, which is what strip.show(); does. It will update the pixels after you have changed something with them. Nothing needs to go into the brackets.

The code should look like:

//Code Made by Foster Phillips
#include Adafruit_NeoPixel.h
#define PIN 10
#define Num 6

Adafruit_NeoPixel strip = Adafruit_NeoPixel(Num, PIN, NEO_GRB + NEO_KHZ800);

void setup() {
strip.begin();
strip.show();
}
void loop() {
strip.setPixelColor(0,255,0,0);
strip.setPixelColor(1,255,0,0);
strip.setPixelColor(2,255,0,0);
strip.setPixelColor(4,255,0,0);
strip.setPixelColor(3,0,0,255);
strip.setPixelColor(5,0,0,255);
strip.show();
}

More information can be found here.

Step 11: Assembling!

This is probably the easiest step, and the coolest.

Start by placing and sliding in the Pro Micro onto the case closure. Glue it into place with some hot glue.

The case/closure was designed so that you could side the switch plate and LED plate in. Just slide it in, and depending on how you printed it, you might need to file or cut the inside of the slides to remove some overhang plastic.

After that, get your screws and just jam it into there and make your own screw holes. I didn't have specific screws threads when I designed the files, so I just made a hole roughly the size of a screw and screwed it in myself. Heating it up with a lighter will help to form it to the screw you need, and usually strengthen the layers. Make sure not to push too much on the screws, or you can strip the head. I used Allen key screws to reduce this risk.

Then just push the key caps onto the keys. Then it's pretty much done! My version of the Arrow Key Macropad is complete!

Step 12: Your Own Improvements!

Now that you know how to make my version, you can make your own! Keyboards can arguably be about expressing yourself, so just having someone else's design isn't fun unless you modify it to fit you! There are many improvements you can do! Here are some improvements that I'd like to add or thought of!

  • Program Tetris and other simple games
  • Make it bluetooth
  • Allow it to read data from slideshows and display it one the OLED (Show the slide number and name of slide)
  • Make a full sized keyboard or larger macropad using these technique
  • You'd need to learn how to make a switch matrix for this
  • Program more colour options
  • Program macros for games, video editing, etc.
  • Use the Autodesk Inventor source files to make your own case, or modify it to be uniquely yours!
  • Add a sound board to have it double as a music player

Have fun making! Feel free to add tips or ask me to clarify!

If you want to see progress of the other parts, consider checking out my Instagram. Thanks for reading my Instructable!

Microcontroller Contest

Runner Up in the
Microcontroller Contest

Pocket-Sized Contest

Participated in the
Pocket-Sized Contest