This repo contains all the code for turning a Keybow 2040 into a fully fledged data-driven macropad.
Huge thanks to the many software devs that contributed to this project:
Neradoc for the Control Codes
A lot of Adafruit Devs for the CircuitPython Libraries
ManelTo for the starting source code
- Keybow 2040 by Pimoroni
- I2C Stemma QT Rotary Encoder Breakout with NeoPixel - STEMMA QT / Qwiic
- Monochrome 0.96" 128x64 OLED Graphic Display - STEMMA QT
- A Rotery Encoder with Push Button
- SparkFun Qwiic Cable Kit
- 10mm M2 Hex Bolts
- M2.5 Flat Top Screws
- USB C Cable
- Knob
Print the files ManelTo created. The file names are in Spanish but you will need to print:
- cajaKeyBow-Anexos.stl
- cajaKeyBow-Caja.stl
If you would like a tilt-stand, one of:
- cajaKeyBow.FCStd (10 mm foot)
- cajaKeyBow-pie5mm.stl (5mm foot)
Once the prints are completed, remove the plugs from the various holes in the prints. There are two holes on the right side that are a bit of a challenge to remove. I ended up using tweezers to pull the plugs out. It took some time.
Next, set your soldering iron to just above the melting temperature of the filament you used. Then align a 2.5 mm insert for 12 pegs on the front and back cases and push them in with the soldering iron.
If you are confused on the process, watch this video.
Solder a cut off QT stemma connector to the pins on the KEYBOW 2040. You will need a good amount of space so I recommend using the 200mm or 150mm cables. The breakout of the connectors is:
Black | Red | Blue | Yellow |
---|---|---|---|
GND | 3.3V | SDA | SCL |
Secure everything down with the appropriate screws, then hook it all up with the cables from the kit. It'll be a tight fit inside so be careful and don't use too much force. THere are paths to run cables around the various pieces if you are patient.
Several libraries have changes from their defaults to modify behavior.
pmk
has the pinout rotated for the board.adafruit_hid
has an expanded Consumer Control Code list.
First, update your Keybow 2040 to CircuitPython 7.3.3 using the firmware found here.
Next, copy all the files in this repo (except the .github
folder) onto the board, replace any existing files.
Finally, customize the maps.json
as you see fit.
{
"layers": [
...
]
}
-
"name": "The short name of the layer shown when switching layers"
"name": "General",
-
"description": "A internally unused description of the layer that can be longer"
"description": "General Keybinds",
-
"color": An RGB Color code split into a 3 segment array that sets the encoder color
"color": [ 255, 255, 0 ],
-
"keymap": A 16 length array of control commands. This value must be exactly 16 commands. Leave the others listed as unused as described below if needed.
Example Keymap
"keymap": [ { "label": "Ins.", "type":"key", "keys": [ "INSERT" ], "color": [ 0, 0 , 255] }, { "label": "Home", "type":"key", "keys": [ "HOME" ] , "color": [ 0, 0 , 255] }, { "label": "PgUp", "type":"key", "keys": [ "PAGE_UP" ], "color": [ 0, 0 , 255] }, { "label": "()", "type": "text", "text": "()", "color": [ 255, 0, 0] }, { "label": "Del", "type": "key", "keys": [ "DELETE" ], "color": [ 0, 0 , 255] }, { "label": "End", "type": "key", "keys": [ "END" ], "color": [ 0, 0, 255] }, { "label": "PgDn", "type": "key", "keys": [ "PAGE_DOWN" ], "color": [ 0, 0 , 255] }, { "label": "Win", "type": "key", "keys": [ "GUI" ], "color": [ 0, 0 , 255] }, { "label": "Ctrl", "type": "key", "keys": [ "CONTROL" ], "color": [ 0, 0 , 255] }, { "label": "Alt", "type": "key", "keys": [ "ALT" ], "color": [ 0, 0, 255] }, { "label": "ArrUp", "type": "key", "keys": [ "UP_ARROW" ], "color": [ 255, 255, 255] }, { "label": "Pause", "type": "key", "keys": [ "PAUSE" ], "color": [ 0, 0, 255] }, { "label": "Shift", "type": "key", "keys": [ "SHIFT" ], "color": [ 0, 0, 255] }, { "label": "LftAr", "type": "key", "keys": [ "LEFT_ARROW" ], "color": [ 255, 255, 255] }, { "label": "DwnAr", "type": "key", "keys": [ "DOWN_ARROW" ], "color": [ 255, 255, 255] }, { "label": "RigAr", "type": "key", "keys": [ "RIGHT_ARROW" ], "color": [ 255, 255, 255] } ],
-
"encoder_down_action": A control command with the
type
and required pair (keys
,text
orcontrol
) that is run when the knob is turned counter-clockwise"encoder_down_action": { "type": "control", "control": "VOLUME_DOWN" }
-
"encoder_up_action": A control command with the
type
and required pair (keys
,text
orcontrol
) that is run when the knob is turned clockwise"encoder_up_action": { "type": "control", "control": "VOLUME_UP" }
A control command is defined in lib/macro_pad/control.py
. I encourage you to take a look.
A control command is composed of a few parts.
-
label
: The label shown when the command is displayed on the OLED screen -
type
: one ofkey
,text
, orcontrol
key
will any number of keys and release them when the key is releasedtext
will type the message as if it is the keyboardcontrol
will send a ConsumerControl HID code.
-
color
: The color the interaction will change a key to when pressed -
keys
: Required fortype=key
. An array of keys that can be pressed. The valid options are listed inlib/adafruit_hid/keycode.py
. These keys will act as if they were typed on a US_en keyboard. (If you need something else, look into using Neradoc's library).A parentheses
(
could be typed with thekeys
"keys": [ "SHIFT", "NINE" ]
-
text
: Required fortype=text
. A string of text to be sent by the macropad"text": "Hello world"
-
control
: Required fortype=control
. A Consumer control code as found inlib/adafruit_hid/consumer_control_code.py
. There are more of them not listed in that file, if you find one you need, feel free to open a PR. The HID Usage Tables for Universal Serial Bus (USB) if needed."control": "VOLUME_DOWN"
Open a serial connection with baud 9600
to the device and you can see error messages get printed