Arduino Uno R3 as HID

Revision as of 18:16, 27 August 2014 by Gaess (talk | contribs) (→‎Arduino as a USB-Keyboard)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search


To change your Arduino UNO R3 into a usb HID device - for example a USB-keyboard - you will have to load a new firmware on the ATMEGA 16U2 chip on your Arduino board. That is the small square chip just behind the USB port on the board. This procedure is called DFU-programming or updating the firmware.

Updating the ATMEGA 16U2

First step is to reflash the ATMEGA 16U2 so we know that our setting is actually working. This instructions are based on some useful sites and forum hints on the web:

And some more hints in different forums I cannot recall anymore.

Install dfu-programmer

Download dfu-programmer from your distribution repos. For Ubuntu and Debian:

sudo apt-get install dfu-programmer

Once installed, check the version with

dfu-programmer --version

It has to be at least 0.6.1 for the following steps to work. If it's not, download the programmer directly from the authors: DFU-Programmer at GitHub

Reset 16U2

The Arduino Uno R3 (I'll call it just R3 from now on) comes with pin headers for the 16U2. To reset the chip, connect the two pins closest to the usb-port.

Flash Arduino's standard firmware to ATMEGA 16U2

The following instructions are for linux OS's.

Download the latest firmware from GitHub. The file is called Arduino-COMBINED-dfu-usbserial-atmega16u2-Uno-Rev3.hex at the time of writing. You will have to open the file on GitHub as raw and save it locally with your browsers' "save" function. If the hex is stored in a wrong format locally, the flashing will fail with the error message: "Error parsing the line."

Open a terminal and change to your download directory.

Check if the programmer sees the 16U2:

sudo dfu-programmer atmega16u2 dump

You should get a gazillion of question marks on the terminal as a response.

Erase the chip, upload firmware and reset:

sudo dfu-programmer atmega16u2 erase
sudo dfu-programmer atmega16u2 flash --suppress-bootloader-mem Arduino-COMBINED-dfu-usbserial-atmega16u2-Uno-Rev3.hex
sudo dfu-programmer atmega16u2 reset

Unplug your Arduino and plug it back in. It should behave like an ordinary R3. Try uploading a sketch from the Arduino environment to check.

Flashing HID firmware to the 16U2

We're going to change the arduino into a HID device now. The code we are using is from the LUFA project and, who used this library to create some ready made arduino firmwares.

Arduino as an USB-Keyboard

Loading the firmware

Download the keyboard firmware and supporting files from here.

First, load the example sketch "kbd_usb_demo" on the Arduino.

Open a terminal, change to the directory where the downloaded files are and flash the firmware to the Arduino:

  • Reset 16U2 (explained above)
  • flash the chip:
sudo dfu-programmer atmega16u2 erase
sudo dfu-programmer atmega16u2 flash Arduino-keyboard-0.3.hex
sudo dfu-programmer atmega16u2 reset

Unplug the arduino. Open a text editor. Attach the arduino while having your text editor in focus. The Arduino should now write "hello world" and set the volume.


Some of the explanations from here and some own insights from the example code provided in kbd_usb_demo.pde.

Define all modifier keys in your sketch:

#define KEY_LEFT_CTRL	0x01
#define KEY_LEFT_SHIFT	0x02
#define KEY_LEFT_ALT    0x04
#define KEY_LEFT_GUI    0x08
#define KEY_RIGHT_CTRL	0x10
#define KEY_RIGHT_SHIFT	0x20
#define KEY_RIGHT_ALT   0x40
#define KEY_RIGHT_GUI   0x80

Define most common special keys in your sketch:

#define KEY_RIGHT_ARROW 0x4F
#define KEY_LEFT_ARROW  0x50
#define KEY_DOWN_ARROW  0x51
#define KEY_UP_ARROW    0x52
#define KEY_ESC         0x29
#define KEY_F1          0x3A
#define KEY_F2          0x3B
#define KEY_F3          0x3C
#define KEY_F4          0x3D
#define KEY_F5          0x3E
#define KEY_F6          0x3F
#define KEY_F7          0x40
#define KEY_F8          0x41
#define KEY_F9          0x42
#define KEY_F10         0x43
#define KEY_F11         0x44
#define KEY_F12         0x45
#define KEY_PRTSCR      0x46
#define KEY_SCRLK       0x47
#define KEY_PAUSE       0x48
#define KEY_DEL         0x4C
#define KEY_INS         0x49
#define KEY_END         0x4D
#define KEY_HOME        0x4A
#define KEY_PGDN        0x4E
#define KEY_PGUP        0x4B
#define KEY_BACKSPC     0x2A
#define KEY_TAB         0x2B
#define KEY_ENTER       0x28
#define KEY_SPC         0x2C
#define KEY_MUTE        0x7F
#define KEY_VOL_UP      0x80
#define KEY_VOL_DOWN    0x81

Send Ctrl + Alt + F1:

 uint8_t codebuffer[8] = { 0 };	// Keyboard keycodes buffer
 void setup() {

 void loop() {
   codebuffer[0] = KEY_LEFT_CTRL + KEY_LEFT_ALT;
   codebuffer[2] = KEY_F1;
   Serial.write(codebuffer, 8);	// Send keypress
   codebuffer[0] = 0;
   codebuffer[2] = 0;
   Serial.write(codebuffer, 8);	// Release key

Find all keycodes in Chapter 10: "Keyboard/Keypad Page (0x07)" of the HID usage Tables document.

Re-programming the Arduino after it is set as HID

The change the sketch on your R3 again, you will have to load the standard firmware fisrt, as explained above.