Skip to the content
2 layers190 × 75 mmKeyboardMacroPad, the printed circuit board in 3D

Repo for simple GUI that makes Serial data from a MacroPad work as a macro input device

Size
190 × 75 mm
Copper layers
2
Thickness
1.6 mm
Parts
75
Nets
88
Pads
336
Tracks, vias
972, 53
Pours
1
Routed
Yes
KiCad
KiCad 8.0 (file 20240108)
Created
22 Apr 2024
Updated
5 Jun 2026

Overview

KeyboardMacroPad is an open-source printed circuit board by brimgit, from the brimgit/MacroPad-Serial-To-Macros-GUI repository on GitHub. It is a 2-layer board of 190 × 75 mm with 75 parts on 88 nets, routed with 972 tracks and 53 vias.

It is built around the ESP32-DEVKITC-VE and SK6812MINI-E. Its parts include 52 diodes, 12 switches and 1 IC. It belongs with the keyboards and input and interfaces and adapters boards and the ESP32 boards of this library.

Main components

2

README

README.md

MacroPad

A full-featured desktop app for controlling a custom ESP32-based macropad over serial. Built with a React + Vite frontend running inside a pywebview frameless window, backed by a pure-Python layer for serial communication, audio control, and macro execution.


Features

Macros

  • Assign press and hold actions to all 8 keys and 4 encoder buttons

  • Configurable hold duration per key (100–3000 ms, default 500 ms)

  • Drag keys to swap their assignments directly on the grid

  • Copy / Paste macros between keys with one click

  • Undo the last macro edit with a single button

  • Supported macro types:

    TypeDescription
    Keyboard KeyAny letter, number, or special key
    Media ControlPlay/pause, next/prev track, volume up/down, mute
    Function KeyF1–F24
    Modifier KeyCtrl, Shift, Alt, Win, and combos (Ctrl+C, Alt+Tab, etc.)
    Type TextTypes a free-form string
    LaunchOpens a file, folder, application, or URL
    SystemLock screen, sleep, shutdown, or restart
    Mute AppToggles mute for the encoder's assigned audio source
    RecordedRecords a full keyboard sequence and replays it with original timing
    Multi ActionChains multiple macro steps into a single key press

Encoders

  • Each of the 4 encoders independently controls a volume source:
    • Any audio app (Discord, Spotify, browsers, games, etc.)
    • 🔊 Master Volume — system-wide output level
    • 🎤 Microphone — default capture device input level
  • Each app can only be assigned to one encoder at a time — assigning it elsewhere automatically clears the previous one
  • Offline indicator — encoder card shows a yellow ● OFFLINE badge if the assigned app is not currently running
  • Encoder button macros (press + hold) assignable per encoder, same types as keys
  • Mute toggle: pressing the encoder button mutes/unmutes the source
    • LED ring turns solid red while muted
    • Turning while muted flashes red continuously, then gives 3 final blinks to confirm still muted
    • Mute state is read on connect so the ring reflects reality immediately

LED Ring

Each encoder card shows a live 10-LED ring preview that mirrors the physical device:

  • Volume display — LEDs fill proportional to current volume %, shown for 2 s after each turn

  • Idle animations:

    EffectDescription
    OffStrip turns off after timeout
    BreatheAll LEDs pulse in and out (smootherstep curve)
    WaveBrightness ripples across the ring
    RainbowHue band scrolls around the ring
    ChaseBright spot bounces with fade trail
    Color CycleAll LEDs drift through the full spectrum
    SparkleRandom LEDs flash in the encoder's color
  • LED modes (color while active):

    • Default — green→red gradient tracking volume
    • Solid — single custom color
    • Fade — gradient between two custom colors

Profiles

  • Create, rename, duplicate, and delete named profiles
  • Each profile stores: all key macros, encoder button macros, encoder app assignments, LED mode/colors/effects
  • Import / Export profiles as .json files
  • Profiles are stored as individual files (Data/profiles/{name}.json) — easy to back up, diff, and share
  • Auto profile switching — configure a list of trigger apps per profile; the active profile switches automatically when that app comes into focus

Settings

