low-profile hexagon keyboards.

firmware hacking

The 0x33.board firmware is built on CircuitPython and can easily be modified while the board is connected to a computer.

updating/installing the firmware

These steps assume you already have the latest version of CircuitPython installed on the board. If this is not the case, follow the steps in the next section first.

  1. If you don’t see a HEX33BOARD or CIRCUITPYTHON drive when connecting the board to your computer, you need to enter dev mode first (see below).
  2. Download or clone the firmware source code source code.
  3. Back up your profiles directory to make sure you don’t lose your settings when updating.
  4. Change config.py to reflect your hardware revision or any changes you made.
  5. Copy all files from the repo to the drive.
  6. Use circup to install the dependencies, or manually get them from the Adafruit CircuitPython library bundle:

    $ cd $DRIVE
    $ circup --path . install -r requirements.txt

updating/installing CircuitPython

  1. Download the latest CircuitPython build (.uf2 file) for the Solderparty RP2040 Stamp.
  2. Connect the 0x33.board to a computer.
  3. Reset the board into bootloader mode by double-pressing the RESET button in the small hole on the bottom of the 0x33.board. A new removable drive with the UF2 bootloader should appear.
  4. Copy the .uf2 file to the removable drive. The drive should disappear and reappear with a different name.
  5. Reinstall the hex33board firmware (see above).

debugging & the serial console

The firmware can print debugging messages and errors to the Serial Console. See the Adafruit guide for connecting to the CircuitPython Serial Console for information on how to access it.

After connecting, you can enter CTRL+C to interrupt the firmeware and press any key to enter the REPL. It can be useful to load the board config (with the hardware pin assignments) and/or instantiate Keyboard for debugging:

from hex33board import Keyboard
import config as board

k = board.Keyboard(board)

dev mode

When the board is in dev mode, it will show up on a computer as a flash storage in addition to MIDI and Serial connections. This allows viewing or changing the stored profile data, firmware source code etc.

When the board turns on, it will enter dev mode when either:

  • the config.py option dev_mode is set to True
    • setting this will keep the board in dev mode across restarts
  • the menu key is held down while the board is plugged in or reset
    • this override is temporary

When the board is in dev mode, profiles can’t be saved (so any settings changed will be lost). When the board is set to dev_mode=True in config.py, holding down the menu key while the board starts will temporarily bring the board out of dev mode. This can be useful to test or debug issues with profile saving etc. during development.


The firmware can be run without any hadrware using ‘regular python’ on a computer. To do this, install the dependencies and run simulator.py:

$ pip install -r requirements.sim.txt # you may want to do this in a venv
$ python simulator.py

This will start the simulator server, which can now be accessed in a browser at http://localhost:8000/. The simulator currently supports pressing keys, RGB lighting and display output via the web interface. It also exposes MIDI ports via python rtmidi API.

hardware input

A hardware keyboard configured with sysex_key_sync = True and connected via USB to the simulator’s virtual USB-MIDI input can be used as a hardware control surface for the simulator.

In this case the firmware will be running twice in parallel: once on the physical device, and once on the computer. Only key press/release events are shared, so care must be taken to start with the devices in the same state in order to keep them in sync.