Skip to content

Naivedya-sahu/SwitchPad

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

9 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

SwitchPad

Wireless BLE numpad with F13 monitor switching — ESP32-C3 based 11-key keyboard with DDC/CI integration for seamless dual-monitor workflows.

License: MIT Hardware Status

SwitchPad Hardware


Overview

SwitchPad started as a solution to a workflow problem: switching monitor input between desktop and laptop required reaching behind the display. The result is a custom wireless numpad where a single F13 keypress toggles HDMI inputs via DDC/CI commands.

What It Does

  • Standard wireless numpad (keys 0-9) via BLE HID
  • F13 macro key triggers automated monitor input switching
  • Eliminates manual monitor button pressing — one keypress switches between HDMI1 (desktop) and HDMI2 (laptop)

Project Evolution

Originally aimed at dual-host BLE switching between devices, but pivoted when ESP32-BLE-Keyboard v0.3.0+ introduced Windows reconnection bugs that made reliable power cycling impossible. Downgrading to v0.2.3 solved reconnection issues but revealed ESP32-C3 RAM constraints that made BLE stack restarts unreliable (BT_HCI: status=0x7 errors). The F13 monitor switching approach proved more elegant: the numpad stays connected to the desktop, but controls which system displays on the monitor.


Features

  • ESP32-C3 SuperMini - Low-cost ($2-3), power-efficient MCU with native BLE 5.0
  • 11 Cherry MX switches - 10 numpad keys + 1 F13 macro key
  • Hardware debouncing - 50ms blocking debounce eliminates ghost typing (solved 6× repeat issue)
  • BLE HID keyboard - Standard implementation using ESP32-BLE-Keyboard v0.2.3
  • LiPo powered - 3.7V battery (500-1000mAh) with TP4056 USB-C charging
  • 3D printed enclosure - Custom STL files included, no PCB required
  • Monitor switching service - Optional Go-based Windows service for F13→DDC/CI automation
  • Single-host stable - Polling-based approach prevents GPIO 0 boot loops

Hardware

Bill of Materials

Component Qty Approx. Cost Notes
ESP32-C3 SuperMini 1 $2-3 AliExpress, 4MB flash variant
Cherry MX Switches 11 $0.50 each Any color (Brown recommended for typing)
TP4056 Charging Module 1 $0.50 Type-C variant, 1A charge rate
SPDT Slide Switch 1 $0.30 CK OS102011MS2Q or equivalent
3.7V LiPo Battery 1 $3-5 500-1000mAh, protected cell
JST 2-pin Connector 1 $0.20 2.5mm pitch for battery
22-26 AWG Wire 2m $1 Point-to-point wiring

Total cost: ~$15-20 USD (excluding 3D printing)

Complete BOM with part numbers →

Photos


Complete Assembly

ESP32-C3 Wiring

Power System

Wiring

Schematic

GPIO Mapping:

GPIO 0-9  → Numpad keys 0-9
GPIO 10   → F13 macro key
All pins  → INPUT_PULLUP (switch to GND)

Critical Design Notes:

  • GPIO 0 is boot strapping pin — polling used instead of interrupts to prevent boot loops
  • No external pull-ups required (firmware uses internal INPUT_PULLUP resistors)
  • Direct GPIO-to-GND wiring = minimal component count, simple assembly
  • GPIO 20/21 avoided due to limited breakout on SuperMini variant

3D Printed Parts

Located in Hardware/3d/:

  • Enclosure.stl — Main housing (~4hr print @ 0.2mm layer height)
  • OneKey.stl — Single keycap (print 11×)
  • TwoKey.stl — Double-wide keycap (optional for 0/Enter)

Preview: Enclosure


Firmware

Prerequisites

