A little-known functionality of certain microprocessors is the ability to emulate a keyboard or mouse when connected to a computer and other compatible devices via USB.
This HID (Human Interface Device) emulation functionality is natively available on boards that incorporate the ATMEGA 32u4 (Micro, Leonardo) or SAMD (Zero, Due, MKR) processors.
Other processors outside of the Arduino “ecosystem” may also incorporate the HID emulation function. There are even certain ‘workarounds’ for processors like the Atmega 328 to act as a HID, but in general, they do not work very well.
What can this be useful for? For example, to interact with machines or programs to which we do not have access to install a program. For example, we can control an Android video player, or even industrial machines that cannot have software installed but are controlled by keyboard or mouse.
Another common use is to combine the HID functionality with a sensor to create our “own” HID controllers. For example, controlling a video game with potentiometers, or a glove with accelerometers, or with ultrasonics, etc.
Finally, another possible use is to automate tasks in devices. For example, if you have to run a process on many computers, or enter a password discreetly, you can set up one or more devices to run the processes. They plug it in, and it’s ready.
As we say, a very simple functionality to use and sometimes forgotten, which can be useful in quite a few situations and deserves a quick entry.
To use Arduino as a keyboard, we have the ‘Keyboard’ library that is included in the standard Arduino IDE. Its use is very simple, here is a summary of the main functions of the library.
// Start and end the virtual keyboard Keyboard.begin() Keyboard.end() // Write text using the keyboard Keyboard.print() Keyboard.println() Keyboard.write() // Press and release a key Keyboard.press() Keyboard.release() Keyboard.releaseAll()
As we can see, its use is very similar to using the Serial library. But let’s see it with some examples.
Let’s start with a simple example. With the following code we write ‘Hello world!’ using keyboard emulation.
#include void setup() Keyboard.begin(); delay(5000); > void loop() Keyboard.println("Hello world!"); delay(1000); >
We have left a 5-second pause in the ‘Setup’ to make it easier to reprogram. If we don’t leave any pause, the program will start writing immediately, which would write in the IDE itself, and it is annoying to reprogram.
If you don’t put a pause and have trouble reprogramming, you can do it by connecting the Arduino to USB just when the IDE has finished compiling.
If we want to use key combinations (for example, Control+…), we can use the ‘press’ and ‘release’ functions. In the following code, we see two different ways to, for example, press Control+n.
#include void setup() Keyboard.begin(); > void loop() Keyboard.press(KEY_LEFT_CTRL); Keyboard.press('n'); delay(100); Keyboard.releaseAll(); // another way to release, key by key //Keyboard.release(KEY_LEFT_CTRL); //Keyboard.release('n'); delay(1000); >
Here is a list of the available keys and modifiers, and their hexadecimal and decimal codes.
KEY | HEX | DEC |
---|---|---|
KEY_LEFT_CTRL | 0x80 | 128 |
KEY_LEFT_SHIFT | 0x81 | 129 |
KEY_LEFT_ALT | 0x82 | 130 |
KEY_LEFT_GUI | 0x83 | 131 |
KEY_RIGHT_CTRL | 0x84 | 132 |
KEY_RIGHT_SHIFT | 0x85 | 133 |
KEY_RIGHT_ALT | 0x86 | 134 |
KEY_RIGHT_GUI | 0x87 | 135 |
KEY_UP_ARROW | 0xDA | 218 |
KEY_DOWN_ARROW | 0xD9 | 217 |
KEY_LEFT_ARROW | 0xD8 | 216 |
KEY_RIGHT_ARROW | 0xD7 | 215 |
KEY_BACKSPACE | 0xB2 | 178 |
KEY_TAB | 0xB3 | 179 |
KEY_RETURN | 0xB0 | 176 |
KEY_ESC | 0xB1 | 177 |
KEY_INSERT | 0xD1 | 209 |
KEY_DELETE | 0xD4 | 212 |
KEY_PAGE_UP | 0xD3 | 211 |
KEY_PAGE_DOWN | 0xD6 | 214 |
KEY_HOME | 0xD2 | 210 |
KEY_END | 0xD5 | 213 |
KEY_CAPS_LOCK | 0xC1 | 193 |
KEY_F1 | 0xC2 | 194 |
KEY_F2 | 0xC3 | 195 |
KEY_F3 | 0xC4 | 196 |
KEY_F4 | 0xC5 | 197 |
KEY_F5 | 0xC6 | 198 |
KEY_F6 | 0xC7 | 199 |
KEY_F7 | 0xC8 | 200 |
KEY_F8 | 0xC9 | 201 |
KEY_F9 | 0xCA | 202 |
KEY_F10 | 0xCB | 203 |
KEY_F11 | 0xCC | 204 |
KEY_F12 | 0xCD | 205 |
In this last example, we see a somewhat more functional case, launching Notepad in Windows. To do this, we press the Windows+R key, type “notepad” + ENTER in the window that appears. Finally, we write “Hello world!” in the Notepad window.
#include void setup() Keyboard.begin(); > void loop() Keyboard.press(KEY_RIGHT_GUI); Keyboard.press('r'); delay(100); Keyboard.releaseAll(); delay(1000); Keyboard.println("notepad"); Keyboard.press(KEY_RETURN); delay(100); Keyboard.releaseAll(); Keyboard.print("Hello world!"); >
It is also possible to emulate a mouse with the ‘Mouse’ library included in the standard IDE. The functions of this library are as follows.
// Start and stop the virtual mouse Mouse.begin() Mouse.end() // Relative mouse movement Mouse.move() // Click with the mouse Mouse.click() Mouse.press() Mouse.release() Mouse.isPressed()
Let’s see a simple example of how to emulate a mouse with Arduino. The following example moves the mouse 10px to the left and up and clicks.
#include "Mouse.h" void setup() Mouse.begin(); > void loop() Mouse.move(10, 10, 0); Mouse.click(); delay(100); >
The ‘Mouse’ library has the disadvantage that it only allows relative mouse movements. This may be sufficient to interact with programs (for example, a video game) from a device moved by a user (for example, a potentiometer or a gyroscope).
But in many cases, it is convenient to be able to move the mouse to some screen coordinates, in absolute value. For example, to click on a button in a program.