KVMote/conhecimento.md
Ricardo Carneiro 91e43e73d5 fix: ajustes
2026-03-22 18:59:18 -03:00

9.7 KiB

KVMote — Conhecimento do Projeto

Documento de referência técnica e histórico de decisões do projeto KVMote.


O que é

KVMote é um KVM (Keyboard, Video, Mouse) over Bluetooth que permite controlar um PC remoto usando o teclado e mouse do seu PC principal, sem instalar nenhum software no PC controlado.

Inspirado em: Barrier / InputLeap / Mouse Without Borders — mas funciona em ambientes corporativos restritivos porque o PC cliente enxerga apenas um teclado e mouse USB comuns (Arduino).


Como funciona

┌─────────────────────┐         Bluetooth SPP          ┌──────────────────┐
│   PC Host           │ ◄────── (COM virtual) ────────► │  HC-06           │
│   KVMote.exe        │                                  │  (Bluetooth)     │
│   - captura mouse   │                                  └──────┬───────────┘
│   - captura teclado │                                         │ Serial 9600
│   - detecta borda   │                                  ┌──────▼───────────┐
└─────────────────────┘                                  │  Arduino Leonardo │
                                                         │  (USB HID)        │
                                                         └──────┬────────────┘
                                                                │ USB
                                                         ┌──────▼───────────┐
                                                         │   PC Cliente      │
                                                         │   (sem software)  │
                                                         └───────────────────┘
  1. O KVMote.exe roda no PC host (onde estão teclado e mouse físicos)
  2. O mouse chega na borda da tela configurada → cursor some → modo cliente ativo
  3. Movimentos de mouse e teclas são capturados por hooks globais do Windows
  4. Enviados via Bluetooth Serial ao HC-06 → Arduino Leonardo
  5. O Arduino injeta os eventos como USB HID no PC cliente
  6. Para voltar: mova o mouse ~15px de volta na direção do host

Hardware necessário

Componente Modelo Observação
Microcontrolador Arduino Leonardo Obrigatório — único com HID USB nativo (ATmega32U4)
Bluetooth HC-06 Módulo slave, 9600 baud padrão
LED indicador LED RGB catodo comum Pinos R=5, G=6, B=9 (PWM)
Resistores ~100Ω por canal Proteção do LED

Arduino Uno não funciona — não tem suporte HID nativo.


Instalação e configuração

PC Cliente (onde o Arduino fica conectado)

  1. Conectar o Arduino Leonardo via USB (aparece como teclado + mouse)
  2. Verificar que o HC-06 está pareado com o PC Host via Bluetooth Windows
  3. Nenhum software adicional necessário

PC Host (onde o KVMote.exe roda)

  1. Parear o HC-06 no Bluetooth do Windows → anota a porta COM gerada
  2. Rodar KVMote.exe (portable, sem instalação)
  3. Selecionar a posição do PC cliente (Esquerda / Direita / Acima / Abaixo)
  4. Clicar Detectar → aguarda auto-detecção da porta COM
  5. Selecionar o layout do teclado do PC cliente (US ou PT-BR ABNT2)
  6. Clicar Conectar

Indicadores LED do Arduino

Cor Significado
🟢 Verde Arduino ligado, aguardando conexão do host
🔵 Azul Host conectado, mouse no PC host
🟣 Magenta Mouse no PC cliente (modo ativo)

Protocolo serial binário

Comunicação Host → Arduino a 9600 baud:

Comando Bytes Ação
M + dx + dy 3 Mover mouse (valores int8 com sinal)
W + delta 2 Roda do mouse / scroll touchpad
K + char 2 Digitar caractere (Keyboard.write)
P + keycode 2 Pressionar tecla (mantém pressionada)
U + keycode 2 Soltar tecla
A 1 Soltar todas as teclas
C + L/R 2 Clique do mouse
D + L/R 2 Pressionar botão do mouse (arrastar)
E + L/R 2 Soltar botão do mouse
O 1 LED magenta (entrou no cliente)
H 1 LED azul (host conectado)
G 1 LED verde (host desconectado)
~ 1 Ping → Arduino responde [PONG]

Funcionalidades implementadas

KVM básico

  • Controle de mouse (move, clique, arraste, scroll)
  • Controle de teclado (todas as teclas, modificadores, F-keys, numpad)
  • Detecção de borda (Left, Right, Above, Below)
  • Retorno ao host por coordenadas virtuais (threshold 15px)
  • Cursor escondido durante modo cliente

Conexão

  • Auto-detecção de porta COM por PONG handshake
  • Heartbeat a cada 3s (PONG timeout = 9s)
  • Reconexão automática em loop
  • Saída do modo cliente ao perder conexão (cursor sempre volta)

Scroll

  • Mouse wheel físico
  • Touchpad dois dedos (acumulador de delta para smooth scroll)

Clipboard

  • Ctrl+V (ou Shift+Ins) em modo cliente envia texto do host como digitação
  • Limite de 300 caracteres
  • Suporte a layout PT-BR ABNT2 (remapeamento de pontuação)
  • ReleaseAll antes de digitar (evita Ctrl+letra indesejado)