⚠️ CRITICAL: Use v0.2.3 specifically. Version 0.3.0+ has Windows BLE reconnection bugs after power cycling (GitHub issue #115).

🔧 F13 Key Support: The ESP32-BLE-Keyboard library must support F13-F24 keys (Hence HID descriptor extended to LOGICAL_MAXIMUM(0x73)). Stock ESP32-BLE-Keyboard only supports up to F12. Details in FIRMWARE.md

Installation

  1. Install ESP32 board support in Arduino IDE:

    • File → Preferences → Additional Board Manager URLs
    • Add: https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json
    • Tools → Board → Board Manager → Search "ESP32" → Install v2.0.17
  2. Extract ESP32-BLE-Keyboard v0.2.3.zip to Arduino libraries folder:

    • Windows: Documents\Arduino\libraries\
    • macOS: ~/Documents/Arduino/libraries/
    • Linux: ~/Arduino/libraries/
  3. Open Firmware/Wireless NUMPAD.ino

  4. Select board: Tools → Board → ESP32 Arduino → ESP32C3 Dev Module

  5. Upload (hold BOOT button if upload fails)

Complete firmware documentation →

Configuration

// Customize device identity
BleKeyboard bleKeyboard("NavyPad", "Navy Industries", 100);

Battery level is hardcoded to 100% (cosmetic reporting only, no ADC monitoring implemented).


Monitor Switching Service

Optional Windows service that listens for F13 keypresses and executes DDC/CI commands to switch monitor input.

How It Works

F13 pressed → Windows service detects via keyboard hook 
           → Executes ControlMyMonitor.exe 
           → Sends VCP code 60 (Input Select)
           → Monitor switches HDMI1 ⇄ HDMI2

Setup

  1. Download ControlMyMonitor from NirSoft
  2. Extract ControlMyMonitor.exe to Service/ directory
  3. Build service:
    cd Service/bat
    build-service.bat
  4. Run monitor-switch-service.exe
  5. Press F13 on numpad to test

Complete service documentation →

Requirements

  • Monitor must support DDC/CI (enable in OSD settings) [Tested on Viewsonic VX2779-HD-PRO]
  • HDMI cable must support DDC/CI (not all do)
  • Windows 10/11 (service uses Windows API keyboard hooks)

Assembly

Detailed assembly guide →

Quick Steps

  1. 3D Print enclosure and 11 keycaps (~8 hours total print time)
  2. Solder switches to ESP32-C3 GPIO pins (one pin per switch)
  3. Wire all switches to common GND rail
  4. Connect battery through TP4056 module (OUT+ → ESP32 5V, OUT- → GND)
  5. Install power switch between battery and ESP32
  6. Flash firmware via Arduino IDE
  7. Mount in enclosure, install keycaps
  8. Pair via Bluetooth (device appears as "NavyPad")

No PCB required — point-to-point wiring works reliably for 11 keys.


Troubleshooting

Windows won't reconnect after power cycle

Cause: ESP32-BLE-Keyboard v0.3.0+ has Windows-specific BLE reconnection bugs
Fix: Use v0.2.3 (included in Asset folder). If already using v0.3.0+, uninstall and install v0.2.3.

Keys repeat 6 times per press

Cause: Mechanical switch contact bounce (~60ms duration)
Fix: Firmware implements blocking 50ms debounce (already solved in current firmware).

ESP32 won't boot / stuck in boot loop

Cause: GPIO 0 is boot strapping pin — interrupts cause boot failures
Fix: Firmware uses polling approach instead of interrupts (already implemented).

Monitor doesn't switch with F13

  • Verify DDC/CI is enabled in monitor OSD menu (usually under "System" or "Advanced")
  • Test cable supports DDC/CI: ControlMyMonitor.exe /SetValue PRIMARY 60 17
  • Check service is running: tasklist | findstr monitor-switch
  • View service logs: Service/monitor-switch.log

Upload fails in Arduino IDE

  • Hold BOOT button during upload
  • Check USB cable supports data (not just charging)
  • Try lower upload speed: Tools → Upload Speed → 115200

Key not detected

  • Check wiring: GPIO pin → Switch → GND
  • Verify INPUT_PULLUP in code (line 8-9)
  • Test with multimeter: GPIO should read 3.3V open, 0V when pressed

Development History

Complete development iterations preserved in /Dev/ directory (not included in this repo):

  • 23 firmware versions tracking feature evolution
  • 7 conversation logs documenting design decisions
  • Hardware iteration notes and testing results
  • Library compatibility testing (v0.2.3 vs v0.3.0 comparison)

Key Learnings

  1. ESP32 RAM fragmentation prevents reliable BLE stack restart without full reboot

    • bleKeyboard.end() + bleKeyboard.begin() causes BT_HCI: status=0x7 errors
    • Single-host approach more stable than dual-host switching
  2. GPIO 0 interrupt attachment causes device bricking during boot

    • Boot strapping pin requires polling, not interrupt-driven scanning
    • 50ms polling provides adequate 20Hz scan rate for numpad
  3. Library v0.3.0 Windows bug breaks reconnection after power cycling

  4. Mechanical switch bounce manifests as exactly 6× character repeat

    • 60ms bounce duration ÷ 10ms loop interval = 6 false triggers
    • Blocking 50ms debounce eliminates ghost typing

License

MIT License - See LICENSE for details.

Acknowledgments

Author

Navy - GitHub


Project Status: ✅ Complete and functional
Hardware: Validated and tested
Firmware: Stable (v5, single-host polling)
Monitor Switching: Operational with ControlMyMonitor + Go service

About

A wireless BLE numpad built on ESP32-C3 SuperMini with dedicated F13 key for seamless dual-monitor input switching via DDC/CI commands.

Topics

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors