H₂H³ is a compact, STM32 microcontroller-driven USB 2.0 KVM switch and 3-port hub designed to maintain a clean, clutter-free workspace in modern home offices. It enables two computers to seamlessly share a single set of peripherals—like your keyboard, mouse, and flash drives—while delivering live voltage and current telemetry via an integrated OLED display. Paired with the native Rust host daemon, H₂H³ features seamless automatic host switching as your mouse reaches the screen edge, alongside intuitive configuration directly from your system tray.
Note
Project Status & Contribution: This project is actively developed. The core KVM switching, screen-edge mouse transition, telemetry functionality, and host daemon communication are fully functional.
To bring this project to a 100% polished release, contributions from the open-source community are highly welcome! Whether you want to optimize edge-case handling in the C++ firmware, expand the Rust host daemon features, or help refine the documentation—feel free to open an issue or submit a Pull Request. Let's build this together!
- Smart Break-Before-Make Switching: Advanced, software-controlled VBUS and data line multiplexing ensures safe, glitch-free transitions and isolated power rails between both host PCs.
- Integrated 3-Port Hub: Built-in Genesys Logic controller expands a single shared USB connection into three downstream ports for your everyday desk peripherals.
- Modern C++ Firmware: Driven by a powerful STM32G0 architecture running a modular, object-oriented C++ firmware stack with hardware-level overcurrent protection.
- 🚀 Edge-Triggered Mouse Switching & Native Host Daemon: The onboard STM32 MCU communicates natively with our lightweight Rust host daemon via Custom HID. Move your mouse pointer past the edge of your screen to automatically trigger a host switch—just like a multi-monitor setup across two distinct PCs.
- 🖥️ User-Friendly System Tray Controls: Effortlessly tweak hotkeys, adjust screen-edge transition sensitivity, or trigger manual host switches directly from an intuitive Windows system tray menu.
- Live Telemetry Dashboard: A crisp, integrated 64x32 pixel OLED display provides real-time insights by showing live bus voltage and precise current draw per port.
- Ergonomic & Screw-less Enclosure: Features a clean interface with a discreetly placed rear tactile button to prevent cable snags, all housed in a robust, snap-fit PA12-HP Nylon shell optimized for MJF 3D printing.
🖼️ Jump straight to the Photo Gallery.
🏪 Hardware Available: Skip the assembly line and grab a fully functional H₂H³ on Tindie.
H₂H³ represents a personal exploration into modern decentralized manufacturing and open-source engineering. It blends professional design principles with modern open-source software, AI-collaborative programming to refine the C++ firmware, and on-demand fabrication. The fact that an individual engineer can now prototype industrial-grade hardware using low-volume far-east manufacturing is nothing short of incredible.
To give back to the community, the full design files—spanning schematics, mechanics, and source code—are public domain under MIT and CERN Open Hardware licenses. It is intended strictly for educational use, and community-driven remixes are highly encouraged.
The hardware, enclosure, and software for H₂H³ were designed using the following tools:
- KiCad 9.0: Schematic entry and PCB design for the 4-layer board.
- FreeCAD 1.0: 3D modeling of the screw-less, snap-fit two-part enclosure.
- Firmware Toolchain: Developed in modern modular C++ utilizing STM32CubeMX for hardware abstraction. Out of the box, the repository supports a dual-development workflow—you can build and debug the firmware seamlessly using either Visual Studio Code (via CMake/Ninja) or STM32CubeIDE, depending on your preferred environment.
- Host Software: A lightweight background daemon written in Rust using Custom HID protocol for cross-platform control (Windows - Linux and MacOS prepared). The screenshot shows the Windows systray configuration app:
- Microcontroller: ARM Cortex-M0+ 32-bit MCU (STM32G0B1KBU6, 64 MHz, 128 KB Flash, 144 KB RAM), integrated as a 4th peripheral on the hub.
- USB 2.0 Hub Controller: Genesys Logic GL852G.
- Physical Interface:
- 2x USB-A Male (Host 1 / Host 2 upstream connections)
- 3x USB-A Female (Peripheral downstream ports)
- Telemetry Sensors: Continuous dual-host VBUS voltage sensing (enables auto-detection) and triple-peripheral current monitoring.
- Switching Architecture: Hybrid automatic/software-controlled VBUS muxer combined with hardware USB data line multiplexers.
- User Interface: 64x32 pixel OLED screen, 1x rear tactile switch button, and 1x fully programmable RGB LED (color and brightness).
- Form Factor: Ultra-compact desktop footprint (approx. 60 × 20 × 20 mm).
![]() |
![]() |
![]() |
Located in daemon/, this Rust application runs in the background on connected host PCs:
- Custom HID Communication: Interfaces directly with the STM32 firmware over custom USB HID reports.
- Screen-Edge Boundary Detection: Tracks cursor movement to trigger host transitions instantly as the mouse reaches configured display boundaries.
- System Tray Control: Features a user-friendly system tray menu for configuring edge triggers, manual host selection, and daemon startup options.
- Cross-Platform: Supports Windows and Linux (MAC OS prepared).
Located in firmware/, built using STM32CubeMX for hardware abstraction and written in C/C++:
- Fully Modular C++: Application logic is decoupled into distinct C++ modules (
App/). - Custom HID Transport: Uses a robust Custom HID interface to communicate bidirectionally with the host daemon.
- Switch Request Admission: Incorporates switch request evaluation logic (
evaluateSwitchRequest) to ensure safe transition rules and prevent bus contention during edge triggers or manual button presses. - Optimized ADC Sampling: Continuous monitoring of port power states with software-side calibration.
- Overcurrent Protection: Peripheral current draw of more than 1.5 A triggers a fault state requiring user confirmation.
- UART Debug Console: Retargeted
printfover the STM32 USART2 or USB virtual COM port. - Binary Programming: Powering on and holding switch button simultaneously enters the programming mode (STM32CubeProgrammer) which enables programming the ST32 integrated flash without the need for a hardware debugger
twinusb/
├── assets/ # Public media & documentation images
├── firmware/ # Production-ready STM32G0 C/C++ firmware
│ ├── App/ # Core Application Logic (C++)
│ │ ├── Inc/ # Application Managers (Hub, Display, Sensors, UI)
│ │ └── Src/ # Implementation source code
│ ├── Core/ # Hardware peripheral initialization (ADC, I2C, GPIO)
│ ├── cmake/ # Toolchain configuration profiles
│ ├── Libs/ # Embedded drivers & hardware abstraction libraries
│ │ └── oled_waveshare/ # Low-level 0.49" 64x32 OLED display driver components
│ ├── Middlewares/ # STMicroelectronics USB Device Library stack
│ ├── Startup/ # Microcontroller boot vector assembly code
│ └── USB_Device/ # USB CDC Class configuration and descriptor maps
├── daemon/ # Rust host daemon (twinusb-daemon crate)
│ ├── src/ # Rust source code (HID communication, tray app)
│ └── Cargo.toml # Rust dependencies & package config
├── hardware/ # Electronics engineering files (KiCad)
│ ├── src/ # Rust source code (HID communication, tray app)
│ ├── lib_fp/ # Custom PCB footprint libraries (.pretty)
│ └── lib_sch/ # Custom schematic component symbols
└── enclosure/ # Mechanical 3D CAD design (FreeCAD)
git clone https://github.com/s-t-e-f-a-n/twinusb.git
cd twinusb
- Rust Toolchain: Install rustup (Cargo).
- Linux Dependencies:
libudev-dev(if compiling natively on Linux).
cd daemon
# Build for development
cargo build
# Run locally
cargo run
# Build optimized release binary
cargo build --release
For Windows cross-compilation from Linux:
cargo build --target x86_64-pc-windows-gnu --release
This project supports a dual-development workflow. You can build the firmware using either VS Code (via CMake) or the official STM32CubeIDE. Choose the workflow that best fits your environment. You do not need to use STM32CubeMX to build the project from scratch.
This method uses CMake and Ninja/Make. It requires a local ARM GCC toolchain installed on your system.
Ensure you have the following installed and available in your system's PATH:
- ARM GNU Toolchain:
arm-none-eabi-gcc - Build Tools:
CMakeandNinja(orMake) - VS Code Extensions:
- CMake Tools
- C/C++ Extension Pack
- Open Project: Open the
firmwaredirectory in VS Code. - Select Compiler Kit: Open the Command Palette (
Ctrl+Shift+P/Cmd+Shift+P), search forCMake: Select a Kit, and select your installedarm-none-eabicompiler. - Select Build Variant: Choose either
DebugorReleasefrom the CMake status bar at the bottom. - Configure Project: Run
CMake: Configurefrom the Command Palette. This will clean-room generate your localbuild/directory with the correct absolute paths for your machine. - Compile: Click
Buildin the status bar or pressF7.
STM32CubeIDE is an all-in-one Eclipse-based IDE that includes its own compiler toolchain and internal build system out of the box.
- Import Project:
- Open STM32CubeIDE.
- Go to
File➔Open Projects from Filesystem... - Select
Directory➔Choose twinusb folderand click Select Folder. - Click Finish.
-
Index Project: Wait a few moments for the IDE to finish indexing the source files.
-
Compile: Click the Hammer icon (Build) in the top toolbar, or press
Ctrl+B(Cmd+Bon macOS).
The core application logic of this project is written in modern C++ and lives inside the App/ directory (App/Src and App/Inc), keeping it cleanly decoupled from the autogenerated ST HAL layer.
If you decide to open the twinusb.stm32.ioc file to modify pinouts or peripherals via STM32CubeMX and click "Generate Code", the tools will reset the project workspace to ST's default pure-C template.
If your IDE loses track of the C++ files after code generation, fix it manually:
-
In STM32CubeIDE: Right-click the project ➔
Properties➔C/C++ General➔Paths and Symbols. -
Under Includes, re-add the
App/Incdirectory. -
Under Source Location, re-add the
App/Srcdirectory. -
In VS Code: Simply run
CMake: Delete Cache and Reconfigurefrom the Command Palette to force CMake to re-scan the file structure.
The schematics and PCB layout are located in the /hardware folder, designed in KiCad and optimized for automated assembly (PCBA) via services like JLCPCB.
Print the shell components located in the /enclosure folder. Nylon (SLS/MJF technique) is highly recommended for that professional, textured matte finish and mechanical durability.
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
This project is licensed under different Open Source licenses depending on the component:
- 💻 Software & Firmware (Daemon & MCU): Licensed under the MIT License (Permissive, commercial-friendly software license)
- 🔌 Hardware (PCB & Schematics): Licensed under the CERN-OHL-W v2 (CERN Open Hardware Licence - Weak Copyleft)
- 📦 Enclosure (Mechanical CAD): Licensed under the CERN-OHL-W v2 (CERN Open Hardware Licence - Weak Copyleft)
All components are copyrighted © 2026 by s-t-e-f-a-n who developed them with ❤️

























