Arduino USB HID Keyboard

  

Turn your Arduino UNO into a USB HID keyboard, and make buttons that do whatever you want. Make it a useful tool, with new buttons for Cut/Copy/Paste or Volume+/Volume-/Mute, or annoy your friends and colleagues by setting the keyboard to perform random keypress after random delays!

The USB HID keyboard conforms to the standard USB specification, so is functional on all modern operating systems.  All this is made possible by the use of the Arduino Device Firmware Update (DFU) function.

Arduino Device Firmware Update (DFU)

The Atmega8U2 chip on the Arduino UNO can be programmed directly using the special USB protocol called Device Firmware Update (DFU). This is completely independant of the ‘normal’ method of flashing sketches to the board using the Arduino IDE.

This process is normally used to update the firmware to a more recent version, as explained in the offical Arduino guide, Updating the Atmega8U2 on an Uno or Mega2560 using DFU. Note: If your board is NOT an Arduino UNO SMD you’ll need to solder a 10k resistor (Brown-black-orange) at the back of your board as shown on the Arduino site.

However, in addition to the ability to flash standard USB Serial firmwares, we can also flash alternative firmwares as well. This allows the device to be recognized as many other device types, including keyboard, mouse, joystick, midi device, etc. This is made possible in part to the wonderful open source LUFA (Lightweight USB Framework for AVRs)  USB stack, and keyboard HID firmware from Darran.

In this demonstration, we will flash generic USB HID keyboard firmware. The USB HID protocol provides manufactures the generic specifications to interact with nearly every operating system in existence. For more info, check out the USB HID Spec sheet.

Before you start, install the required packages. On Ubuntu and Debain systems, in a terminal run:

sudo apt-get install dfu-programmer dfu-util

For Windows and Mac instructions to install the dfu-programmer tool, consult the official Arduino DFU documentation.

Then download these two firmware files:

Arduino-usbserial.hex
Arduino-keyboard-0.3.hex

The first step is to make sure you are able to flash the standard arduino firmware. This will confirm that the programmer and the environment are both functional. NOTE: There is no chance of ‘bricking’ the device using this method. The Arduino bootloader firmware can always be updated using the DFU protocol!

sudo dfu-programmer at90usb82 erase
sudo dfu-programmer at90usb82 flash --debug 1 Arduino-usbserial.hex
sudo dfu-programmer at90usb82 reset

Plug cycle the Arduino, then open the Arduino IDE and ensure that you can still upload a sketch. Assuming everything flashes normally, we can move forward with flashing the HID keyboard firmware.

sudo dfu-programmer at90usb82 erase
sudo dfu-programmer at90usb82 flash --debug 1 Arduino-keyboard-0.3.hex
sudo dfu-programmer at90usb82 reset

NOTE: The Arduino can only be flashed with skectches through the Adruino IDE if the Arduino-usbserial.hex bootloader is active. So, to develop a USB HID device, the process becomes:

Flash Arduino-usbserial.hex bootloader with dfu-programmer (erase/flash/reset)
Plug cycle the Arduino
Flash firmware sketch using Arduino IDE
Plug cycle the Arduino
Flash Arduino-keyboard-0.3.hex bootloader with dfu-programmer (erase/flash/reset)
Test and repeat

Now that you understand how the process works, you can try out some of these keyboard samples. The easiest example is the random keypress with random delays, since it doesn’t require any components connected to the Arduino.

Random Key/Random Delay

The following two examples both use three buttons connected to the Arduino. The code can easily be changed to make the buttons perform other actions, by consulting the mapping tables in the USB HID documentation.  Here is a diagram of the circuit, (created with Fritzing):

 

Volume+/Volume-/Mute

Cut/Copy/Paste

 

