Simple Mechanical Keyboard/Macropad
We calculate the final price from your selected file. You review and accept it before payment.
Saved on this device.
Just a 4-switch mechanical keyboard.
- Rating
- 0 / 5
- Likes
- 50
- Downloads
- 100
- Makes
- 0
- Views
- 1,280
- Reviews
- 0
Updated at source:
Model information
- Source
- Printables
- Category
- Computers
- License
- Creative Commons — Attribution — Noncommercial — Share Alike
Note: This macro-pad was originally designed for personal use, so a few things were tailored to my specific setup:
- All 3D-printed parts were modeled for a 0.8mm nozzle and 0.4mm layer height. If you’re using different settings, clearances may vary.
- The board used is the Adafruit ItsyBitsy M0 Express, simply because that’s what I had.
- It is up to you how you bind the key press/release events on your computer to actual macros (if that is what you want). The firmware provided can only simulate the pressing and releasing of standard keys.
🔧 Parts & Tools Required
- Electronics
- 1 x Adafruit ItsyBitsy M0 Express
- 4 x Linear mechanical switches
- 4 x Keycaps — (I used this model, but any MX-compatible caps will work)
- 30 AWG copper wire
- Tools & Materials
- Soldering iron, solder, and basic soldering skills
- Superglue or hot glue (hot glue recommended)
- Micro USB cable
- Arduino IDE installed and configured
🛠 Assembly Instructions
- Print the top_plate, bottom_plate, and the switch_plate. Print the keycaps unless you are using keycaps you already have.
- Insert the switches into the switch plate. The side with the smaller openings should be up. The switches should click into place.
- For each switch:
- Cut a small piece of wire.
- Solder one end of the wire to the switch. Doesn't matter which leg, but pick the same for each switch. These are the switch input lines.
- Solder the other end of the wire to the ItsyBitsy. First switch goes to pin 13. Second to pin 12. Third to pin 11, and fourth to pin 10. You can switch the order if you want just make sure you note down which switch is connected to with pin.
- Once again, for each switch, cut a small piece of wire and connect the remaining leg to the same leg on the switch next to it. These are the ground connections. For the last switch, take an additional segment of wire and solder one end to the switch, and the other end to the G(round) pin on the ItsyBitsy.
- Your connections should look similar to the way they are shown in the photo.
- Now you need to attach the switch plate to the top plate. You have two options:
- Apply superglue to the underside of the lip on the top plate. Then insert the switch plate and hold it in place until the two parts are firmly attached.
- OR you can insert the switch plate into the top plate, then put dabs of hot glue on all four corners along the inner wall to fix the switch plate in place (recommended).
- Insert the ItsyBitsy into its mount. It should click into place.
- Attach the top plate assembly to the bottom plate. It helps if you first insert the lip on the short side of the bottom plate into the top plate at an angle, then “close the hinge” and the two halves should click into place.
- That is it for the assembly. Now, connect your ItsyBitsy to the computer with a micro USB cable. Load the following firmware. If you get a popup about missing libraries, install them. You can refer to the Arduino keyboard library reference for more details about how it works and what key codes you can use.
/*
Firmware for my 3D printed 4-switch macropad/keyboard.
*/#include "Keyboard.h"
#include <Adafruit_DotStar.h>
#include <SPI.h>
// Uncomment the following to log keypresses to the serial port.
// #define DEBUG
// For the RGB LED on the ITSY BITSY M0
#define NUMPIXELS 1
#define DATAPIN 41
#define CLOCKPIN 40
Adafruit_DotStar strip(NUMPIXELS, DATAPIN, CLOCKPIN, DOTSTAR_BRG);
// Utility function to update the colour of the LED
void updatePixel(uint8_t red, uint8_t green, uint8_t blue) {
strip.setPixelColor(0, green, red, blue);
strip.show();
}
#define NUM_SWITCHES 4
// The GPIO pin numbers
const uint8_t switchPin[NUM_SWITCHES] = { 13, 12, 11, 10 };
// The last instantaneous (raw) state of the input
static uint8_t lastState[NUM_SWITCHES] = { HIGH, HIGH, HIGH, HIGH };
// The last debounced (filtered) state of the input
static uint8_t lastDebouncedState[NUM_SWITCHES] = { HIGH, HIGH, HIGH, HIGH };
// The timestamp for when the last raw input transition took place
unsigned long lastTransitionAt[NUM_SWITCHES] = { 0, 0, 0, 0 };
// How long the input state must be sustained before it is 'accepted'
unsigned long debounceDelay = 25;
void setup() {
#ifdef DEBUG
Serial.begin(115200);
while (!Serial) {};
Serial.println("Starting...");
#endif
// Configure all the input pins
for (uint8_t i = 0; i < 4; i++) {
pinMode(switchPin[i], INPUT_PULLUP);
lastState[i] = digitalRead(switchPin[i]);
lastDebouncedState[i] = lastState[i];
}
Keyboard.begin();
strip.begin();
strip.show();
}
void loop() {
uint8_t currState;
// Loop through all the inputs and handle them sequentially
for (uint8_t i = 0; i < 4; i++) {
currState = digitalRead(switchPin[i]);
if (currState != lastState[i]) {
lastTransitionAt[i] = millis();
}
if ((millis() - lastTransitionAt[i]) > debounceDelay) {
if (currState != lastDebouncedState[i]) {
#ifdef DEBUG
Serial.print("Switch ");
Serial.print(i);
Serial.print(" (debounced): ");
currState ? Serial.println("RELEASED") : Serial.println("PRESSED");
Serial.flush();
#endif
lastDebouncedState[i] = currState;
if (currState == LOW) {
// Keypress event...
switch (i) {
// You can send function keys
case 0:
updatePixel(255, 0, 0);
Keyboard.press(KEY_F1);
break;
// Or chords such as CTRL+C for copy...
case 1:
updatePixel(0, 255, 0);
Keyboard.press(KEY_LEFT_CTRL);
Keyboard.press('c');
break;
// ...and CTRL+V for paste
case 2:
updatePixel(0, 0, 255);
Keyboard.press(KEY_LEFT_CTRL);
Keyboard.press('v');
break;
// Or any other non-character key too.
case 3:
updatePixel(255, 255, 0);
Keyboard.press(KEY_DELETE);
break;
}
} else {
updatePixel(0, 0, 0);
// Key release event
switch (i) {
case 0:
Keyboard.release(KEY_F1); // Release F1 key
break;
case 1:
Keyboard.releaseAll(); // Release CTRL + C
break;
case 2:
Keyboard.releaseAll(); // Release CTRL + V
break;
case 3:
Keyboard.release(KEY_DELETE); // Release DELETE key
break;
}
}
}
}
// Update the last filtered state
lastState[i] = currState;
} // for (uint8_t i = 0; i < 4; i++)
delay(1);
}
And that's it! Enjoy your super simple mini macropad!