Arduino USB HID (Human Interface Devices)

The Hid protocol is used for physical interaction devices such as the mouse, keyboard and much more. Many Arduino-compatible development boards support HID (but not all), allowing the microcontroller to behave just like a regular mouse, keyboard or gamepad. These examples are intended for ESP32 boards, such as the ESP32-S3 Thing Plus from Sparkfun, which also supports the MIDI protocol.

All the examples on this page can be tested with jumper wires connecting the appropriate pins to ground.

Warning! You may have a hard time re-programming your Arduino if it’s constantly taking over your mouse or keyboard!

You can build in a work around with a little logic and a jumper wire or button. Start your code with something similar to this, which would block the HID behaviour, unless pin 10 is connected to GND. This already needs to be connected before powering up the Arduino (or reseting).

#define HIDdisablePin 10 void setup() { pinMode(HIDdisablePin, INPUT_PULLUP); // Disable the mouse Unless HIDdisablePin is connected to ground if(digitalRead(HIDdisablePin) == HIGH) { while(1) { /* infinite loop */ } } // The rest of your code after this line } void loop() { }


You may also have trouble finding your Arduino on the port list in the Arduino IDE after turning it into a HID device. With the ESP32-S3 Thing Plus, hold the BOOT button while plugging into the USB C plug to set it into boot mode, which should allow you to find it in the port list.

 

HID Mouse

This example gets the Arduino to act like a mouse, based on two analog Inputs. Don’t forget to connect pin 10 to GND! This example uses basic digital inputs, so you can test it out with a jumper wire from GND to pins 1,2,3,5, and 7 to left click.

 

#include "USB.h" #include "USBHIDMouse.h" #define HIDdisablePin 10 #define mouseXUp 1 #define mouseXDown 2 #define mouseYLeft 4 #define mouseYRight 5 #define click 7 USBHIDMouse Mouse; void setup() { pinMode(HIDdisablePin, INPUT_PULLUP); // disable the mouse unless HIDdisablePin is connected to ground if (digitalRead(HIDdisablePin) == HIGH) { while (1) { /* infinite loop */ } } // The rest of your code after this line pinMode(mouseXUp, INPUT_PULLUP); pinMode(mouseXDown, INPUT_PULLUP); pinMode(mouseYLeft, INPUT_PULLUP); pinMode(mouseYRight, INPUT_PULLUP); pinMode(click, INPUT_PULLUP); // initialize mouse control: Mouse.begin(); USB.begin(); } void loop() { if (digitalRead(mouseXUp) == LOW) { // move mouse up Mouse.move(0, -10); } else if (digitalRead(mouseXDown) == LOW) { // move mouse down Mouse.move(0, 10); } if (digitalRead(mouseYLeft) == LOW) { // move mouse left Mouse.move(-10, 0); } else if (digitalRead(mouseYRight) == LOW) { // move mouse right Mouse.move(10, 0); } // if the mouse button is pressed: if (digitalRead(click) == LOW) { // if the mouse is not pressed, press it: if (!Mouse.isPressed(MOUSE_LEFT)) { Mouse.press(MOUSE_LEFT); } } else { // if the mouse is pressed, release it: if (Mouse.isPressed(MOUSE_LEFT)) { Mouse.release(MOUSE_LEFT); } } delay(10); }

 

HID Keyboard

Here is an example writing messages and using shortcuts with the HID keyboard protocal. You can find the full list of keys in the library source code. Again, be sure the pin 10 is connected to GND.

 

#include "USB.h" #include "USBHIDKeyboard.h" #define HIDdisablePin 10 #define message 1 #define shortcut 2 USBHIDKeyboard Keyboard; void setup() { pinMode(HIDdisablePin, INPUT_PULLUP); delay(20); // disable the mouse unless HIDdisablePin is connected to ground if (digitalRead(HIDdisablePin) == HIGH) { while (1) { /* infinite loop */ } } // The rest of your code after this line pinMode(message, INPUT_PULLUP); pinMode(shortcut, INPUT_PULLUP); // initialize keyboard control: Keyboard.begin(KeyboardLayout_de_DE); // optional keyboard region setting USB.begin(); } void loop() { if (digitalRead(message) == LOW) { // write a keyboard message Keyboard.print("Interaction Design ZHdK!"); delay(400); } if (digitalRead(shortcut) == LOW) { // focus on a random application window in OSX Keyboard.press(KEY_RIGHT_GUI); Keyboard.press(KEY_TAB); delay(100); Keyboard.release(KEY_TAB); delay(100); int randomCount = random(6); int count = 0; while (count < randomCount) { count++; Keyboard.press(KEY_TAB); Keyboard.release(KEY_TAB); delay(400); } Keyboard.releaseAll(); } delay(10); }

 

HID Volume

Here is a simple example for controlling your computer's volume. This uses the consumer control options from the HID library, which includes many common controls for browsing, music playback and more. See the source code for the full list. Again, be sure the pin 10 is connected to GND.

 

Â