Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ESP32 Keyboard & Mouse Switch for Two PCs

CI

An open-source keyboard and mouse sharing switch for two nearby computers. PC 1 captures the USB input and sends it over serial to an ESP32; PC 2 sees the ESP32 as a normal Bluetooth Low Energy keyboard and mouse.

USB keyboard + mouse
          │
          ▼
   PC 1 (Linux/X11) ── USB serial ──► ESP32 ── BLE HID ──► PC 2

Press Scroll Lock once to move both devices to PC 2. Press it again to return them to PC 1. PC 2 needs no client software or network connection.

Tested configuration

Component Tested
Keyboard Logitech K270 receiver (046d:4003)
Mouse Logitech M331/B330/M330 receiver (046d:4057)
Bridge ESP32-WROOM-32D (classic ESP32)
PC 1 Linux, systemd-logind, X11
PC 2 Windows with Bluetooth Low Energy

Other USB keyboards and mice can be selected at runtime, but are not yet part of the tested matrix.

Requirements

  • Python 3, dbus-python, and xinput on PC 1
  • PlatformIO Core to build and flash the firmware
  • A classic ESP32 board with BLE support
  • A BLE-capable target computer

On Debian or Ubuntu, install the host dependencies with:

sudo apt install python3 python3-dbus xinput

Setup

Clone the repository and flash the ESP32:

git clone https://github.com/cinunii/esp32-keyboard-mouse-switch.git
cd esp32-keyboard-mouse-switch
platformio run --target upload

If several serial devices are connected, select the ESP32 explicitly:

platformio run --target upload --upload-port /dev/ttyUSB0

Pair PC 2 with ESP32 Input Bridge, then start the host bridge on PC 1:

python3 host/bridge.py

The bridge starts on PC 1. It restores local input when stopped with Ctrl+C or when the BLE connection is lost.

Use a different keyboard or mouse

List the IDs reported by the Linux input subsystem:

python3 host/bridge.py --list-devices

Pass the selected IDs to the bridge:

python3 host/bridge.py \
  --keyboard-id 046d:4003 \
  --mouse-id 046d:4057

Use the same ID for both options when a single receiver exposes both devices. The serial port is detected when only one is present; otherwise pass --serial /dev/ttyUSB0.

Design

The host obtains input file descriptors from the active session through systemd-logind, so it does not require root or a persistent udev rule. In remote mode it disables only the selected X11 devices locally, while continuing to read their events.

Keyboard, mouse, wheel, and media-key reports are framed with SLIP and CRC-8 before crossing the USB serial link. The ESP32 validates each frame and exposes a composite BLE HID device. The wire format is documented in docs/protocol.md.

Limitations

  • PC 1 currently requires Linux with X11; Wayland is not supported.
  • BLE HID is generally unavailable in BIOS/UEFI and before PC 2 loads Bluetooth.
  • The keyboard report supports six simultaneous non-modifier keys.
  • Compatibility beyond the tested hardware above is not guaranteed.
  • Initial BLE bonding uses the Just Works association model. Pair in a trusted physical location; see SECURITY.md.

Development

Run the host tests and build the firmware:

python3 -m unittest discover -s host -v
platformio run

CI performs both checks on every push and pull request. Reports should not contain captured input, Bluetooth addresses, serial numbers, or credentials.

License

MIT. Dependencies retain their own licenses; see THIRD_PARTY.md. Logitech product names are trademarks of their respective owner. This project is independent and is not endorsed by Logitech.

About

Open-source ESP32 BLE keyboard and mouse switch for two PCs—no network or client software on PC 2

Topics

Resources

Security policy

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages