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
- Arduino UNO
- bouton poussoir (ou un 1 câble dupont)
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.
- Télécharger et installer le logiciel Flip
- Sélectionner le microprocesseur dans la liste proposée
- Faire un reset du port USB en reliant les deux pins les plus à gauche du port ICSP2. (les LEDs Tx et Rx devrait s’allumer toutes les deux)
- Sélectionner Settings>Communication>USB Ctrl+U, puis cliquer sur « Open ».
- Charger le fichier Arduino-keyboard-0.3.hex dans File> Load HEX…, puis appuyer sur « Run »
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
- Créer un clavier ou un contrôleur de jeu vidéo avec Arduino
- Utiliser Arduino pour piloter un ordinateur automatiquement