49 Comments

  1. kirill

    Neat, I found it easier to flash the 8U2 via an external programmer, but I like that it is possible to do it using a DFU

  2. Zirrus

    I wonder, could the teensyduino add-on be used to upload sketches while the 8U2 is burned with the keyboard hex?

    • Interesting… I was previously not familiar with the teensyduino add-on. I will give it a try and see if this will work to flash sketches while the keyboard hex firmware is active.

      • Zirrus

        Looks like teensy uses a special proprietary bootloader call HalfKay, instead of DFU. LUFA has a similar HID bootloader that can be used as an alternative, from what I’ve found (http://elasticsheep.com/2010/01/installing-the-lufa-teensyhid-bootloader/).

        The hardware/teensy/boards.txt file for the teensyduino addon will need to be edited, and there is no support for a90usb82 in the headers. Could be an involved project to add the capability.

        • Aww… too bad. This seemed like it would be a more efficient solution to the current awkward development cycle of flashing back and forth to the serial firmware.

          • Zirrus

            Yea, I’m still looking at it. If anything, it would be nice to be able to flash back and forth to the serial firmware from inside the arduino ide.

  3. Really awesome stuff. The sudo “dfu-programmer at90usb82 erase” fails me though, all I get is “dfu-programmer: no device present.”. I can see the my UNO with lsusb … Anyone got any ideas?

    • Zirrus

      If you can see your UNO and *Not* UNO DFU, your ATmega8U2 isnt in DFU mode. Different revisions have different methods to reset into DFU, my UNO R2 only requires a momentary short on pins 5 & 6 of the 8u2′s ISP header.

    • Zirrus is right. You will only be able to see the UNO in DFU if you have performed the momentary short of the ISP header pins. If you are able to see it from the Adruino IDE (or it is currently running the keyboard firmware and is acting according), then give the momentary short another attempt.

      • Bekky

        Thanks you two. It is all still a bit strange to me though.

        When I short the two ISP pins (reset & gnd) the small LED marked “L” flashes a few times and I can no longer see the UNO from the Arduino IDE.

        With lsusb, this is what I get: “Bus 004 Device 010: ID 03eb:2fef Atmel Corp.” – where before the UNO was listed by lsusb without the “Atmel Corp.”-part.

        However, I still get the “no device present.” when I try to run the “dfu-programmer at90usb82 erase”-command. Both as root and regular user.

        Oh dear :-(

        • Zirrus

          Hello again Bekky. You’re on the right track atleast. You might need to add a rule to udev to have permissions to the device. You can trying running ‘sudo dfu-programmer’ and see if that works OR you can create the file /etc/udev/rules.d/99-dfu-programmer.rules and add the following text:

          SUBSYSTEM==”usb”, ACTION==”add”, SYSFS{idVendor}==”03eb”, SYSFS{idProduct}==”2fef”, MODE=”660″, GROUP=”plugdev”, SYMLINK+=”at90usb-%k”

          BUS==”usb”, ACTION==”add”, SYSFS{idVendor}==”03eb”, SYSFS{idProduct}==”2fef”, MODE=”660″, GROUP=”plugdev”

          Then restart udev with “/etc/init.d/udev restart” This should change the permission so that your user account can touch the device.

          • I have been using an Uno compatible device called an eleven from Freetronics. I initially had similar issues to you with setting the at90usb82 to DFU mode – The method I found that works best, is too short the two pins(reset and gnd), push the reset button, remove the short (whilst still pressing the button), then release the button – I found that I then got three short flashes from the LED, and was able to send erase using dfu-programmer. Hopefully this may help?

  4. Nice Tutorial – thanks for sharing – It really got my project moving in the right direction. The links are a wealth of information also. Cheers

  5. Hi Michael,

    I have loaded the arduino-keyboard hex file on my r3 uno, with a 16u2, and i am able to send any character (a through z) but i cant get the volume up (128) mute (127) or volume down (129) or it seems any thing above 100 to work. page up and down (75 and 78 are working)

    my code is :

    buf[2] = 127; // Random character
    Serial.write(buf, 8); // Send keypress
    releaseKey();

    any ideas why it wont work? i have spent many hours trying to figure it out, I am using the latest keyboard hex (0.3).

    Cheers

  6. Hi Michael,

    the keybord software works fine, but when when i put the uno board into a usb-hub bios and windows only see an unknown device. It is so too when i use a power supply.
    Any idea?
    I have tested this with some hubs

  7. Can you link us to the source code of Arduino-keyboard-0.3.hex please?

  8. Would I be able to use the USB keyboard functionality on another chip, like an ATtiny45? Would I first reflash the Arduino, then use it in that mode to program the ATtiny45? would I need something larger, like an ATmega? or does the Arduino have magic that I just can’t get from one of these chips alone?

    http://blog.makezine.com/2011/10/10/how-to-shrinkify-your-arduino-projects/

    This is a great project idea but, like all of them, I hate the thought of giving up my Arduino permanently :)

  9. Ulrich Prinz

    Hi Michael,

    This little ‘toy’ of yours has become an important productive tool for me!
    Thank you for documenting this so nicely!

    I had bougth a Logitech Touchpad T650, and like many people that commented
    on the Logitech website, I find that it lacks gestures e.g. for Switch-to-next-Tab, Close-Tab, Close-window etc.
    These missing functions are now provided by a row of leftover Cherry MX keyboard keys at the top end of the T650 served buy the Arduino.
    Now I can whizz through tabs like a whirlwind ;-)

    I have 2 more tips to make the whole thing even more efficient:
    1) Your code for the 3 keys still looks ok, but when you have more keys, it makes more sense to take out these 2 lines out of the individual “if” branches to the bottom of the loop
    Serial.write(buf, 8); // Send keypress
    releaseKey();
    2) Because I have to drag the little Arduino out of its tiny Keyboard-Case every time I want to DFU and reprogram it, I have changed the code to send the keycodes for F13 to F24 on the pins, and then using AutoHotKey (look it up in Google) to translate those into the keys&combinations that I really want. This allows also to use the few keys I have there very specific to the application that is active at the moment.

  10. Hi, say I want to send keypress like [CTRL] + [ALT] + [C] to computer via Arduino. What is the way to do it please?

    • buf[0] is for the modifier keys such as control, shift and alt. You can simulate multiple modifier keys simultaneously pressed by making buf[0]=KEY_LEFT_CTRL+KEY_LEFT_ALT;
      Then buf[2]=KEY_C;

      • Can you clarify for me if the “delete” key is considered a modifier key or just another key? If the latter, would you implement the “three-finder-salute” Control-Alt-Delete like this???

        #define KEY_LEFT_CTRL 0×01
        #define KEY_LEFT_ALT 0×04

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

        int PIN_POWEROFF = 7;
        int KEY_DELETE = 76;

        void loop()
        }
        state = digitalRead(PIN_POWEROFF);
        if (state != 1) {
        buf[0] = KEY_LEFT_CTRL+KEY_LEFT_ALT
        buf[2] = KEY_DELETE;
        Serial.write(buf, 8);
        releaseKey();
        }
        }

  11. When my arduino 2560 is in HID USB keyboard mode, I have to press the reset button before it runs my code. Any idea what is going on here? is it a safe guard of some sort? Will I need to make a reset on boot circuit to get around this or is there another way. Also, is this just me or is it normal behavior?

    Other than this niggle it works great and your tutorial made it much easier to set up.

  12. Thanks for the informative post.
    I have a quick question, How do you send a long key press?
    for an example, long press home button on Android will activate google voice search app?

  13. Hi, I am having trouble installing the DFU programmer, I get libusb0.dll missing when I try to run the program . Anyone have this same problem?

  14. Mads Juel

    Hello, Im making a product with bitvoicer and and the key setup. I kan se that you buf 2 and then there is a number for the different letters .. i was wondering what the numbers for [a],[s],[d],[w] and/or the arrow keys :) ??

  15. This is really cool, I would like to use this for a custom keyboard project. But with this new firmware on the Arduino. Since it is using the __factory USB__ port to communicate with PC **as a keyboard**, doesn’t this increase the parts cost? What if you wantted to put this into a product? The cost would go up because instead of a $6 ATmel chip, you now have the cost of $22 arduino development board to? That is was it seems like to me.

    • If you’re competent to buy a $6 smd chip (more like $2 really) and make PCB’s for production you don’t need Arduino in the first place. This project let’s folks use their existing Uno hardware in new ways, very groovy

  16. rockstar

    Hey.. in the example code..
    buf[0]=27; //letter X
    I can’t understand from where does the no. 27 comes from?
    Plz help..

  17. If you get problems with the r3, always try to replug the usb cable and restart the flip software

  18. Hi, I am wondering, any chance to get this to work for Arduino Pro Mini?

  19. when come arduino joystick hid interface code, ?
    need all 64 button(toggleswitch) and encoder inbut all maximum what can adding.
    and all analog inbut second board.
    or all button max what can adding one arduino board, second board have all encoder/rotary what can adding and thirth board have all analog(potentiometers)what can adding board.
    neew my game special joystick
    who make.???? i no can make im newbie but need thats fast.

  20. nice post, saved a project of mine. thanks!

  21. Curtdissel

    Does anyone know what keyboard table is used?
    http://www.usb.org/developers/devclass_docs/Hut1_11.pdf
    i tried using the table from pages 54-56 but the keys do not match up
    I would write a 4 to the buffer and get spaces when I expected an A.

    • Curtdissel

      I solved it. What had happened was was that I thought the same characters that appeared in the com screen would also be the output as a keyboard. I now know that to be false.

  22. Curtdissel

    If I desire to press three keys at once like alt-control-delete.
    what is the best way to handle that?

  23. Jordan Rejaud

    Hullo, I had some trouble getting your instructions to work with the Arduino r3 so I wrote this little guide:

    How to set an Arduino R3 into DFU Mode and then into a USB keyboard

    If using Arduino R3 then you don’t need an SMD Edition, that is just for the older versions!

    XX Have your computer recognize an Arduino as a USB keyboard XX

    First you upload your code to your Arduino using the regular Arduino IDE, nothing fancy.

    Get the Arduino into DFU Mode (See instructions below)

    Erase, flash, reset and “start” the KeyBoard Hex

    Plug cycle Arduino (This means uplug it, wait a few seconds, then plug it back in again)

    Tada! If you did it correctly then your computer should recognize the Arduino as a keyboard and not an Arduino!

    XX Changing the code on your Arduino once you’ve “turned it” into a keyboard XX

    If you want to change the code running on your Arduino (the chip inside it, technically) then keep reading.

    Plug Arduino into PC

    DFU Mode, Erase, flash, reset and “start” the Arduino Hex

    Plug cycle Arduino

    Computer should recognize Arduino as an Arduino and you can use the IDE to upload your code

    Plug cycle Arduino

    DFU Mode, Erase, flash, reset and “start” the KeyBoard Hex

    Tada! If you did it correctly then your computer should recognize the Arduino as a keyboard and it should now run the new code that you uploaded to it.

    XX Get into DFU Mode and have FLIP talk to the arduino XX

    Download and install FLIP

    Download the Arduino hex files (this file will have your computer recognize the Arduino as an Arduino when you plug it in) and the usb keyboard hex (this file will have your computer recognize the Arduino as Human Interface Device Keyboard when you plug it in)

    Plug in the Arduino to your PC

    Short the top 2 pins (the ones closest to the reset button) for 1 second, the device manager should no longer be able to recognize the Arduino that you just plugged into it and an unknown device will appear

    Open FLIP, set the device to ATMega16U2 and you should be able to connect to Arduino.

    I hope this helps somebody, cheers :)

  24. I have a school project to make something with the arduino, I went the route of choosing to do keyboard commands to send strings into a game while I’m playing. I have flashed the firmware and loaded the keyboard.hex and tried a couple of the above examples, I have an arduino R1 I have soudered the 10k resistor onto the back for the firmware update. But anytime I upload one of the codes, put the arduino in DFU and upload the keyboard.hex, (I’m only testing everything with one button hooked up.) For the cut, copy, and paste one the cut command stays on the entirer time cutting anything I highlight or closing certain programs (like flip for instance), I used this method and unplugged the arduino and pasted from my keyboard, the text that it cut is there so the cut is functioning but won’t shut off when I’m not pressing the button. Any help would be greatly appreciated the project is due in a couple days and I’m no where close to getting this working, let alone being able to enter a string push a button on arduino and have it paste the string from the code to my game,
    (Short version: The buttons are always read as on constantly cutting text? Don’t know if I’m doing something wrong, it’s my version of the arduino (R1) or the code here is written to be always used. I highly doubt that last one is the case but thought I would add it.)
    Do you need 3 buttons hooked up and I’m just wreaking it by only using one?

  25. Hi there, recently the Arduino Leonardo came out and I wanted to ask if you have tried to flash the Leonardo-Bootloader to the 16u2 of the Uno R3 and if yes if it is then possible to load sketches onto the 16u2?

  26. I get the random keyboard to work, but i am not able to get the pushbutton to send a spessiffic char on buttonpress..

    Anyone having trouble with this?

  27. Great tutorial :

    My only headache was I wanted to understand the contents of HID output buffer [0] and I couldn’t find any documented definitions. It must be spec’d somewhere but for others… my current understanding is that the high / low nibble reflect the right/left side of the keyboard respectively and that the following are true

    #define KEY_LEFT_ALT 0×04
    #define KEY_RIGHT_ALT 0×40

    #define KEY_LEFT_GUI 0×08
    #define KEY_RIGHT_GUI 0×80
    (GUI == Windows Key on MS systems)

    … and so my test project now successfully sends “Windows + L” and locks the computer for me. Why? well I always forget and now I have a big red button on the desk.

    Hope those definitions are correct and useful to someone.

    • Oh … should have said:
      * Random Chinese sourced Arduino UNO R3.
      * Using FLIP 3.4.7 on the PC to do the ATMega16U2 programming.
      everything else sourced from material and postings in the tutorial (So all the information you need IS here somewhere)

  28. Hello ı dont know Arduino well but ı try learn ıt.ı want to use arduino on my project. I have Arduino Uno R3 and Arduino Mega 256 ADK. I want to control game wıth push button .ı mean ı want to use push button lıke keyboard lıke these examples. But ı could not run these codes. Must ı change my arduino model or can ı control by these uno r3 and mega 256 adk? can you help me about these subject please? Or can you contact wıth me on thıs e-mail?
    satogluibrahim@gmail.com

  29. wıll some body help to me ?

