169 lines
6.8 KiB
C++
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;
|
|
}
|
|
}
|
|
}
|