Skip to content

FutilityDesigns/Continuum-keyboard

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

11 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Continuum Keyboard

Open-source firmware and companion tools for custom, application aware keyboards and macropads
By Futility Designs


Current Status

This firmware, while generally stable, should be considered a Beta release until a formal release is added. Bugs are still being located and worked out.

Table of Contents


Overview

Continuum is a flexible keyboard firmware built on the RP2040 microcontroller. It is designed to run on anything from a 1-key macro pad to a full 110-key keyboard — the physical layout is entirely up to you. There is no fixed PCB shape or key count baked into the firmware; you define the layout, wiring, and key assignments through the included visual configuration tool.

The firmware supports plain key assignments, multi-key macros, layer switching, and per-key OLED displays that show what each key does at a glance. Paired with the Active Window Monitor running on your PC, the keyboard can automatically switch its entire layout as you jump between applications — making it a powerful productivity tool, especially for macro pads.

macroPad + keyboard


Key Features

Feature Description
Any size or shape Configure from 1 to 110 keys in whatever physical layout you need.
Multiple key action types Keystroke (tap), key hold, additive macros (chord), consecutive macros (sequence), layer hold (Fn-style), layer toggle, and mode selection.
Up to 8 layers Define separate layers for different tasks or applications, each with its own key assignments, LED colors, and OLED labels.
Per-key OLED displays Tiny SSD1306 72×40 OLED screens embedded in key caps show the current function — text labels or custom monochrome icons.
Per-key RGB LEDs WS2812B NeoPixel LEDs under every key with solid or reactive (press-to-flash) modes and per-layer color schemes.
Automatic power management LED brightness is automatically calculated to stay within USB power limits based on the number of LEDs in your specific device.
Application-aware switching The Active Window Monitor detects your foreground app and tells the keyboard to switch layouts automatically.
Dual-core architecture Key scanning and HID run on Core 0 for minimal input latency; displays, LEDs, and SD card I/O run on Core 1.
SD card + flash storage Configuration files live on an SD card. The firmware caches them to on-chip flash so the keyboard keeps working even if the SD card is removed.
USB HID + serial The keyboard appears as a standard USB HID device. A CDC serial channel enables live communication with the PC tools.
Visual configuration tool The Keyboard Mapper provides a complete drag-and-drop GUI — no code editing or config file hand-writing required.

OLED Key Caps

macropad keycaps

The standout feature of Continuum is support for per-key OLED displays. Each key cap can contain a small 72×40 pixel monochrome OLED screen. This means every key can display:

  • Text labels — the key's display name, automatically updated when you switch layers.
  • Custom icons — monochrome 72×40 XBM images uploaded through the configuration tool and stored on flash/SD.

No More Forgetting Your Layouts

On a traditional macro pad, if you want per application layouts you're forced to memorize each one. The OLEDs make sure you can always see the assigned layout.

When paired with the Active Window Monitor, your macro pad becomes a dynamic control surface that adapts to whatever you're working in. Switch to your browser and the keys can show "New Tab," "Refresh," "Bookmark." Switch to Fusion 360 and they show "Line," "Extrude," "Sketch." It all happens automatically.

auto layout switching live function switching

Sleeping and waking

After a configurable inactivity timeout the firmware puts the OLEDs and LEDs to sleep to save power. Any key press wakes them instantly.


LED Lighting and Power Management

Every key supports an individually addressable WS2812B NeoPixel LED. The LED system offers:

  • Solid mode — static colors per key, per layer.
  • Reactive mode — a base color at rest that flashes to a press color when the key is hit.
  • Per-layer color schemes — each layer can define its own base and press colors, with optional per-key overrides.

reactive LEDs

Automatic brightness limiting

USB 2.0 provides a maximum of 500 mA. After reserving power for the RP2040, peripherals, and OLEDs, there is a finite budget available for LEDs. The firmware automatically calculates the maximum safe brightness based on the number of LEDs in your build and caps brightness to stay within the USB power budget. This means:

  • A 12-key macro pad can run brighter than a 60-key board.
  • You never risk browning out or damaging your USB port.
  • Brightness is constrained between a visible floor and a hard maximum of 50%.

Future addition: USB Power Delivery (PD) negotiation will allow the firmware to request higher voltage/current from PD-capable ports and raise the brightness ceiling accordingly. For now, the firmware always assumes standard 500 mA USB 2.0 power.


Firmware Architecture

The firmware runs on the RP2040's dual cores:

Core Responsibilities
Core 0 Key scanning, debounce, HID report generation, serial protocol, layer/app switching — all latency-critical tasks.
Core 1 OLED display updates, NeoPixel LED output, SD card I/O — latency-tolerant tasks that should never block input.

