KVMote/Uno/KVMote.ino

169 lines
6.8 KiB
C++

/*
KVMote — Arduino Leonardo (Serial1 = HC-06)
Baud rate: 9600 (padrão de fábrica do HC-06).
Se você já configurou o HC-06 para outra velocidade via AT commands,
altere a constante abaixo.
Protocolo binário:
Mouse move → 'M' dx(int8) dy(int8) 3 bytes
Mouse wheel → 'W' delta(int8) 2 bytes
Tecla write → 'K' char 2 bytes
Clique → 'C' 'L'|'R' 2 bytes
Tecla press → 'P' keycode 2 bytes
Tecla release → 'U' keycode 2 bytes
ReleaseAll → 'A' 1 byte
Mouse press → 'D' 'L'|'R' 2 bytes
Mouse release → 'E' 'L'|'R' 2 bytes
LED cliente → 'O' (laranja — mouse no cliente)
LED host ok → 'H' (azul — host conectado)
LED sem host → 'G' (verde — host desconectado)
Ping/Pong → '~' → responde [PONG] 1 byte
*/
#include <Keyboard.h>
#include <Mouse.h>
// ── Pinos do LED RGB ──────────────────────────────────────────────────────────
#define PIN_R 5
#define PIN_G 6
#define PIN_B 9
#define BAUD_HC06 9600 // ← altere se necessário
// ── Cor base do LED (muda conforme o modo) ────────────────────────────────────
uint8_t basR = 0, basG = 255, basB = 0; // verde = aguardando conexão
// ── Máquina de estados ────────────────────────────────────────────────────────
enum Estado : uint8_t {
AGUARDA_CMD,
AGUARDA_MOUSE_DX,
AGUARDA_MOUSE_DY,
AGUARDA_MOUSE_WHEEL,
AGUARDA_TECLA,
AGUARDA_CLIQUE,
AGUARDA_PRESS_KEY,
AGUARDA_RELEASE_KEY,
AGUARDA_MOUSE_PRESS,
AGUARDA_MOUSE_RELEASE
};
Estado estado = AGUARDA_CMD;
int8_t pendingDX = 0;
// ── Helper de LED ─────────────────────────────────────────────────────────────
void ledCor(int r, int g, int b) {
analogWrite(PIN_R, r);
analogWrite(PIN_G, g);
analogWrite(PIN_B, b);
}
// ── Setup ─────────────────────────────────────────────────────────────────────
void setup() {
Serial1.begin(BAUD_HC06);
Keyboard.begin();
Mouse.begin();
ledCor(basR, basG, basB); // verde = aguardando conexão do host
}
// ── Loop principal (non-blocking) ─────────────────────────────────────────────
void loop() {
while (Serial1.available() > 0) {
byte b = (byte)Serial1.read();
switch (estado) {
// ── Aguarda o byte de comando ──────────────────────────────────────────
case AGUARDA_CMD:
if (b == 'M') estado = AGUARDA_MOUSE_DX;
else if (b == 'W') estado = AGUARDA_MOUSE_WHEEL;
else if (b == 'K') estado = AGUARDA_TECLA;
else if (b == 'C') estado = AGUARDA_CLIQUE;
else if (b == 'P') estado = AGUARDA_PRESS_KEY;
else if (b == 'U') estado = AGUARDA_RELEASE_KEY;
else if (b == 'D') estado = AGUARDA_MOUSE_PRESS;
else if (b == 'E') estado = AGUARDA_MOUSE_RELEASE;
else if (b == 'A') {
Keyboard.releaseAll();
}
else if (b == 'O') {
// Entrou no PC cliente → LED magenta
basR = 255; basG = 0; basB = 255;
ledCor(basR, basG, basB);
}
else if (b == 'H') {
// Host conectado → LED azul
basR = 0; basG = 0; basB = 255;
ledCor(basR, basG, basB);
}
else if (b == 'G') {
// Host desconectado → LED verde
basR = 0; basG = 255; basB = 0;
ledCor(basR, basG, basB);
}
else if (b == '~') {
Serial1.print("[PONG]");
}
// qualquer outro byte é silenciosamente descartado
break;
// ── Mouse: lê DeltaX ──────────────────────────────────────────────────
case AGUARDA_MOUSE_DX:
pendingDX = (int8_t)b;
estado = AGUARDA_MOUSE_DY;
break;
// ── Mouse: lê DeltaY e executa o movimento ────────────────────────────
case AGUARDA_MOUSE_DY:
Mouse.move(pendingDX, (int8_t)b, 0);
estado = AGUARDA_CMD;
break;
// ── Mouse: roda do mouse / touchpad dois dedos ────────────────────────
case AGUARDA_MOUSE_WHEEL:
Mouse.move(0, 0, (int8_t)b);
estado = AGUARDA_CMD;
break;
// ── Teclado: lê o caractere e digita (write) ──────────────────────────
case AGUARDA_TECLA:
Keyboard.write(b);
estado = AGUARDA_CMD;
break;
// ── Clique: lê L ou R e clica ─────────────────────────────────────────
case AGUARDA_CLIQUE:
if (b == 'L') Mouse.click(MOUSE_LEFT);
if (b == 'R') Mouse.click(MOUSE_RIGHT);
estado = AGUARDA_CMD;
break;
// ── Tecla press (mantém pressionada) ─────────────────────────────────
case AGUARDA_PRESS_KEY:
Keyboard.press(b);
estado = AGUARDA_CMD;
break;
// ── Tecla release ─────────────────────────────────────────────────────
case AGUARDA_RELEASE_KEY:
Keyboard.release(b);
estado = AGUARDA_CMD;
break;
// ── Mouse press (botão segurado) ──────────────────────────────────────
case AGUARDA_MOUSE_PRESS:
if (b == 'L') Mouse.press(MOUSE_LEFT);
if (b == 'R') Mouse.press(MOUSE_RIGHT);
estado = AGUARDA_CMD;
break;
// ── Mouse release ─────────────────────────────────────────────────────
case AGUARDA_MOUSE_RELEASE:
if (b == 'L') Mouse.release(MOUSE_LEFT);
if (b == 'R') Mouse.release(MOUSE_RIGHT);
estado = AGUARDA_CMD;
break;
}
}
}