Layout de teclado (clipboard)

Layout Chars problemáticos corrigidos
US / Internacional — (padrão)
PT-BR ABNT2 ; : [ ] { } mapeados corretamente

Chars não mapeáveis em PT-BR (ignorados no paste): / ? \ | @


Arquitetura do código C#

Principal.cs — seções

  1. P/Invoke — SetWindowsHookEx, ClipCursor, SetCursorPos
  2. Auto-detect — ProbePorts, PONG handshake
  3. Position selector — botões Acima/Esquerda/Direita/Abaixo
  4. Connect/Disconnect — abertura de porta, timers, hooks
  5. Port management — OpenPort, ClosePort, OnDataReceived
  6. Watchdog + Heartbeat + Reconnect — saúde da conexão
  7. Global Hooks — instala/remove WH_MOUSE_LL e WH_KEYBOARD_LL
  8. Mouse Hook Callback — edge detection, warp, virtual coords, scroll
  9. Keyboard Hook Callback — Ctrl+V intercept, P/U por VK code
  10. VK → Arduino keycode mapping — tabela + ranges (a-z, 0-9, numpad)
  11. Send methods — Send (blocking+lock), SendMouse (lossy TryEnter)
  12. Utilities — SetStatus, SetPortInfo, Log
  13. Clipboard send + layout — TranslateChar, SendClipboardToClient

Técnica de mouse (FPS warp)

  • ClipCursor não é usado — causava problemas
  • Em vez disso: cursor fica em posição fixa no centro (_lastRawPos)
  • A cada WM_MOUSEMOVE: calcula delta, acumula em _pendingDX/_pendingDY, faz warp de volta
  • Throttle de 50ms antes de enviar ao Arduino

Decisões de projeto

Decisão Alternativa considerada Motivo
Arduino Leonardo Arduino Uno Uno não tem HID nativo
9600 baud 115200 baud HC-06 padrão de fábrica, simples
WH_MOUSE_LL hook Raw Input API Mais simples, suficiente
Monitor.TryEnter para mouse Queue assíncrona Lossy é OK para mouse, não bloqueia
Coordenadas virtuais para retorno Timer de inatividade Mais natural, sem delay artificial
AutoScaleMode.Dpi AutoScaleMode.None None quebrava em telas de alta resolução
TCP não usado TCP local seria mais rápido Corporativo bloqueia portas

Limitações conhecidas

  • Velocidade: 9600 baud limita a ~50 teclas/s no clipboard; mouse trava durante paste
  • Chars acentuados: é, ã, ç etc. não enviáveis via clipboard (não-ASCII)
  • Monitor único: sem suporte a multi-monitor no host
  • Um cliente: arquitetura 1:1
  • PT-BR parcial: /, ?, \, |, @ não mapeáveis via Keyboard.write()
  • Tela do cliente: não capturada (KV sem o V — só K e M)

Roadmap

Clipboard Bridge (próximo projeto)

App separado para compartilhar clipboard entre host e cliente. Transporte via:

  1. OneDrive pasta compartilhada — funciona em corporativo (Microsoft 365 whitelisted)
  2. TCP/IP local — rápido, para redes domésticas
  3. Bluetooth RFCOMM — PC a PC direto, sem rede

Suporte planejado: texto (qualquer tamanho), imagens PNG (comprimidas), não arquivos.

Melhorias futuras

  • Baud rate configurável (AT commands HC-06)
  • Multi-monitor
  • Layout US-International completo com dead keys
  • Indicador visual de latência BT

Como gerar o executável portable

# Na pasta do projeto:

# Self-contained (~70MB) — roda sem .NET instalado
dotnet publish -c Release -r win-x64 --self-contained true -p:PublishSingleFile=true -p:IncludeNativeLibrariesForSelfExtract=true

# Dependente do runtime (~2MB) — requer .NET 8 Desktop Runtime
dotnet publish -c Release -r win-x64 --self-contained false -p:PublishSingleFile=true

Saída: bin\Release\net8.0-windows\win-x64\publish\KVMote.exe

⚠️ Não usar o botão "Publicar" do Visual Studio — gera ClickOnce (múltiplos arquivos).


Troubleshooting

Sintoma Causa provável Solução
Porta não detectada HC-06 não pareado Parear BT no Windows antes
Cursor some e não volta Conexão caiu em modo cliente Mover mouse — reconexão automática restaura cursor
Teclas erradas no cliente Layout diferente Ajustar "Layout do cliente" no app
Scroll não funciona Apenas no touchpad? Acumulador captura, mas pode ser lento
Mouse lento no cliente Throttle 50ms Normal — limitação do BT 9600 baud
Texto colado com chars errados Layout PT-BR Selecionar PT-BR ABNT2 no app
App muito pequeno no notebook Tela alta resolução App já corrigido com AutoScaleMode.Dpi