Open-source USB stream deck firmware for RP2040 boards (RP2040-Zero, etc.). Turn any RP2040 microcontroller into a fully configurable stream deck with a native desktop app.
- Composite HID+CDC USB Device — acts as both a keyboard and a serial port for configuration
- Desktop App — native Tauri app for macOS, Windows, and Linux with serial port access
- Native App Launching — launch apps directly via OS APIs (no keyboard shortcuts)
- 7 Action Types — key press, consumer control, macro (true combos), text, paste, app launcher
- Configurable Pins — remap any button to any GPIO, any number of buttons
- Flash Storage — persist button configs to on-chip flash with CRC32 validation
- GitHub Pages — use the webconfig directly from your browser
| Component | Quantity | Notes |
|---|---|---|
| RP2040-Zero | 1 | Any RP2040 board works, but the Zero is compact and has USB-C |
| MX-compatible switches | 6 (or your count) | Cherry MX, Gateron, Kailh, etc. — 3-pin or 5-pin |
| Wire | ~5-10 cm | 26-28 AWG solid core or stranded, any colors |
| Keycaps | 6 (or your count) | MX-compatible keycaps |
| 3D-printed case | 1 | See Enclosure below |
| USB-C cable | 1 | For connection and power |
This project uses the OneClick MacroPad by zlicer3d on MakerWorld — a clean, customizable 6-button macropad case.
The original design targets an Arduino ProMicro, but the RP2040-Zero fits perfectly with minor wiring adjustments. Print the case in PLA, no AMS needed.
Print settings: PLA, 0.2mm layer height, ~2.3 hours print time.
All buttons are wired active-low: one leg to a GPIO pin, the other leg to GND. The firmware enables internal pull-up resistors — no external resistors needed.
RP2040-Zero
+--------------+
| |
Button 1 ----| GPIO 2 |
Button 2 ----| GPIO 3 |
Button 3 ----| GPIO 4 |
Button 4 ----| GPIO 5 |
Button 5 ----| GPIO 6 |
Button 6 ----| GPIO 7 |
| |
All GNDs ----| GND |
| |
| USB-C ----|---- to computer
+--------------+
Each MX switch has 2 metal pins on the bottom. Wire one pin to GPIO, the other to GND:
MX Switch (bottom view)
+---------+
| +---+ |
| | | |
| +---+ |
| |
o o
| |
+----+----+
|
Pin A ---- GPIO (e.g. GPIO 2)
Pin B ---- GND (common ground)
-
Insert switches into the 3D-printed plate. Make sure the metal pins face inward (toward the center of the board).
-
Solder all GND pins together — solder a single wire connecting one pin from each switch. This creates a common ground bus. Use a single color (e.g., black) for all ground connections.
-
Solder individual signal wires — solder one wire to the remaining free pin of each switch. Use different colors if possible for easy identification:
- Button 1 -> GPIO 2
- Button 2 -> GPIO 3
- Button 3 -> GPIO 4
- Button 4 -> GPIO 5
- Button 5 -> GPIO 6
- Button 6 -> GPIO 7
-
Connect to RP2040-Zero — solder the signal wires to the corresponding GPIO pads, and the ground bus to any GND pad on the board.
-
Test with a multimeter — before plugging in, check for shorts between GPIO and GND. Each button should show continuity only when pressed.
-
Close the case — place the RP2040-Zero inside the case (components facing away from the switches for easier identification). Route the USB-C port to the case opening.
+---------------------------------------------------+
| TOP VIEW |
| |
| [SW1] [SW2] [SW3] |
| | | | |
| +- GPIO 2 +- GPIO 3 +- GPIO 4 |
| | | | |
| [SW4] [SW5] [SW6] |
| | | | |
| +- GPIO 5 +- GPIO 6 +- GPIO 7 |
| | | | |
| +------------+------------+ |
| | |
| GND |
| | |
| +-----+-----+ |
| | RP2040 | |
| | Zero | |
| | | |
| | USB-C ---+---- to computer |
| +-----------+ |
+---------------------------------------------------+
-
Edit pin configuration in
firmware/src/pin_config.h— set your GPIO pins and number of buttons:static const uint8_t BUTTON_PINS[] = { 2, 3, 4, 5, 6, 7 }; #define NUM_BUTTONS (sizeof(BUTTON_PINS) / sizeof(BUTTON_PINS[0]))
-
Build the firmware:
cd firmware mkdir build && cd build cmake -DPICO_SDK_PATH=/path/to/pico-sdk .. make -j$(nproc)
-
Flash — hold BOOTSEL on the RP2040-Zero, plug in USB, then drag
streamdeck.uf2onto theRPI-RP2drive that appears. -
Configure — open the StreamDeck Config desktop app and connect to your device.
The native Tauri app provides full device configuration:
cd app
npm install
npm run dev # development mode
npm run build # production buildNative apps for macOS (DMG), Windows (EXE), and Linux (AppImage) are available in Releases.
- Connect — select your serial port from a dropdown
- Configure buttons — 7 action types with full UI
- App Launcher — browse installed apps, launch natively via
open -a/xdg-open - Macro Recorder — record key combos by pressing them
- Save to Flash — persist mappings across power cycles
See companion/README.md for details.
Edit firmware/src/pin_config.h:
static const uint8_t BUTTON_PINS[] = { 2, 3, 4, 5, 6, 7, 10, 11 }; // any GPIO 0-29NUM_BUTTONS is automatically calculated — just add or remove pins from the array.
| Action | Description |
|---|---|
| Key | Send a keyboard key press (with modifiers) |
| Consumer | Send a media key (volume, play/pause, etc.) |
| Macro | Record and play back key combos (Ctrl+Shift+V as one press) |
| Text | Type out a string character by character |
| Paste | Copy text to clipboard and send paste shortcut |
| Launcher | Launch an app by name via the companion app |
- Pico SDK installed
- CMake 3.13+
- ARM GCC toolchain
cd firmware
mkdir build && cd build
cmake -DPICO_SDK_PATH=/path/to/pico-sdk ..
make -j$(nproc)Output: firmware/build/streamdeck.uf2
- Build: firmware + desktop apps build on every push/PR
- Release: tagged pushes (v*) create a GitHub release with UF2 + DMG + EXE + AppImage
- Pages: webconfig auto-deploys to GitHub Pages
MIT License. See LICENSE for details.
- Enclosure: OneClick MacroPad by zlicer3d
- Firmware: RP2040 USB HID using TinyUSB via Pico SDK
- Desktop app: Tauri