2016/06/11

How to turn Arduino Uno into HID Keyboard - Part 1 of 2

This is the first of a two parts series. This part is to provide a brief overview of HID concept and how to prepare and turn an Arduino Uno into a HID device (in this case, a HID Keyboard).

The 2nd part will be dealing with the coding of an Arduino sketch to send keystrokes to the connected PC over the USB port and some other stuff. The 2nd part can be found here.

Brief Overview

The Arduino USB HID keyboard is implemented by sending a 8-byte long "Keyboard Report Buffer" via the USB that connects the PC and the Arduino.

The format of the Keyboard Report Buffer is as follow.


The format of the Modifier Keys (Byte 0) is as follow.



As for keycode 1 ~ 6, they can be found in the Keyboard Scan Codes in the reference section of this post.

Preparing the Arduino and the needed firmware and tools

Note, the instructions below are for Arduino Uno and MS-Windows 8.1.

1. Check the Arduino board for its version and whether the USB Serial chip used is supported by the DFU tool.

Mine is R3 (no need to modify it)

If yours is R1, please follow the instruction here to modify it.

This board is using MEGA16U2

MEGA16U2 is on the support list

2. Download and save the "Arduino-usbserial.hex" in a safe location. This firmware needs to be in atmega16u2 for burning sketch unto the Arduino board using Arduino IDE and USB cable.

Here is the download link.
https://dl.dropboxusercontent.com/u/1816557/Arduino-usbserial-uno.hex

Note,

I think there is a missing Arduino-usbserial.hex in at the below github site.

https://github.com/arduino/Arduino/tree/master/hardware/arduino/avr/firmwares/atmegaxxu2/arduino-usbserial

3. Download a DFU Programmer from http://www.atmel.com/tools/flip.aspx.

Since I already have Java Run Time installed on my PC, I downloaded the one without Java Run Time.


4. Download the Keyboard HID firmware "Arduino-keyboard-0.3.hex" from here and save it to a safe location. After this firmware is written into atmega16u2, the Arduino Uno board will be viewed as a USB keyboard when it's plugged into a PC.


Burning the firmware into atmega16u2

1. Put the atmega16u2 in DFU (Device Firmware Update) mode by briefly shorting the 2 leftmost ICSP headers next to the USB port.


2. Install the ATmega16U2 DFU driver.

Note, the driver needs to be installed for Flip to communicate with ATmega16U2 on the Arduino Uno board.

On the computer, the driver "atmel_usb_dfu.inf" can be found under C:\Program Files (x86)\Atmel\Flip 3.4.7\usb.

3. Launch Flip. Select "Device", then select ATmega16U2 from the list.


4. Left click on the "Select a Communication Medium", left click on USB, left click on Open. The USB:ON indication on the lower right hand corner indicates Flip is now connected to ATmega16U2.


5. Go to File, Load HEX File, and select the Hex file to be written into ATmega16U2.


In this case, I choose to burn the "Arduino-keyboard-0.3.hex".


6. Click on Run to erase the existing firmware (Earse), write the new firmware (Program), and verify the written firmware (Verify) in ATmega16U2.

7. Unplug the USB cable that connects the Arduino Uno and the PC then plug the cable back in again. Go to Device Manager and there is now a HID Keyboard Device under "Keyboard".


Below is the Device Manager screen when a normal Arduino Uno is plugged in. Note that there is no HID Keyboard Device under Keyboard and an Arduino Uno is shown under COM & LPT


To burn the USB Serial firmware back to ATmega16U2 (turn the HID Keyboard Device back to a normal Arduino Uno board), simply repeat step 1 to 7 above except step 5. In step 5, select the previous saved "Arduino-usbserial-uno.hex" instead of "Arduino-keyboard-0.3.hex".

After "Arduino-usbserial-uno.hex" is written into ATmega16U2, close Flip, remove USB cable then plug it back in. The Windows OS will detect it as a new device and look for its driver. Very soon it will recognize it as an Arduino Uno and uses the already installed driver to support it. After that, the board is ready for uploading sketch via the Arduino IDE again.

Note,

Remember to short the 2 leftmost ICSP headers next to the USB port before launching Flip.


After shorting the pins, there will be an Atmel USB Devices in the Device Manager and no HID Keyboard Device. The ATmega16U2 is now ready to be flashed with new firmware.


Reference

Keyboard Scan Codes

The tables below are from P53 ~ P59 of the "USB HID Usage Tables". This document can be downloaded at http://www.usb.org/developers/hidpage/Hut1_12v2.pdf.









DFU Related References

Updating the Atmega8U2 and 16U2 on an Uno or Mega2560 using DFU
https://www.arduino.cc/en/Hacking/DFUProgramming8U2

DFU programming the atmega16u2 on the Arduino UNO R3
http://bartruffle.blogspot.tw/2013/09/dfu-programming-atmega16u2-on-arduino.html

HID Keyboard Related References

List of hex keyboard scan codes and USB HID keyboard documentation
http://stackoverflow.com/questions/27075328/list-of-hex-keyboard-scan-codes-and-usb-hid-keyboard-documentation

HID USB Keyboard
http://stackoverflow.com/questions/24055687/hid-usb-keyboard

USB Device Class Definition for Human Interface Devices (HID)
http://www.usb.org/developers/hidpage/HID1_11.pdf

HID Keyboard Related Arduino Sketch References

Arduino USB HID Keyboard
http://mitchtech.net/arduino-usb-hid-keyboard/

Arduino UNO Keyboard HID part 2
http://hunt.net.nz/users/darran/weblog/faf5e/Arduino_UNO_Keyboard_HID_part_2.html

--------------------------------------------------------------------------------------------------------------------------

HID Joystick Related Arduino Sketch References

Arduino UNO Big Joystick HID firmware
http://hunt.net.nz/users/darran/weblog/15f92/Arduino_UNO_Big_Joystick_HID_firmware.html

unojoy - GettingStarted.wiki
https://code.google.com/archive/p/unojoy/wikis/GettingStarted.wiki

Arduino wireless gamepad (UnoJoy)
https://www.youtube.com/watch?v=cZc-23NjNHY

--------------------------------------------------------------------------------------------------------------------------

Misc. Info.

PPM / CPPM Receiver
http://www.deviationtx.com/forum/3-feedback-questions/1845-ppm-cppm-receiver

Arduino + 2 Servos + Thumbstick (joystick)
http://www.instructables.com/id/Arduino-2-Servos-Thumbstick-joystick/step3/Connecting-the-thumbstick-joystick/

Arduino thumbstick controller
http://www.instructables.com/id/Arduino-thumbstick-controller/

How to Restore the Arduino UNO R3 ATmega16U2 Firmware Using the Arduino IDE
http://www.instructables.com/id/How-to-Restore-the-Arduino-UNO-R3-ATmega16U2-Firmw/

5 comments:

  1. This maybe worth looking at as he seems to be using the 74hc165.

    https://github.com/MrOnak/attiny2313usbkeys/commit/ecefaf02bc5cbb9a9320be89a2cca048e9522420

    ReplyDelete
  2. This comment has been removed by the author.

    ReplyDelete
  3. Wow~ The program looks complicated.. :-)

    ReplyDelete
  4. I'm hoping I have thought of an easier solution but havn't had time to try it yet. Basically looking to set up an array of 24 virtual pins which will map to the output of 3 74hc165's. This should then be sent as a HIGH or LOW to the joy-report in the first part of the void loop(). This will avoid touching the existing hex file. I'm not a coder so this is looking at the problem at a very basic level.

    ReplyDelete
    Replies
    1. I think you are on the right track with your approach....

      Delete