I designed this to be able to assign keyboard shortcuts for different software that I use on a regular basis. This MACRO keypad; in conjunction with JoyToKey will allow a great number of options for different software, batchfiles, shortcuts etc. Currently using it primarily for fusion 360.
Lists for Macro Keyboard V2 – as of 11/19/2022
*** Some models May need to be oriented before slicing.
The KeyCapPlate prints quick and will let you know if your switches will fit (14mmx14mm)
I have not done a full write up yet, but plan on doing that when I have the time. Photos should provide enough to go by for now.
When pressing the 3D printed Keycaps onto the switches, there is a notch on the switch which correlates to the “dot” on the 3D printed key cap; line those up and then press firmly. All key caps should pressure fit into place. You can remove them a few times without too much risk of them becoming loose.
The key switches are wired into a 5x5 matrix.
Single color lines are for rows: Blue, Orange, Green, Brown, Grey
Double color lines are for columns: 2Blue, 2Orange, 2Green, 2Brown, 2Grey
The Yellow line is for the LED Output.
In the final wiring, I wired the columns backwards - so if you are following along the scripts below will work as I had to accommodate for this… Otherwise you may need to reverse the keys for the two test scripts. (In the final script, I flipped the colpins around so it reads more naturally in the script.)
Here are x2 Test scripts (.ino) and the final script that is currently being used.
Test Script to output only to serial monitor
#include <Keyboard.h>
#include <KeyboardLayout.h>
#include <Keyboard_da_DK.h>
#include <Keyboard_de_DE.h>
#include <Keyboard_es_ES.h>
#include <Keyboard_fr_FR.h>
#include <Keyboard_it_IT.h>
#include <Keyboard_sv_SE.h>
#include <Keypad.h>
const int ledPin = 14;// led Pin#
const byte rows = 5; //five rows
const byte cols = 5; //five columns
char keys[rows][cols] = {
{'E','D','C','B','A'},
{'J','I','H','G','F'},
{'O','N','M','L','K'},
{'T','S','R','Q','P'},
{'Y','X','W','V','U'}
};
byte rowPins[rows] = {2, 3, 4, 5, 6}; //connect to the row pinouts of the keypad
byte colPins[cols] = {7, 8, 9, 10, 16}; //connect to the column pinouts of the keypad
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, rows, cols );
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
pinMode(ledPin, OUTPUT);
Keyboard.begin();
}
void loop() {
// put your main code here, to run repeatedly:
char key = keypad.getKey();
if(key != NO_KEY){
Serial.println(key);
Keyboard.write(key);
digitalWrite(ledPin, HIGH);
delay(100);
digitalWrite(ledPin, LOW);
}
}
Test script to output to serial monitor and input keyboard strokes. Test in notepad.
#include <Keyboard.h>
#include <KeyboardLayout.h>
#include <Keyboard_da_DK.h>
#include <Keyboard_de_DE.h>
#include <Keyboard_es_ES.h>
#include <Keyboard_fr_FR.h>
#include <Keyboard_it_IT.h>
#include <Keyboard_sv_SE.h>
#include <Keypad.h>
//-Below is where we will define the keys
//-Variables are defined as following:
//-[keyA] [keyB] [keyC] [keyD] [keyE]
//-[keyF] [keyG] [keyH] [keyI] [keyJ]
//-[keyK] [keyL] [keyM] [keyN] [keyO]
//-[keyP] [keyQ] [keyR] [keyS] [keyT]
//-[keyU] [keyV] [keyW] [keyX] [keyY]
//------------Define 1st Row------------
//Ex: [keyA] [keyB] [keyC] [keyD] [keyE]
//--------------------------------------
char keyA = 'A';
char keyB = 'B';
char keyC = 'C';
char keyD = 'D';
char keyE = 'E';
//-Define 2nd Row-----------------------
//Ex: [keyF] [keyG] [keyH] [keyI] [keyJ]
//--------------------------------------
char keyF = 'F';
char keyG = 'G';
char keyH = 'H';
char keyI = 'I';
char keyJ = 'J';
//-Define 3rd Row-----------------------
//Ex: [keyK] [keyL] [keyM] [keyN] [keyO]
//--------------------------------------
char keyK = 'K';
char keyL = 'L';
char keyM = 'M';
char keyN = 'N';
char keyO = 'O';
//-Define 4th Row-----------------------
//Ex: [keyP] [keyQ] [keyR] [keyS] [keyT]
//--------------------------------------
char keyP = 'P';
char keyQ = 'Q';
char keyR = 'R';
char keyS = 'S';
char keyT = 'T';
//-Define 5th Row-----------------------
//Ex: [keyU] [keyV] [keyW] [keyX] [keyY]
//--------------------------------------
char keyU = 'U';
char keyV = 'V';
char keyW = 'W';
char keyX = 'X';
char keyY = 'Y';
//--------------------------------------
//-End of Defining Keys-----------------
//--------------------------------------
const int ledPin = 14;// led Pin#
const byte rows = 5; //five rows
const byte cols = 5; //five columns
char keys[rows][cols] = {
{keyE,keyD,keyC,keyB,keyA},
{keyJ,keyI,keyH,keyG,keyF},
{keyO,keyN,keyM,keyL,keyK},
{keyT,keyS,keyR,keyQ,keyP},
{keyY,keyX,keyW,keyV,keyU}
};
byte rowPins[rows] = {2, 3, 4, 5, 6}; //connect to the row pinouts of the keypad
byte colPins[cols] = {7, 8, 9, 10, 16}; //connect to the column pinouts of the keypad
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, rows, cols );
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
pinMode(ledPin, OUTPUT);
Keyboard.begin();
keypad.setDebounceTime(50);
}
void loop() {
// put your main code here, to run repeatedly:
char key = keypad.getKey();
if(key != NO_KEY){
Serial.println(key);
Keyboard.write(key);
digitalWrite(ledPin, HIGH);
delay(100);
digitalWrite(ledPin, LOW);
}
}
FINAL as built Working Script.
Hit win key > type “Set up USB game controllers” > click controller > Properties > Test. Will display a page and allow you to test the Joystick inputs.
#include <Joystick.h>
#include <Keypad.h>
#define NUMBUTTONS 25
#define NUMROWS 5
#define NUMCOLS 5
#define statLED 14
//-Define the buttons for the macropad
byte buttons[NUMROWS][NUMCOLS] = {
{0,1,2,3,4},
{5,6,7,8,9},
{10,11,12,13,14},
{15,16,17,18,19},
{20,21,22,23,24},
};
byte rowPins[NUMROWS] = {2,3,4,5,6}; //-Connect to the row pinouts of the macropad
byte colPins[NUMCOLS] = {16,10,9,8,7}; //-Connect to the column pinouts of the macropad
//-Initialize an instance of class NewKeypad
Keypad macroPad = Keypad( makeKeymap(buttons),rowPins, colPins, NUMROWS, NUMCOLS);
Joystick_ Joystick(JOYSTICK_DEFAULT_REPORT_ID,JOYSTICK_TYPE_GAMEPAD,
25, 0, // Button Count, Hat Switch Count
false, false, false, // no X and Y, no Z Axis
false, false, false, // No Rx, Ry, or Rz
false, false, // No rudder or throttle
false, false, false); // No accelerator, brake, or steering
void setup() {
// put your setup code here, to run once:
// Initialize Joystick Library
Joystick.begin();
pinMode(statLED, OUTPUT);
}
void loop() {
// put your main code here, to run repeatedly:
CheckAllButtons();
delay(0);
}
void CheckAllButtons(void) {
if (macroPad.getKeys())
{
for (int i=0; i<LIST_MAX; i++)
{
if (macroPad.key[i].stateChanged)
{
switch (macroPad.key[i].kstate) {
case PRESSED:
case HOLD:
Joystick.setButton(macroPad.key[i].kchar, 1);
digitalWrite(statLED, HIGH);
break;
case RELEASED:
case IDLE:
Joystick.setButton(macroPad.key[i].kchar, 0);
digitalWrite(statLED, LOW);
break;
}
}
}
}
}
***Note: Photos are of prototype model so uploaded models may differ a bit in appearance.
The author marked this model as their own original creation.