ProductionDeck is an open-source firmware library for creating StreamDeck-compatible devices using the Raspberry Pi Pico (RP2040). It provides full compatibility with official StreamDeck software by implementing exact USB HID protocols for multiple StreamDeck models.
- Multi-Device Support - Supports 6 different StreamDeck models with dedicated firmware binaries
- USB HID Protocol - Exact implementation of Elgato's communication protocols (V1 BMP and V2 JPEG)
- Device-Specific Binaries - Compile-time optimized firmware for each model
- Plug-and-Play - Recognized as authentic StreamDeck devices by Windows/macOS
- Open Source - Complete firmware source code with modular architecture
- RP2040 Based - Uses the powerful dual-core Raspberry Pi Pico microcontroller
Build device-specific firmware using: cargo run --bin <device-name>
| Product | Keys | Display | USB Protocol | Binary Target | Status |
|---|---|---|---|---|---|
| StreamDeck Mini | 6 (3x2) | 80x80px | V1 BMP | mini |
β Alpha |
| StreamDeck Revised Mini | 6 (3x2) | 80x80px | V1 BMP | revised-mini |
β Alpha |
| StreamDeck Original | 15 (5x3) | 72x72px | V1 BMP | original |
β Alpha |
| StreamDeck Original V2 | 15 (5x3) | 72x72px | V2 JPEG | original-v2 |
β Alpha |
| StreamDeck XL | 32 (8x4) | 96x96px | V2 JPEG | xl |
β Alpha |
| StreamDeck Plus | 8 (4x2) | 120x120px | V2 JPEG | plus |
β Alpha |
| StreamDeck Pedal | β | β | β | Not implemented | |
| StreamDeck Studio | β | β | β | Not implemented | |
| StreamDeck Mobile | N/A | N/A | N/A | Not Planned | |
| StreamDeck Module 6Keys | 6 (3x2) | 80x80px | BMP | module6 |
β Alpha |
| StreamDeck Module 15Keys | 15 (5x3) | 72x72px | JPEG | module15 |
β Alpha |
| StreamDeck Module 32Keys | 32 (8x4) | 96x96px | JPEG | module32 |
β Alpha |
- β Fully implemented and working
β οΈ Implemented but disabled (due to memory issues)- β Not implemented
- USB Protocol: β Complete HID implementation, device enumeration working
- Button Input: β 6-button matrix scanning with debouncing
- Display Output:
β οΈ ST7735 driver implemented but disabled due to buffer memory issues - Software Compatibility: β Recognized as authentic StreamDeck Mini by official software
Note: Only StreamDeck Mini is currently targeted. Other StreamDeck variants require different USB protocols, button layouts, and display configurations.
- Raspberry Pi Pico (RP2040 microcontroller)
- 1x ST7735 TFT Display (80x80 pixels, SPI interface) - shared by all buttons
- 6x Tactile Switches
- Basic passive components (resistors, capacitors)
- Status LEDs (USB, Error, Status indication)
- Enclosure (3D printed or custom case)
RP2040 Pin Layout (Raspberry Pi Pico):
USB Connection:
βββ VID: 0x0fd9 (Elgato Systems)
βββ PID: 0x0063 (StreamDeck Mini)
βββ Protocol: USB HID
GPIO Assignments:
βββ Buttons (Matrix Scan):
β βββ ROW0: GP2 β
β βββ ROW1: GP3 ββ Button Matrix
β βββ COL0: GP4 β (3x2 layout)
β βββ COL1: GP5 β
β βββ COL2: GP6 β
β
βββ SPI Displays (SPI0):
β βββ MOSI: GP19 (Data to displays)
β βββ SCK: GP18 (Clock)
β βββ DC: GP14 (Data/Command)
β βββ RST: GP15 (Reset, shared)
β
βββ Display CS (Chip Select):
β βββ DISPLAY: GP8 (Single shared display)
β
βββ Control:
β βββ Brightness: GP17 (PWM backlight control)
β βββ Status LED: GP25 (Built-in LED)
β βββ USB LED: GP20 (Connection status)
β βββ Error LED: GP21 (Error indication)
β
βββ Debug:
βββ UART TX: GP0 (Debug output)
βββ UART RX: GP1 (Debug input)
Physical Button Layout: GPIO Matrix:
βββββββ¬ββββββ¬ββββββ ROW0(GP2): BTN0 BTN1 BTN2
β 0 β 1 β 2 β β β β
βββββββΌββββββΌββββββ€ ROW1(GP3): BTN3 BTN4 BTN5
β 3 β 4 β 5 β β β β
βββββββ΄ββββββ΄ββββββ β β β
COL0 COL1 COL2
(GP4) (GP5) (GP6)
- Rust Toolchain - Latest stable Rust (1.75+) with embedded target support
- elf2uf2-rs - Tool for converting ELF to UF2 format
- flip-link - Stack overflow protection for embedded Rust
- Git - For cloning repositories
# Install Rust (if not already installed)
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source ~/.cargo/env
# Add embedded target for RP2040
rustup target add thumbv6m-none-eabi
# Install required tools
cargo install elf2uf2-rs
cargo install flip-linkAll Platforms:
# Install additional helpful tools
cargo install cargo-audit # Security audit
cargo install cargo-expand # Macro expansion for debugging
cargo install cargo-bloat # Binary size analysis# Clone the repository
git clone https://github.com/FlowingSPDG/productiondeck.git
cd productiondeck
# Check that dependencies compile
cargo check
# Build device-specific firmware
cargo build --release --bin mini # For StreamDeck Mini
cargo build --release --bin xl # For StreamDeck XL
cargo build --release --bin original # For StreamDeck Original
# ... or any other device from the support matrix
# Build all devices at once (optional)
./build-devices.sh
# The UF2 files will be at: target/thumbv6m-none-eabi/release/<device-name>.uf2After successful build, you'll find these files in target/thumbv6m-none-eabi/release/:
mini- ELF executable for Mini (with debug symbols)mini.uf2- Mini firmware file for flashingxl- ELF executable for XL (with debug symbols)xl.uf2- XL firmware file for flashing- ... (and similarly for other devices)
Each device gets its own optimized binary with compile-time device selection.
The UF2 files are automatically generated thanks to the runner configuration in .cargo/config.toml.
-
Enter Bootloader Mode:
- Hold the BOOTSEL button on the Pico
- Connect USB cable to computer
- Release BOOTSEL button
- Pico appears as
RPI-RP2drive
-
Flash Firmware:
# Copy UF2 file to the Pico cp target/thumbv6m-none-eabi/release/productiondeck.uf2 /Volumes/RPI-RP2/ # macOS cp target/thumbv6m-none-eabi/release/productiondeck.uf2 /media/RPI-RP2/ # Linux # On Windows: drag productiondeck.uf2 to RPI-RP2 drive
-
Automatic Reboot:
- Pico automatically reboots with new firmware
- Should appear as "Stream Deck Mini" in Device Manager
# Using cargo run with configured runner (requires debug probe setup)
cargo run --release
# Alternative: Use probe-rs for advanced debugging (install first: cargo install probe-rs-tools)
probe-rs run --chip RP2040 target/thumbv6m-none-eabi/release/productiondeck- Flash the firmware to your Pico
- Install Stream Deck Software
- Connect ProductionDeck via USB
- Should be recognized as "Stream Deck Mini"
- Configure keys in Stream Deck software
Same as Windows - the device uses standard USB HID drivers.
Since this is currently a firmware-only project, you'll need to wire the components manually:
Single ST7735 display connects via SPI (shared by all 6 buttons):
ST7735 Display β RP2040
VCC β 3.3V
GND β GND
SCL β GP18 (SCK)
SDA β GP19 (MOSI)
RES β GP15 (RST)
DC β GP14 (Data/Command)
CS β GP8 (Chip Select)
BLK β GP17 (PWM backlight control)
Simple tactile switch matrix:
Button connections:
BTN0: ROW0(GP2) β COL0(GP4)
BTN1: ROW0(GP2) β COL1(GP5)
BTN2: ROW0(GP2) β COL2(GP6)
BTN3: ROW1(GP3) β COL0(GP4)
BTN4: ROW1(GP3) β COL1(GP5)
BTN5: ROW1(GP3) β COL2(GP6)
Connect UART to see debug messages:
# Linux/macOS
screen /dev/ttyUSB0 115200
# Windows
# Use PuTTY or similar terminal program
# Port: COM port of Pico
# Baud: 115200Debug output is controlled via the DEFMT_LOG environment variable in .cargo/config.toml:
- Set to
debugfor detailed logging - Set to
infofor basic information - Set to
warnfor warnings only - Set to
offto disable logging
You can also set the log level temporarily:
DEFMT_LOG=debug cargo build --release- Check USB VID/PID in device manager
- Ensure firmware flashed correctly
- Try different USB cable/port
- Check SPI connections
- Verify power supply (3.3V)
- Test individual displays
- Check button matrix wiring
- Verify pull-up resistors
- Check debounce timing
# Format code according to Rust standards
cargo fmt
# Check code quality with Clippy
cargo clippy
# Clean build artifacts
cargo clean
# Check compilation without building
cargo check
# Build and flash (with debug probe configured)
cargo run --releaseProductionDeck implements the exact StreamDeck Mini USB HID protocol:
- VID:
0x0fd9(Elgato Systems) - PID:
0x0063(StreamDeck Mini) - Class: HID (Human Interface Device)
- Input Reports: Button states (6 bytes)
- Output Reports: Image data (1024 bytes per packet)
- Feature Reports: Commands (version, reset, brightness)
V2 Image Packet (1024 bytes):
[0x02][0x07][key_id][is_last][len_low][len_high][seq_low][seq_high][image_data...]
β β β β β β β β ββ Image payload
β β β β β β β ββ Sequence high byte
β β β β β β ββ Sequence low byte
β β β β β ββ Payload length high byte
β β β β ββ Payload length low byte
β β β ββ Last packet flag (1=final, 0=more)
β β ββ Key ID (0-5)
β ββ Image command (0x07)
ββ Report ID (0x02)
- Language: Rust 2021 Edition
- Framework: Embassy async framework for embedded
- USB Stack: Embassy USB with HID support
- Graphics: embedded-graphics with ST7735 driver
- Target: thumbv6m-none-eabi (Cortex-M0+)
We welcome contributions! Please see:
- Issues for bug reports
- Discussions for questions
- Fork the repository
- Create feature branch:
git checkout -b feature-name - Make changes and test thoroughly
- Submit pull request
This project is licensed under the MIT License - see the LICENSE file for details.
This project is not affiliated with Elgato Systems. StreamDeck is a trademark of Elgato Systems. This project implements a compatible device through reverse engineering for educational and interoperability purposes.
- rust-streamdeck - Protocol reference
- Raspberry Pi Foundation - RP2040 microcontroller
- TinyUSB - USB stack
- StreamDeck reverse engineering community
- Firmware Issues: Submit Issue
- Questions: GitHub Discussions
Made with β€οΈ for the maker community
Build your own StreamDeck and join the open hardware revolution!