SettingDescription
Serial Port & Baud RateConnect to the MacroPad over any COM port
LED BrightnessGlobal brightness (0–100%) sent to device on change
Enc LED OffIdle timeout before encoder strip turns off (2 / 5 / 10 s)
Effect SpeedAnimation frame rate: 5 ms (Ultra) → 50 ms (Light)
Export / Import ProfileSave or load the active profile as a .json file
Start with WindowsAdds MacroPad to the Windows startup registry key

Other

  • Device auto-detection — on startup the app sends a PING to the configured port and looks for MACROPAD_OK; if the wrong port is saved it scans all available ports automatically and updates the setting
  • Frameless window with a custom title bar — minimize, maximize, and close buttons blend into the app's colour scheme; the bar is draggable
  • Collapsible sidebar — collapse to icon-only mode to save screen space; hover tooltips identify each page
  • Auto-reconnect — if the device is unplugged the app reconnects automatically and restores all LED state
  • Test Mode — shows all 8 key assignments with live flash highlighting and a scrolling event log when keys are pressed
  • Firmware Upload — compile and flash .ino sketches directly from the app via Arduino CLI with a live log output
  • Update checker — checks GitHub for a newer version on the Settings page

Hardware

PCB designed in KiCad — schematic, board files, and Gerber files are in PCB_files/. Order directly from any PCB manufacturer with the Gerbers.

ESP32 microcontroller with:

  • 4× rotary encoders with push button (A/B/C/D)
  • 8× mechanical keys (1–8)
  • 4× NeoPixel LED strips (10 LEDs each, surrounding each encoder knob)

Running from Source

Requirements

  • Python 3.10+
  • Node.js 18+ (for building the frontend)

Install dependencies

bash
git clone https://github.com/brimgit/MacroPad-Serial-To-Macros-GUI
cd MacroPad-Serial-To-Macros-GUI

# Python dependencies
pip install -r requirements.txt

# Frontend dependencies
cd frontend
npm install
cd ..

Development mode (hot-reload)

bash
# Terminal 1 — Vite dev server
cd frontend
npm run dev

# Terminal 2 — Python backend (connects to Vite at localhost:5173)
python src/main_webview.py --dev

Production mode (no Node.js needed at runtime)

bash
# Build the frontend once
cd frontend
npm run build
cd ..

# Run the app
python src/main_webview.py

Python dependencies

PackagePurpose
pywebviewNative frameless window hosting the React frontend
pyserialSerial communication with ESP32
keyboardMacro execution and keystroke recording
pycawWindows audio session / endpoint volume control
psutilProcess name lookup for auto profile switching

Frontend stack

PackagePurpose
React 19UI framework
ViteBuild tool and dev server

Project Structure

text
src/
  main_webview.py      # Entry point — creates frameless pywebview window
  api.py               # Python API exposed to React via pywebview JS bridge
  macro_manager.py     # Macro storage, persistence, and execution
  profile_manager.py   # Profile CRUD, per-file JSON persistence
  serial_manager.py    # Serial connection, device identification, auto-reconnect
  volume_manager.py    # Per-app, master, and microphone volume control (pycaw)
  foreground_watcher.py# Polls foreground window for auto profile switching
  utils.py             # Path helpers for PyInstaller and data directory

frontend/
  src/
    App.jsx                     # Root component, state, event listeners
    components/
      Sidebar.jsx               # Navigation, profile management, theme toggle, collapse
      TitleBar.jsx              # Custom frameless title bar with window controls
      MacroModal.jsx            # Shared macro assignment modal (all types + Multi Action)
    pages/
      MacrosPage.jsx            # 2×4 key grid — drag/swap, copy/paste, undo
      EncodersPage.jsx          # Encoder cards with LED ring, volume, button macros
      SettingsPage.jsx          # Serial, brightness, LED, startup, import/export
      UploadPage.jsx            # Arduino CLI firmware upload with live log
      TestPage.jsx              # Live key-press display and event log

Firmware

The Arduino sketch is in MacroPad_Arduino_Code/. Upload it via the Upload Firmware page in the app (requires Arduino CLI) or via the Arduino IDE.