Configuration files

All configuration is JSON-based. Configurations can be written and placed on the sd card manually, or configurations are uploaded directly to the device over USB using the Keymapper tool.

File Purpose
hardware.json Physical wiring — which pins, which expanders, which keys have OLEDs.
keys.json Keymap — layers, key actions, display names, macro sequences, OLED images.
led_config.json LED mode, per-layer base/press colors, per-key overrides.
settings.json Device name, sleep timeout, wake behavior.

On first boot with no configuration, the firmware enters setup mode — it accepts only USB commands, waiting for you to push a hardware config from the Keyboard Mapper.


Hardware Requirements

This firmware is written in a way that should make it fairly generic in terms of wiring and hardware, however I can't promise all configurations will work.

Component Details
Microcontroller RP2040-based board (e.g. Raspberry Pi Pico)
GPIO Expanders MCP23017 (Optional, but recommended. Other GPIO expander support to be added)
LEDs WS2812B / NeoPixel (one per key, Use GPIO 24)
OLED displays SSD1306 72×40 SPI (optional, one per key)
Storage SD card over SPI (optional, but highly encouraged. Without storage you're limited to one layout and no immage support)
Shift registers 74HC595 (Optional, used to control the CS pins of the OLED displays)

Note: The firmware currently prefers direct GPIO and MCP23017 I2C expander key inputs. Row/column matrix scanning (as used by most conventional keyboards) is has been added but is largely untested at this time.

Pin Selections - The firmware allows almost any pin to be assigned to any function, with the following exceptions:

  • OLEDs and SD cards should be wired with MISO: GPIO16, MOSI: GPIO19, CLK: GPIO18. CS pins should be connected to 74HC595 Shift Registers
  • GPIO 9+17 are hard coded as dummy CS and Reset pins for the OLED/SD card SPI Bus and should not be used.
  • If OLEDs are used, shift registers should be on a second SPI bus using LATCH: GPIO13, CLK: GPIO14, MOSI: GPIO15, RESET: GPIO10
  • GPIO 4+5 should be reserved for I2C
  • GPIO 0+1 should be reserved for UART
  • GPIO24 should be used for LED data (this will be made configurable in the future)

Getting Started

Prebuilt Firmware

Firmware is provided in the releases section with notes about changes in that revision. The released firmware should run on any RP2040 based keyboard controller, but be sure to check the known issues and requirements listed below.

  1. Put your RP2040 based controller into boot mode and drag the .uf2 file onto the storage partition.
  2. Allow the device to flash and reboot
  3. If there are no configuration files found on the device, it will enter a setup mode and wait for configuration from the Keymapper tool. See the configuration steps below.

Building the firmware

If you wish to modify the firmware or change hardware defaults you can build it yourself.

  1. Install PlatformIO.
  2. Clone this repository.
  3. Open the project and make any desired changes.
  4. Build and upload:

Configuring your keyboard

  1. Run the Keyboard Mapper:
    cd tools
    python -m keyboard_mapper
    
  2. Design your layout in the Layout tab.
  3. Set up wiring in the Hardware tab.
  4. Define your layers and key actions in the Keymap tab.
  5. Configure LED colors in the LED tab.
  6. Push to device or export the JSON files to an SD card.

Enabling automatic app switching

  1. Run the Active Window Monitor:
    cd tools
    python -m active_window_monitor
    
  2. Your keyboard is auto-detected. The monitor begins reporting the foreground application.
  3. Tag your keymap layers with application names in the Keymap tab (e.g. set Application to chrome or Fusion360).

Companion Tools

Two PC-side tools work together with the firmware:

Keyboard Mapper

Keymapper

The Keyboard Mapper is a visual desktop application for designing and configuring your keyboard. It makes it easy to lay out and configure any keyboard in any custom shape and size — no JSON hand-editing needed.

Layout Tab — drag-and-drop key placement

  • Add individual keys with custom width and height (in standard key units: 1U, 1.5U, 2U, etc.).
  • Add grids of keys — enter rows, columns, and key size to instantly create a macro pad layout.
  • Click and drag keys to reposition them on the canvas.
  • Resize keys by selecting them and adjusting width/height in the property panel.
  • Duplicate or remove keys as needed.

The canvas displays a unit grid so keys snap into natural positions. This is the foundation of your keyboard — define the physical shape here and everything else follows.

Hardware Tab — wiring configuration

  • Set each key's input source: MCP23017 I2C expander or direct GPIO.
  • Configure expander index, pin number, and NeoPixel LED index.
  • Mark keys that have a mounted OLED display and assign their shift-register CS bit.
  • Bulk actions for fast setup: auto-number LED indices, toggle all OLEDs on/off.

hardware tab

Keymap Tab — actions and layers

  • Create up to 8 layers (e.g. Base, FN, Media, application1, etc.).
  • Set a default layer that loads on boot.
  • Tag layers with an application name for automatic switching.
  • Configure each key's action per layer:
    • Keystroke — Ignores how long the key is held, just sends a press/release once.
    • Key Hold — Standard key, reports as held as long as the key is physically held down.
    • Macro — Fully customizable sequences of key pressed, holds, delays, and releases.
    • Mode — enter interactive layer selection on the device.
    • Layer Hold — activate a layer while held (like a Fn key).
    • Layer Toggle — toggle a layer on or off.
    • Layer Switch - Directly switch layers with no actual key inputs.
  • Assign display names and OLED images per key per layer.
  • Visual macro step editor with add, remove, and reorder.

keymap tab

LED Tab — color configuration

  • Choose between solid and reactive LED modes.
  • Set base and press colors per layer.
  • Override colors for individual keys.
  • Visual preview on the canvas showing the color layout.

led tab

Settings Tab

  • Choose behavior for keypresses that wake a device
  • Set a custom device name (shown in the Active Window Monitor).
  • Configure sleep timeout and wake behavior.

Project files and export

  • Save and load .kbproj project files that preserve your full layout, hardware, keymap, and LED configuration.
  • Export individual firmware JSON files (keys.json, hardware.json, led_config.json, settings.json) for placement on the SD card.
  • Push to device directly over USB — the mapper communicates with the Active Window Monitor, which relays configurations to connected keyboards in real time.

push menu


Active Window Monitor

Active Window Monitor

The Active Window Monitor is a lightweight Windows system-tray utility that bridges your PC and your keyboard. It detects which application you're currently using and tells the keyboard to switch layouts automatically.

How it works

  1. The monitor calls the Windows API (GetForegroundWindow) to identify the active window.
  2. It resolves the owning process name via QueryFullProcessImageNameW.
  3. The process name is sent to all connected keyboards over USB serial.
  4. The keyboard firmware finds a layer tagged with that application name and switches to it.
  5. The keyboard replies with the new active layer.

Multi-device support

The monitor auto-detects Continuum keyboards by their USB VID/PID and can manage multiple devices simultaneously. Each device appears as a row in the UI with its own COM port, connection status, and send toggle.

Application memory

The firmware remembers your last-used layer per application. If an app (like a CAD program) has multiple tagged layers, manually switching between them is remembered — so when you alt-tab away and back, you return to the exact layer you were using.

System tray integration

  • Minimizes to the system tray with a blue keyboard icon.
  • Optional Start with Windows — runs automatically at login (no admin required).
  • No external dependencies besides Python (or use the standalone .exe build).

Standalone executables

Both tools can be built into standalone .exe files and run without any need for the command line. Pre-built executables are provided in the releases section. If you prefer to build them yourself so so with the following commands from the project directory.

cd tools
build_monitor.bat    # builds Active Window Monitor
build_mapper.bat     # builds Keyboard Mapper

Roadmap

  • Row/column matrix scanning validation — support for traditional keyboard matrices has been added, but remains untested.
  • USB Power Delivery negotiation — detect PD capability on the connected port and raise LED brightness limits when higher power budgets are available. This requires custom hardware on the controller to manage the PD connection status. Documentation to be created.
  • Linux and macOS support for the prebuilt Active Window Monitor and Keymapper Tools.
  • More display options — support for additional OLED resolutions, and potentially full color TFT displays.
  • RP2350 Support - It would be nice to port to the RP2350 in the future, no promises on timelines

Related Hardware

Hardware projects developed alongside this firmware:

  • OLED KEYCAPS - Fully open source hardware designs for oled keys that function with this firmware
  • Continuum USB Hub + Keyboard Controller - Open sourced Keyboard controller integrated into a 6 port USB3.2 hub with USB PD management (link to be provided when repository is complete)
  • Continuum Companion Full Sized Keyboard - Open Sourced Full 108 key Keyboard to go with the Hub + Controller (link to be provided when repository is complete)

License

This project is licensed under the MIT License — see the LICENSE file for full text.

You are free to use, modify, and distribute this firmware and its companion tools for any purpose, including commercial use, as long as the original copyright notice is retained.


Built by Futility Designs

About

Custom keyboard firmware by Futility Designs

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors