Skip to content

Software for a comprehensive macro pad with encoder and OLED screen

Notifications You must be signed in to change notification settings

ntindle/Keybow2040-Macro-Pad

Repository files navigation

KEYBOW 2040 MACRO PAD

This repo contains all the code for turning a Keybow 2040 into a fully fledged data-driven macropad.

Special thanks to ManelTo for the designs!
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

Requirements

Hardware

Tools

3D Prints

Printing

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)

Assembly

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.

Programming

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.

maps.json

The `maps.json` file is what drives the macro pad. It is a json object made of one or more layers.
{
    "layers": [
        ...
    ]
}

layers

A layer is defined by a few things.
  • "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 or control) 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 or control) that is run when the knob is turned clockwise

    "encoder_up_action": {
                  "type": "control",
                  "control": "VOLUME_UP"
              }

Control Commands

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 of key, text, or control

    • key will any number of keys and release them when the key is released
    • text will type the message as if it is the keyboard
    • control will send a ConsumerControl HID code.
  • color: The color the interaction will change a key to when pressed

  • keys: Required for type=key. An array of keys that can be pressed. The valid options are listed in lib/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 the keys

     "keys": [
          "SHIFT",
          "NINE"
     ]
  • text: Required for type=text. A string of text to be sent by the macropad

    "text": "Hello world"
  • control: Required for type=control. A Consumer control code as found in lib/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"

Debugging

Open a serial connection with baud 9600 to the device and you can see error messages get printed

Releases

No releases published

Packages

No packages published

Languages