I have posted an initial version of the Arduino based firmware to GitHub. It handles the reading of the tiles, and assigns the macros to specific keys. I'm using the Arduino HID-Project library to send the keys via USB to the PC. This is working well.
When I started looking at similar MacroPad projects, at least the ones that were not based on QMK or Kaleidoscope, I found that they were all virtually mapping keys directly to some code. For instance:
switch(button){
case '1': //Return
Keyboard.press(KEY_RETURN);
Keyboard.releaseAll();
break;
case '2': //Escape
Keyboard.press(KEY_ESC);
Keyboard.releaseAll();
break;
default:
break;
};
For every macro added or changed then the code would get modified. Not a big deal but it could be easier, especially maybe for non-programmers. In my implementation the user can define the macros as comma delimited strings. Here are my macro definitions so far.
It starts with the definition of keyboard and media codes.
/*****
* Standard Key Codes.
******
KEY_RESERVED KEY_ENTER KEY_PAGE_DOWN
KEY_ERROR_ROLLOVER KEY_RETURN KEY_RIGHT_ARROW
KEY_POST_FAIL KEY_ESC KEY_LEFT_ARROW
KEY_ERROR_UNDEFINED KEY_BACKSPACE KEY_DOWN_ARROW
KEY_A KEY_TAB KEY_UP_ARROW
KEY_B KEY_SPACE KEY_RIGHT
KEY_C KEY_MINUS KEY_LEFT
KEY_D KEY_EQUAL KEY_DOWN
KEY_E KEY_LEFT_BRACE KEY_UP
KEY_F KEY_RIGHT_BRACE KEY_NUM_LOCK
KEY_G KEY_BACKSLASH KEYPAD_DIVIDE
KEY_H KEY_NON_US_NUM KEYPAD_MULTIPLY
KEY_I KEY_SEMICOLON KEYPAD_SUBTRACT
KEY_J KEY_QUOTE KEYPAD_ADD
KEY_K KEY_TILDE KEYPAD_ENTER
KEY_L KEY_COMMA KEYPAD_1
KEY_M KEY_PERIOD KEYPAD_2
KEY_N KEY_SLASH KEYPAD_3
KEY_O KEY_CAPS_LOCK KEYPAD_4
KEY_P KEY_F1 KEYPAD_5
KEY_Q KEY_F2 KEYPAD_6
KEY_R KEY_F3 KEYPAD_7
KEY_S KEY_F4 KEYPAD_8
KEY_T KEY_F5 KEYPAD_9
KEY_U KEY_F6 KEYPAD_0
KEY_V KEY_F7 KEYPAD_DOT
KEY_W KEY_F8 KEY_NON_US
KEY_X KEY_F9 KEY_APPLICATION
KEY_Y KEY_F10 KEY_MENU
KEY_Z KEY_F11
KEY_1 KEY_F12
KEY_2 KEY_PRINT
KEY_3 KEY_PRINTSCREEN
KEY_4 KEY_SCROLL_LOCK
KEY_5 KEY_PAUSE
KEY_6 KEY_INSERT
KEY_7 KEY_HOME
KEY_8 KEY_PAGE_UP
KEY_9 KEY_DELETE
KEY_0 KEY_END
You can add any of these codes to the keyboard lists below for use in macro definitions.
In the keyboardKeyNames table add the code as a string delimited by "".
In the keyboardKeyCodes table ad the code as is without quotes.
Don't forget the commas at the end of each entry.
It is IMPORTANT to add the name and code in the same position in the list.
*****/
String keyboardKeyNames[] = {
"KEY_LEFT_CTRL",
"KEY_UP_ARROW",
"KEY_DOWN_ARROW",
"KEY_LEFT_ARROW",
"KEY_RIGHT_ARROW"
};
KeyboardKeycode keyboardKeyCodes[] {
KEY_LEFT_CTRL,
KEY_UP_ARROW,
KEY_DOWN_ARROW,
KEY_LEFT_ARROW,
KEY_RIGHT_ARROW
};
/******
* Media Key Codes.
*******
MEDIA_RECORD MEDIA_VOLUME_MUTE
MEDIA_FAST_FORWARD MEDIA_VOL_MUTE
MEDIA_REWIND MEDIA_VOLUME_UP
MEDIA_NEXT MEDIA_VOL_UP
MEDIA_PREVIOUS MEDIA_VOLUME_DOWN
MEDIA_PREV MEDIA_VOL_DOWN
MEDIA_STOP
MEDIA_PLAY_PAUSE
MEDIA_PAUSE
You can add any of these codes to the media lists below for use in macro definitions.
In the consumerKeyNames table add the code as a string delimited by "".
In the consumerKeyCodes table ad the code as is without quotes.
Don't forget the commas at the end of each entry.
It is IMPORTANT to add the name and code in the same position in the list.
*****/
String consumerKeyNames[] = {
"MEDIA_PLAY_PAUSE",
"MEDIA_VOL_MUTE",
"MEDIA_VOLUME_UP",
"MEDIA_VOLUME_DOWN"
};
ConsumerKeycode consumerKeyCodes[]{
MEDIA_PLAY_PAUSE,
MEDIA_VOL_MUTE,
MEDIA_VOLUME_UP,
MEDIA_VOLUME_DOWN
};
/*****
* Define the macros here.
*****
String macros[] = {
"PRESS,KEY_LEFT_CTRL,a,RELEASE_ALL", // select
"PRESS,KEY_LEFT_CTRL,c,RELEASE_ALL", // copy
"PRESS,KEY_LEFT_CTRL,x,RELEASE_ALL", // cut
"PRESS,KEY_LEFT_CTRL,v,RELEASE_ALL", // paste
"KEY_UP_ARROW", // up
"KEY_LEFT_ARROW", // left
"KEY_RIGHT_ARROW", // right
"KEY_DOWN_ARROW", // down
"", // Skip for now.
"", // Skip for now.
"MEDIA_VOLUME_DOWN", // louder
"MEDIA_VOLUME_UP", // softer
"MEDIA_VOL_MUTE", // mute
"MEDIA_PLAY_PAUSE", // pause/play
""
};
When a key on the pad is pressed, it's corresponding tile is read to get the tile number. This number is used as an index into the macros table to get the appropriate macro string which is parsed to determine the keys to send to the PC. The macro string is split into "tokens" at the commas and the tokens are processed from left to right with the following rules:
- If the token is "PRESS", a flag is set to to indicate that all subsequent characters (c) will be sent with the Keyboard.press(c) function. If the press token is not set (default at start of parsing), characters will be sent with Keyboard.write(c).
- If the token starts with "KEY_", then the token is used to lookup a keycode in the keyboardKeyCodes table. That keycode is sent to the PC via the Keyboard press or write functions depending on the press flag.
- If the token starts with "MEDIA_", then the token is used to lookup a keycode in the consumerKeyCodes table. That keycode is sent to the PC via the Consumer press or write functions depending on the press flag.
- If the token is "RELEASE", then a release flag is set. The next character processed (c) will be sent to the PC with a Keyboard.release(c) function and the release flag will be cleared.
- If the token is "RELEASE_ALL", then the Keyboard.releaseAll() function will be executed and the release flag cleared.
- If the token is a hex digit of the form "0xnn" exactly where nn is a valid hex number, then the value based on that number will be sent to the PC via the Keyboard press or write depending on the press flag.
- If the token is not recognized as one of the "key words" above, then it’s assumed to be an ASCII character or a string. If the token is a single character it will be sent to the PC via the Keyboard press or write depending on the press flag. If it's a string (s) it will be sent to the PC with a Keyboard.print(s) call. (NOTE there is no corresponding Keyboard.println(s) call because the user can simply add a \n to the end of the string if that is what they want.)
So someone could define the macros within this code without knowing any programming. Mind you to get the firmware onto the pro Micro they will still have to, at a minimum, learn the Arduino IDE.
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.