Previously, I discussed the Adafruit Bluefruit EZ-Key module. This device comes factory-programmed to send specific key sequences via Bluetooth when one of the 12 inputs is selected. Software is available to change these key sequences, but this software runs on a host computer and requires installing an older version of a development environment called Processing.
Since it appears that the remapping is done simply by sending a text HEX sequence with a checksum to the EZ-Key, I thought it might be easier to just do this on an Arduino with a simple text user interface – no special installs needed.
I did a bit of work on this, and wanted to share my work-in-progress and maybe get some feedback on the interface.
Basically, for each of the 12 inputs you can specify a modifier (SHIFT, CTRL, ALT, etc.) plus up to 6 keycodes which will be sent out (with a Keys-Down) via Bluetooth. When the input is released, a matching Keys-Up message is sent.
To customize, you simply need to specify an input (0-11) and then a modifier (8 available choices) and then up to 6 keycodes (about 112 options available, such as ARROW UP or “k” or numeric keypad minus). I put together a very quick user interface, and here is a sample session, with comments on what is going on:
Adafruit Bluefruit EZ-Key Remapper 0.00 by Allen C. Huffman (alsplace@pobox.com) Enter input to configure (0-11), [L)ist, [U)pdate or [Q)uit: L * Here, I select "L" to list the current input config. Input Key Codes: ----- ---------- 0. ARROW_UP 1. ARROW_DOWN 2. ARROW_LEFT 3. ARROW_RIGHT 4. RETURN 5. SPACE 6. 1 7. 2 8. W 9. A 10. S 11. D Enter input to configure (0-11), [L)ist, [U)pdate or [Q)uit: 6 * I select "6" to change input 7 (currently sends "1"). Editing Input 6 Configuration: Modifier: NONE - Enter new modifier # (0-8), [L)ist, [ENTER)Skip or [Q)uit: L * To see a list of available modifiers, I select "L". 0. NONE 3. ALT_LEFT 6. SHIFT_RIGHT 1. CTRL_LEFT 4. GUI_LEFT 7. ALT_RIGHT 2. SHIFT_LEFT 5. CTRL_RIGHT 8. GUI_RIGHT Modifier: NONE - Enter new modifier # (0-8), [L)ist, [ENTER)Skip or [Q)uit: 1 Setting new modifier value to: CTRL_LEFT * By selecting "1", I am choosing the modifier to be "CTRL_LEFT". Modifier: CTRL_LEFT - Enter new modifier # (0-8), [L)ist, [ENTER)Skip or [Q)uit: * It shows the Modifier line again, and by pressing ENTER, it skips and moves to the next item - Keycodes 0-5: Keycode0: 1 - Enter new key code # (0-111), [L)ist, [ENTER)Skip or [Q)uit: 0 * By entering "0", I am selecting "KEY_NONW" - no key. In this example, I am making this input simply send the left CTRL key. Setting new keycode value to: NONE Keycode0: NONE - Enter new key code # (0-111), [L)ist, [ENTER)Skip or [Q)uit: * By pressing ENTER five more times, it skips over key codes 1, 2, 3, 4 and 5, leaving them to their current values of "NONE". Keycode1: NONE - Enter new key code # (0-111), [L)ist, [ENTER)Skip or [Q)uit: Keycode2: NONE - Enter new key code # (0-111), [L)ist, [ENTER)Skip or [Q)uit: Keycode3: NONE - Enter new key code # (0-111), [L)ist, [ENTER)Skip or [Q)uit: Keycode4: NONE - Enter new key code # (0-111), [L)ist, [ENTER)Skip or [Q)uit: Keycode5: NONE - Enter new key code # (0-111), [L)ist, [ENTER)Skip or [Q)uit: Enter input to configure (0-11), [L)ist, [U)pdate or [Q)uit: L * Now I use "L" to list the input config again, and can see that input 6 is now set to send the left CTRL key: Input Key Codes: ----- ---------- 0. ARROW_UP 1. ARROW_DOWN 2. ARROW_LEFT 3. ARROW_RIGHT 4. RETURN 5. SPACE 6. CTRL_LEFT 7. 2 8. W 9. A 10. S 11. D Enter input to configure (0-11), [L)ist, [U)pdate or [Q)uit: 7 * I then change input 7: Editing Input 7 Configuration: Modifier: NONE - Enter new modifier # (0-8), [L)ist, [ENTER)Skip or [Q)uit: L * I want to make this input send ALT-Q, but I forgot what modifiers are available so I "L" to list them again. 0. NONE 3. ALT_LEFT 6. SHIFT_RIGHT 1. CTRL_LEFT 4. GUI_LEFT 7. ALT_RIGHT 2. SHIFT_LEFT 5. CTRL_RIGHT 8. GUI_RIGHT Modifier: NONE - Enter new modifier # (0-8), [L)ist, [ENTER)Skip or [Q)uit: 3 * "3" is the left ALT key. Setting new modifier value to: ALT_LEFT Modifier: ALT_LEFT - Enter new modifier # (0-8), [L)ist, [ENTER)Skip or [Q)uit: * Then I press ENTER, and it goes to key code 0, which is currently the "2" key. I want to change that. Keycode0: 2 - Enter new key code # (0-111), [L)ist, [ENTER)Skip or [Q)uit: L * But since I don't know what key codes are available, I choose "L" to get a huge list of all of them. 0. NONE 28. 2 56. F2 84. KEYPAD_PLUS 1. A 29. 3 57. F3 85. KEYPAD_ENTER 2. B 30. 4 58. F4 86. KEYPAD_1 3. C 31. 5 59. F5 87. KEYPAD_2 4. D 32. 6 60. F6 88. KEYPAD_3 5. E 33. 7 61. F7 89. KEYPAD_4 6. F 34. 8 62. F8 90. KEYPAD_5 7. G 35. 9 63. F9 91. KEYPAD_6 8. H 36. 0 64. F10 92. KEYPAD_7 9. I 37. RETURN 65. F11 93. KEYPAD_8 10. J 38. ESCAPE 66. F12 94. KEYPAD_9 11. K 39. BACKSPACE 67. PRINT_SCREEN 95. KEYPAD_0 12. L 40. TAB 68. SCROLL_LOCK 96. KEYPAD_PERIOD 13. M 41. SPACE 69. PAUSE 97. EUROPE_2 14. N 42. MINUS 70. INSERT 98. APPLICATION 15. O 43. EQUAL 71. HOME 99. POWER 16. P 44. BRACKET_LEFT 72. PAGE_UP 100. KEYPAD_EQUAL 17. Q 45. BRACKET_RIGHT 73. DELETE 101. F13 18. R 46. BACKSLASH 74. END 102. F14 19. S 47. EUROPE_1 75. PAGE_DOWN 103. F15 20. T 48. SEMICOLON 76. ARROW_RIGHT 104. CONTROL_LEFT 21. U 49. APOSTROPHE 77. ARROW_LEFT 105. SHIFT_LEFT 22. V 50. GRAVE 78. ARROW_DOWN 106. ALT_LEFT 23. W 51. COMMA 79. ARROW_UP 107. GUI_LEFT 24. X 52. PERIOD 80. NUM_LOCK 108. CONTROL_RIGHT 25. Y 53. SLASH 81. KEYPAD_SLASH 109. SHIFT_RIGHT 26. Z 54. CAPS_LOCK 82. KEYPAD_* 110. ALT_RIGHT 27. 1 55. F1 83. KEYPAD_MINUS 111. GUI_RIGHT Keycode0: 2 - Enter new key code # (0-111), [L)ist, [ENTER)Skip or [Q)uit: 17 * Since I want to send a "q" key, that is 17. Setting new keycode value to: Q Keycode0: Q - Enter new key code # (0-111), [L)ist, [ENTER)Skip or [Q)uit: * Above, it confirms that key code 0 is now "Q". I can then press ENTER to skip the next five optional key codes for this input. Keycode1: NONE - Enter new key code # (0-111), [L)ist, [ENTER)Skip or [Q)uit: Keycode2: NONE - Enter new key code # (0-111), [L)ist, [ENTER)Skip or [Q)uit: Keycode3: NONE - Enter new key code # (0-111), [L)ist, [ENTER)Skip or [Q)uit: Keycode4: NONE - Enter new key code # (0-111), [L)ist, [ENTER)Skip or [Q)uit: Keycode5: NONE - Enter new key code # (0-111), [L)ist, [ENTER)Skip or [Q)uit: Enter input to configure (0-11), [L)ist, [U)pdate or [Q)uit: L * Back to the main menu, I do an "L" to list the current input config. Input Key Codes: ----- ---------- 0. ARROW_UP 1. ARROW_DOWN 2. ARROW_LEFT 3. ARROW_RIGHT 4. RETURN 5. SPACE 6. CTRL_LEFT 7. ALT_LEFT + Q 8. W 9. A 10. S 11. D Enter input to configure (0-11), [L)ist, [U)pdate or [Q)uit: U * And they look good. Input 6 is now left CTRL, and input 7 is now left ALT + the Q key. Cool. Selecting "U" will update the EZ-Key to use this new config. ...update device here...
…and there you have it. A very simple and easy-to-use “BIOS-like” interface to remap the Adafruit EZ-Key directly from an Arduino, without touching a line of source code or installing anything special.
Does this seem useful? Should I polish it up and post it? I just created it because I was too lazy to download stuff and writing my own seemed more fun.
Let me know what you think in the comments…
I like your idea: connect – just transfer new keymapping (and all without Processing-overload)
Did you try to transfer Consumer keys? Like VolumeUp.
I couldn’t find any key code for consumer keys, like KEY_A = byte(0x04).
While the EZ-Key device can send consumer keys (by manually building and sending a packet), I am not sure they can be remapped. They are not listed in the table I used for this program. This would be a good question for the Adafruit forums — I will try to ask over there when I get a moment, but if you find out before I do, please let me know. I’d update my program on github to support it.
I have read the adafruit introducing-bluefruit-ez-key-diy-bluetooth-hid-keyboard … and maybe the following will help:
[..]
Raw HID Consumer Reports
As of v1.2, Bluefruit can send raw HID consumer reports. There are “Home”, “KeyboardLayout”, “Search”, “Snapshot”, “VolumeUp”, “VolumeDown”, “Play/Pause”, “FastForward”, “Rewind”,”Scan Next Track”, “Scan Previous Track”, “Random Play”,”Stop” keys you can use with a 2 bytes bitmask.
Raw HID consumer report start with 0xFD and have 8 bytes following. For consumer keys, its
0xFD 0x00 0x02 [bitmask] [bitmask] 0x0 0x0 0x0 0x0
“Home” is bit 0, the bitmask is 0x01 0x00
“Stop” is bit 12, the bitmask is 0x00 0x10
[..]
As a result you will get (or similar):
Home – 0002010000000000
KeyboardLayout – 0002020000000000
Search – 0002040000000000
Snapshot – 0002800000000000
VolumeUp – 0002100000000000
VolumeDown – 0002200000000000
Play/Pause – 0002400000000000
Fast Forward – 0002800000000000
Rewind – 0002000100000000
Scan Next Track – 0002000200000000
Scan Previous Track – 0002000400000000
Random Play – 0002000800000000
Stop – 0002001000000000
Good find. It does allow for sending those key sequences, but I don’t see them in the firmware’s remap for the 12 built in buttons. If the EZ-Key is being used with a micro (like a Teensy or Arduino), it could send them.
I have’t spend any time on my iCade EZ-Key project when someone pointed out that sending packets at 9600 baud (the speed between micro an EZ-Key) would probably produce lag for high speed game controlling — not that someone with my limited game skills would notice (I blame it on the joystick anyway). However, someone did point me to a better part of just sending sequences via a micro — also around the $20-$25 price point. That is what I will probably be looking at next.