The firmware handles:

  • Encoder tick detection → E:{id}:{+/-} serial output (0-indexed)
  • Key press/release with hold-duration reporting → KP:{key}:DOWN / KP:{key}:UP:{ms}
  • Device identification → responds to PING with MACROPAD_OK
  • NeoPixel LED control: color modes, brightness, idle animations, effect speed, timeout
  • Serial command protocol: BRIGHT:, {n}:color(r,g,b), {n}:colorfade(...), EFFECT:{n}:{id}, ENC_TIMEOUT:, EFFECT_SPEED:
  • EEPROM persistence of LED color/mode settings across power cycles

License

MIT License

Parts

75
QtyValueFootprintReferences
40SK6812MINILED_SMD:LED_SK6812MINI_PLCC4_3.5x3.5mm_P1.75mmD13, D14, D15, D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26, D27, D28 +24
12DiodeScottoKeebs_Components:Diode_SOD-123D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12
8KeyswitchScottoKeebs_Hotswap:Hotswap_MX_1.00uS1, S2, S3, S4, S5, S6, S7, S8
4RotaryEncoder_SwitchRotary_Encoder:RotaryEncoder_Alps_EC11E-Switch_Vertical_H20mm_CircularMountingHolesSW1, SW2, SW3, SW4
1ESP32-DEVKITCESP32-DEVKITC:MODULE_ESP32-DEVKITCU1

The 65 most common of 75 parts.

Similar boards

  • 2 layers103.8 × 50 mmGalagino pcb set, the printed circuit board in 3D

    Galagino pcb set

    harbaum/galagino

    A Galaga, Pac-Man and Donkey Kong arcade emulator for the ESP32

    26 parts558
  • 2 layers115 × 75 mmSpinCoater, the printed circuit board in 3D

    SpinCoater

    RParkerE/OpenSilicon

    OpenSilicon enables DIY semiconductor fabrication with open-source guides for building IC equipment at home. The project includes BOMs, 3D files, firmware, and PDKs, supporting makers and researchers in chip fabrication.

    11 parts55GPL-3.0
  • 2 layers127.3 × 54.1 mmESP32 SolarBox, the printed circuit board in 3D

    ESP32 SolarBox

    cole8888/SRNE-Solar-Charge-Controller-Monitor

    Read data from SRNE solar charge controllers.

    34 parts42
  • 2 layers62.2 × 57.1 mmWs2mqtt, the printed circuit board in 3D

    Ws2mqtt

    Tho85/ws2mqtt

    Connect WiSafe2 devices to Home Assistant

    8 parts28BSD-3-Clause
  • 2 layers99.9 × 99.9 mmSplit flap, the printed circuit board in 3D

    Split flap

    tinkermax/split-flap

    DIY mechanical spli-flap display

    28 parts13CC-BY-4.0
  • 2 layersJF ECU32, the printed circuit board in 3D

    JF ECU32

    JoachimF/JF-ECU32

    RC Jet Engine ECU

    27 parts12GPL-3.0
  • 2 layers72.5 × 84.8 mmDevboard, the printed circuit board in 3D

    Devboard

    ste2425/PSP-Bluetooth-AVConnector

    An AV-Out Breakout library for the PSP. Providing Kicad symbols and footprints to interface with the PSP 2/3K AVOut socket (also known as the TVOut socket)

    13 parts12
  • 2 layers100 × 88.9 mmGen2, the printed circuit board in 3D

    Gen2

    Alignof/Juggernaut

    疑似時限爆弾解除競技

    41 parts10MIT

Questions

How big is the KeyboardMacroPad PCB?

It measures 190 × 75 mm and has 2 copper layers, 1.6 mm thick.

What parts does the KeyboardMacroPad use?

75 parts, built around the ESP32-DEVKITC-VE and SK6812MINI-E. The full list of its parts is on this page, with links to each part's symbol and footprint where PCBKit's library has them.

Where can I download the KeyboardMacroPad KiCad files?

From the brimgit/MacroPad-Serial-To-Macros-GUI repository on GitHub, at the commit this page was made from: the board is PCB_files/KeyboardMacroPad.kicad_pcb and its schematic PCB_files/KeyboardMacroPad.kicad_sch. PCBKit opens the board in the browser, with nothing to install.

Can I use the KeyboardMacroPad design in my own project?

Its repository states no licence, so its author keeps all rights: ask brimgit before reusing the design.