Trackbacks/Pingbacks

  1. Arduino USB HID Keyboard | Arduino Passion - [...] link [...]
  2. Using an Arduino board as a USB keyboard « freetronicsblog - [...] To find out more and learn how it’s done, visit Mitch’s website here.  [...]
  3. MAKE | USB Keyboard Support with the Arduino Uno - [...] Mitchell recently shared his tutorial on how to use DFU Programmer to update the firmware on the Atmega8U2, which, …
  4. hello world » Blog Archive » Arduino를 키보드로 사용 - [...] http://mitchtech.net/arduino-usb-hid-keyboard/ Category: arduino  |  Comment (RSS)  |  트랙백 [...]
  5. USB Keyboard Support with the Arduino Uno / Cooking Hacks Blog - [...] Mitchell recently shared his tutorial on how to use DFU Programmer to update the firmware on the Atmega8U2, which, …
  6. USB Keyboard Support with the Arduino Uno - [...] Mitchell recently shared his tutorial on how to use DFU Programmer to update the firmware on the Atmega8U2, which, …
  7. Arduino Uno as USB HID keyboard – Part 1 | Doodling With Electrons - [...] went looking for documentation, and found a great post by Michael Mitchell – Arduino USB HID Keyboard. I was …
  8. Arduino USB HID Keyboard -- Arduino Passion - [...] link [...]
  9. L’heure du barbu – podcast Audio – le pilote… « La Grotte Du Barbu - [...] sur HackerLand: le hacking rural - comment démonter un moniteur CRT - la résistance à 0 Ohms - utiliser …
  10. Creating a Pinball Game Controller | Fun with DC Circuits (and phones, and robots …) - [...] as a USB HID device.  It turns out you can flash the arduino with USB HID firmware, discussed here.  That …
  11. Arduino | MuuTTa - [...] Pending to do or for the next version * Buttons without resistors using this page [...]
  12. Arduino and servos | santerifriman - [...] I’ve always wanted to do my own arcade controller and I found that somebody has actually done it with …
  13. Transponder XPNDR - [...] arduino card with new firmware, this way I can use it as a HID keyboard. Interesting stuff here: Arduino …
  14. Nate Beck | Arduino HID Keyboard and the World of Warcraft auto jumper. - [...] a good bit of internet research I stumbled upon a blog post over at mitchtech.net. In this post they …
  15. Choosing an Arduino board | Rodolfo's Blog - […] an Atmega328 chip and is possible to make it act as an USB HID (like keyboard or mouse). But …
  16. Choosing an Arduino board (for this project) | Rodolfo's Blog - […] an Atmega328 chip and is possible to make it act as an USB HID (like keyboard or mouse). But …
  17. HID | wer bastelt mit? - […] http://www.arduino.cc/playground/ComponentLib/Ps2mouse Arduino liest Keyboard (zB. als zusätzliche Inputs) http://www.practicalarduino.com/news/id/151  http://mitchtech.net/arduino-usb-hid-keyboard/  […]

Leave a Reply