--- title: "Hardware & Input System" description: "COPILOT keyboard hardware, joystick, serial/HID protocols, and key mapping" --- # Hardware & Input System ## Physical Hardware The COPILOT keyboard is a custom-built control panel with three input subsystems: ``` ┌──────────────────────────────────────────────────────────────────┐ │ COPILOT KEYBOARD │ │ │ │ ┌────────────────────────┐ ┌───────────────┐ ┌────────────┐ │ │ │ BUTTON PANEL │ │ JOYSTICK │ │ JOG/ │ │ │ │ │ │ │ │ SHUTTLE │ │ │ │ [Home] [F1-F7] │ │ ╱───╲ │ │ │ │ │ │ [0-9] [.] [*] │ │ │ ● │ │ │ ◄──●──► │ │ │ │ [+] [-] [(] [)] │ │ ╲───╱ │ │ │ │ │ │ [< >] │ │ 3-axis │ │ 7 speeds │ │ │ │ │ │ X/Y/Z │ │ per dir │ │ │ │ Serial (COM port) │ │ USB HID │ │ Serial │ │ │ └────────────────────────┘ └───────────────┘ └────────────┘ │ │ │ │ Arduino Leonardo (ATmega32U4) │ │ USB Composite: Serial + HID │ └───────────────────────────────┬──────────────────────────────────┘ │ USB LattePanda SBC ``` ## Communication Protocol ### Serial Port (Buttons + Jog/Shuttle) Messages are newline-terminated strings with a single-character prefix: | Prefix | Type | Example | Meaning | |--------|------|---------|---------| | `p` | Key Pressed | `pH\r\n` | Home key pressed | | `r` | Key Released | `rH\r\n` | Home key released | | `h` | Heartbeat | `h\r\n` | Keepalive (ignored) | | `j` | Jog | `j+1\r\n` / `j-1\r\n` | Jog wheel step right/left | | `s` | Shuttle | `s3\r\n` / `s-5\r\n` | Shuttle position (-7 to +7) | | `v` | Version | `v2.1\r\n` | Firmware version response | Startup: App sends byte `0xDC` to request firmware version. ### HID Device (Joystick) | Property | Value | |----------|-------| | Vendor ID | `10959` (0x2ACF) | | Product ID | `257` (0x0101) | | Axes | X (pan), Y (tilt), Z (zoom) | | Raw range | Scaled to **-255 to +255** | | Buttons | Button1, Button2, Button3 | ```mermaid graph TD subgraph "HID Input Processing" Raw["Raw HID Report"] --> Parser["DeviceItemInputParser"] Parser --> Changed{"HasChanged?"} Changed -->|Yes| Usage{"Usage Type"} Usage -->|GenericDesktopX| PanEvt["JoystickX event
(-255 to +255)"] Usage -->|GenericDesktopY| TiltEvt["JoystickY event
(-255 to +255)"] Usage -->|GenericDesktopZ| ZoomEvt["JoystickZ event
(-255 to +255)"] Usage -->|Button1| B1["JoystickButton1
Pressed/Released"] Usage -->|Button2| B2["JoystickButton2
Pressed/Released"] Usage -->|Button3| Ignore["Ignored"] end ``` ## Key Mapping ### Hardware Keys → Virtual Keys The serial protocol uses ASCII character codes: | Serial Code | Char | Virtual Key | UI Function | |-------------|------|-------------|-------------| | 72 | `H` | Home | Home position / Jump to live | | 65 | `A` | F1 | Function button 1 | | 66 | `B` | F2 | Function button 2 | | 67 | `C` | F3 | Function button 3 | | 68 | `D` | F4 | Function button 4 | | 69 | `E` | F5 | Function button 5 | | 70 | `F` | F6 | Function button 6 | | 71 | `G` | F7 | Function button 7 | | 46 | `.` | Prefix | Camera number prefix cycle | | 42 | `*` | FullScreen | Toggle monitor maximize | | 41 | `)` | Sequence | Open sequence menu | | 40 | `(` | Backspace | Delete last digit | | 48 | `0` | D0 | Digit 0 | | 55-51 | `7-3` | D1-D5 | Digits 1-5 (note: remapped!) | | 49-51 | `1-3` | D7-D9 | Digits 7-9 (note: remapped!) | | 52-54 | `4-6` | D4-D6 | Digits 4-6 | | 60 | `<` | Minus | Previous camera / Focus far | | 62 | `>` | Plus | Next camera / Focus near | | 43 | `+` | Lock | Toggle camera PTZ lock | | 45 | `-` | Enter | Confirm camera number | **Important:** The digit key wiring is non-standard — D1 maps to ASCII 55 (`7`), not 49 (`1`). This is a hardware layout choice. ### Joystick Buttons | Button | Virtual Key | Function | |--------|-------------|----------| | Button1 | JoystickButton1 | (Context-dependent) | | Button2 | JoystickButton2 | Toggle camera PTZ lock | ### Development Keyboard Emulation When no serial port is detected, the app falls back to standard keyboard input via `VirtualKeyboard.Emulate()`: | PC Key | Virtual Key | |--------|-------------| | Home | Home | | F1-F7 | F1-F7 | | F10 | Prefix | | F11 | FullScreen | | F12 | Sequence | | 0-9 / Numpad | D0-D9 | | Backspace | Backspace | | Enter | Enter | | +/- | Plus/Minus | | Left/Right arrow | JogLeft/JogRight | | Shift+Left/Right | Shuttle (incremental) | | Shift+Up | Shuttle center (reset) | ## Shuttle Speed Mapping The shuttle wheel has 7 positions per direction. Speeds are configurable per deployment: ``` Position: -7 -6 -5 -4 -3 -2 -1 0 +1 +2 +3 +4 +5 +6 +7 ◄── backward ──────────── center ──────────── forward ──► Config: [250,100, 30, 15, 5, 2, 1] ● [ 1, 2, 5, 15, 30,100,250] ``` Default playback speeds (from config): `[1, 2, 5, 15, 30, 100, 250]` ## Service Key (Hidden Menu) Holding the **Backspace** key for 3 seconds opens the Service Menu page. This provides access to firmware update and diagnostic functions.