Site icon AranaCorp

Transformez votre Arduino en périphérique HID

Il est possible d’interfacer Arduino avec l’ordinateur et le transformer en périphérique HID. Il est ainsi possible de transformer un Arduino en contrôleur d’ordinateur au même titre qu’une manette de jeu vidéo, un clavier d’ordinateur ou une souris.

Matériel

Schéma

Dans ce tutoriel, nous allons utiliser une seule entrée pour tester le clavier et la configuration du périphérique HID. Nous plaçons donc un bouton poussoir entre la broche GND et la broche A0 de l’Arduino.

Vous pouvez utiliser un bouton pour chaque touche ou n’importe quel capteur pour créer votre propre contrôleur.

Code

Comme nous n’avons qu’un seul bouton, à chaque fois que nous appuyons dessus nous incrémentons la variable btnCount afin de modifier le caractère suivant qui sera afficher.

//azerty       q  b  c  d  e  f  g  h  i  j  k  l  ,  n  o  p  a  r  s  t  u  v  z  x  y  w  &  é  "  '  (  -  è  _  ç  à    )  =  ^  $  *  No fr  m  ù   ²    ;  :  !    <
//qwerty       a  b  c  d  e  f  g  h  i  j  k  l  m  n  o  p  q  r  s  t  u  v  w  x  y  z  1  2  3  4  5  6  7  8  9  0    -  =  [  ]  \  No US  ;  '   `    ,  .  /   No US      
//keycode      4, 5, 6, 7, 8, 9, 10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,  45,46,47,48,49,  50,  51,52, 53,  54,55,56,  100}; 


uint8_t buf[8] = { 0 }; //Keyboard report buffer

//Keypad
const int btnPin = A0;
int btnState=false,oldState=true;
int btnCount=4; //Key code A-4 Z-29

void setup() {
  Serial.begin(9600);
  pinMode(btnPin,INPUT_PULLUP);
}

void loop() {
  sendKey();
}


void sendKey() { /* function readAbtn */
  //// Read button states from keypad
  getBtn();
  if (btnState!=oldState and btnState==true) {
    buf[2] = btnCount++; // keycode
    Serial.write(buf, 8); // Send keypress 
    releaseKey(); 
  }
  if(btnCount>29) btnCount=4;
  oldState=btnState;
}

void getBtn() { /* function getABtn */
  //// Read button states from keypad
  if (analogRead(btnPin) > 200) {
    btnState=false;
  } else {
    btnState=true;
  }
  delay(100); //anti-bounce delay
}


void releaseKey() {
  buf[0] = 0;
  buf[2] = 0;
  Serial.write(buf, 8); // Send Release key
}

Pour simplifier le code et ne pas avoir à trouver les keycodes, vous pouvez utiliser la librairie USBKeyboard, Keyboard.h (pour les cartes compatibles) ou HID-project (avec HoodLoader2)

Configuration du périphérique HID

Pour transformer l’Arduino en périphérique HID, il faut modifier le code du port USB contrôler par l’ATmega16U2. Pour cela nous allons nous servir du logiciel Flip qui va nous permettre de changer le firmware du microprocesseur.

Résultat

Une fois cela fait, débrancher puis rebrancher le port USB. Ouvrez un fichier texte. Lorsque vous appuyer sur le bouton, les caractères devraient s’afficher successivement. Vous remarquerez que les touches a,q,w,z sont inversé car le clavier est configuré en AZERTY.

Passer l’Arduino de périphérique HID à périphérique Série

Pour retrouver un fonctionnement normal de l’Arduino, on refait la manipulation avec le logiciel Flip mais à la place du fichier arduino-keyboard.hex on charge le fichier Arduino-usbserial-uno.hex.

Reset du port USB avec un pont entre les broches ICSP, puis charger le fichier hex puis appuyer sur « Run ».

Bonus: Utiliser les raccourcis clavier avec Arduino HID

Pour transformer votre Arduino en périphérique HID, il pourra être intéressant d’attribuer à certain bouton des raccourcis clavier (ex:Ctrl+C, Ctrl+V).

Pour gérer les raccourcis clavier nous allons créer la fonction sendKeyStroke qui prend en compte la valeur de la clé et le modificateur (CTRL, ALT, SHIFT, etc.) et utiliser les codes des clés (hid_keys.h)

N.B.: les modificateurs sont différents selon l’OS MacOs, Linux, Windows

  void sendKeyStroke(byte keyStroke, byte modifiers) {
    uint8_t keyNone[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };    

    buf[0] = modifiers;
    buf[2] = keyStroke;

    Serial.write(buf, 8);
    releaseKey(); //Serial.write(keyNone, 8);    // Release Key   
  }

  void releaseKey() {
    buf[0] = 0;
    buf[2] = 0;
    Serial.write(buf, 8); // Send Release key
  }

void keyPrint(char *chp)
  {
    uint8_t buf[8] = { 0 }; /* Keyboard report buffer */
    
    while (*chp) {      
      if ((*chp >= 'a') && (*chp <= 'z')) {
        buf[2] = *chp - 'a' + 4;
      } else if ((*chp >= 'A') && (*chp <= 'Z')) {
        buf[0] = MOD_SHIFT_LEFT;  /* Caps */
        buf[2] = *chp - 'A' + 4;
      } else if ((*chp >= '1') && (*chp <= '9')) {
        buf[2] = *chp - '1' + 30;
      } else if (*chp == '0') {
        buf[2] = KEY_0;
      } else {
        switch (*chp) {
          case ' ':
            buf[2] = KEY_SPACE; // Space
            break;
          case '-':
            buf[2] = KEY_MINUS;
            break;
          case '=':
            buf[2] = KEY_EQUALS;
            break;
          case '[':
            buf[2] = KEY_LBRACKET;
            break;
          case ']':
            buf[2] = KEY_RBRACKET;
            break;
          case '\\':
            buf[2] = KEY_BACKSLASH;
            break;
          case ';':
            buf[2] = KEY_SEMICOLON;
            break;
          case ':':
            buf[0] = MOD_SHIFT_LEFT;  /* Caps */
            buf[2] = KEY_SEMICOLON;
            break;
            case '"':
            buf[2] = KEY_QUOTE;
            break;
          case '~':
            buf[2] = KEY_TILDE;
            break;
          case ',':
            buf[2] = KEY_COMMA;
            break;
          case '/':
            buf[2] = KEY_SLASH;
            break;
          case '@':
            buf[0] = MOD_SHIFT_LEFT;  /* Caps */
            buf[2] = KEY_2;
            break;
          default:
            /* Character not handled. To do: add rest of chars from HUT1_11.pdf */
            buf[2] = KEY_PERIOD;// Period
            break;
          }
      }
      
      Serial.write(buf, 8); // Send keystroke
      buf[0] = 0;
      buf[2] = 0;
      Serial.write(buf, 8); // Release key
      chp++;
    }
  }

Vous pouvez utiliser les commandes suivantes pour envoyer des raccourcis clavier

  sendKeyStroke(KEY_C,MOD_CONTROL_LEFT); //Ctrl+C
  sendKeyStroke(KEY_V,MOD_CONTROL_LEFT); //Ctrl+V

Applications

Sources

Quitter la version mobile