🛠 Télécommande HID avancée : clavier + souris + série simultanés

Arduino Esplora — Board Fiche · avance · Schéma : IMG-esplora-avance-2-esplora-hid-avance-telecommande.svg — Esplora au centre émettant trois flux USB vers l'ordinateur : clavier HID, souris HID et port série CDC, avec joystick pilotant le curseur et boutons les touches.

Objectives

Push the ATmega32u4's native USB to its limits: simultaneously enumerate a HID keyboard, a HID mouse, and a CDC serial port, exactly like the official EsploraRemote and EsploraTable projects. The joystick moves the cursor, the buttons click and type, the slider controls scrolling, and the CDC remains available for debugging — this combination is only possible because the 32U4 handles USB in silicon.

Hardware

Complete Code

/* Telecommande complete : souris + clavier + debug serie en meme temps.
   Pattern inspire des exemples officiels EsploraJoystickMouse/EsploraRemote.
   SECURITE : la condition d'arret (joystick en bas a fond pendant 2 s)
   laisse toujours une porte de sortie avant de lacher du HID sur le poste. */
#include <Esplora.h>
#include <Mouse.h>
#include <Keyboard.h>

uint32_t appuiJoystick = 0;

void setup {
  Serial.begin(9600);
  Mouse.begin;
  Keyboard.begin;
  delay(2000);                 // laisse le temps de lire ce message
  Serial.println("Pret. Joystick en bas a fond 2 s = mode sans HID.");
}

void loop {
  int x = Esplora.readJoystickX;
  int y = Esplora.readJoystickY;

  // Garde-fou : maintenir le stick en bas arrete toute emission HID
  if (y < -480) {
    if (appuiJoystick == 0) appuiJoystick = millis;
    if (millis - appuiJoystick > 2000) {
      Serial.println("HID desactive, je dors.");
      while (true) delay(1000);   // plus aucun mouvement souris/clavier
    }
  } else {
    appuiJoystick = 0;
  }

  // Souris : deplacement proportionnel avec zone morte
  if (abs(x) > 15 || abs(y) > 15) Mouse.move(x / 32, y / 32);

  // Clic gauche = bouton bas ; molette = slider
  if (Esplora.readButton(SWITCH_DOWN) == PRESSED && !Mouse.isPressed(MOUSE_LEFT))
    Mouse.press(MOUSE_LEFT);
  if (Esplora.readButton(SWITCH_DOWN) == RELEASED && Mouse.isPressed(MOUSE_LEFT))
    Mouse.release(MOUSE_LEFT);
  int s = Esplora.readSlider;
  if (s > 900) Mouse.move(0, 0, 1);
  if (s < 100) Mouse.move(0, 0, -1);

  // Clavier : fleches avec les autres boutons
  if (Esplora.readButton(SWITCH_LEFT) == PRESSED)  Keyboard.write(KEY_LEFT_ARROW);
  if (Esplora.readButton(SWITCH_RIGHT) == PRESSED) Keyboard.write(KEY_RIGHT_ARROW);
  if (Esplora.readButton(SWITCH_UP) == PRESSED)    Keyboard.write(KEY_UP_ARROW);

  delay(20);
}

Expected Verification

The cursor follows the joystick, the bottom button clicks, the slider scrolls the page, and the other buttons send arrow keys. The serial monitor (CDC) remains active in parallel: the startup message is displayed, proving the triple HID+CDC enumeration. The safety guard (stick held down for 2 s) stops all transmission before becoming problematic.

Common Errors

  1. No safety guard: Official warning for the Leonardo/Esplora class — a misbehaving HID sketch can render the PC unusable; always provide a physical stop condition, and keep the Reset button accessible (bootloader window ~8 s).
  2. Forgetting Mouse.begin/Keyboard.begin: One of the two devices remains silent.
  3. Too fast: Without delay(20), the host is flooded with mouse reports; the cursor jumps and the PC lags.
  4. Thinking you lose serial when adding HID: Arduino libraries combine descriptors; only when writing a custom HID descriptor (lumino/usbdcore) do you control the composition — and potentially break the CDC.
  5. Neglecting multimedia/special keys: KEY_LEFT_ARROW does not exist in lowercase; the constants are those from Keyboard.h — a typo becomes an unexpected ASCII character on the host.

Other tutorials for this board

Code examples for this board

← Back to the board 🛠 All tutorials