Making the Arduino act like a keyboard

The keyboard is a common and (relativily) simple device to understand, create and test everything around the USB HID. This is useful to build the circuit (hardware part), a basic software to the chip and is the first test to make an HID (Human Interface Device) device using the Arduino. There is the first pratical work for this project. 🙂

The necessary tools is based on the v-usb project, a “software-only implementation of a low-speed USB device”. To use if friendly with the Arduino, there is a port called vusb-for-arduino.

Before install it, is necessary download the Arduino IDE at least version 1.5.5 (there is a veta version for now). This is very important because there is a bug with the version 1.0 of the IDE and compiler.

The next step is decompress the downloaded file and copy the 3 contentent folders from “libraries” to the “libraries” folder inside Arduino IDE. There is able the “Usb*” options inside the “Sketch > Import library” menu of the IDE. Is possible to test the compiler and libs by compiling the example code (on the “File > Examples” menu). There is what you need to install for now.

The hardware part need some (cheap) components (available on eletronical stores):

  • 1 USB cable (will be necessary cut it)
  • 2 3.6V Zener diodes
    – must be rated at 0.5W or less, 1W won’t work
    – I used 3.3V Zener diodes and it works as well
  • 1 2K2 resistor (red-red-red)
  • 2 68R resistors (blue-gray-black)
  • cables for the breadboard
  • 1 push button (and a resistor) (for tests)
  • 1 LED and a resistor (for tests/debug, if are not using the LED from the Arduino board)

To assemble the circuit, follow the image:
V-USB Schematic for Arduino
Special atention to the correct side of the diodes.

If a USB cable are used, the colors have standards meanings:
USB-B pinout

Or, if you are using a USB-B pug:
USB Cable Wiring(colors)

More information about hardware parts and the project are available on Arduino to Excel using V-USB and Virtual USB Keyboard.

After that, add the button following the instructions from Arduino website, using the pin 12 (is you use other pin, change it on the source code). Do the same for the LED into the pin 13 (if the board doesn’t have one). There is to simple to put the instructions here. 🙂

Next step is code the software to control this USB interface.

Firs of all, a caveat: the Freeduino and the Uno use an Atmega328P. All chips of “p” series uses a different interruption for the v-usb code. If you simple get the example code, you’ll get some crazy USB error messages (on /var/log/kern.log or dmesg, like:

kernel: [11519.185369] usb 2-1.2: device not accepting address 33, error -32
kernel: [12101.080142] usb 2-1.2: device not accepting address 37, error -71
kernel: [11511.911788] usb 2-1.2: device descriptor read/64, error -71
kernel: [11518.601621] usb 2-1.2: device descriptor read/64, error -32
kernel: [12749.360912] usb 2-1.2: device descriptor read/all, error -32
kernel: [12815.218855] usb 2-1.2: device descriptor read/8, error -32

To solve this, is required to add to the code, before the #include "UsbKeyboard.h" line, a define:

#define USB_INTR_VECTOR INT0_vect

After that, the code is the same of the examples from the library. The minimum code is available on this gist. Plugging the new interface (DO NOT PLUG BOTH CABLES AT SAME TIME), the kernel (dmesg or tail /var/log/kern.log) shows some messages:

[38725.703573] usb 2-1.2: new low-speed USB device number 91 using ehci-pci
[38725.805027] usb 2-1.2: New USB device found, idVendor=4242, idProduct=e131
[38725.805038] usb 2-1.2: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[38725.805043] usb 2-1.2: Product: UsbKeyboard
[38725.805048] usb 2-1.2: Manufacturer: rancidbacon.com
[38725.809476] input: rancidbacon.com UsbKeyboard as /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0/input/input28
[38725.809600] hid-generic 0003:4242:E131.000D: input,hidraw0: USB HID v1.01 Keyboard [rancidbacon.com UsbKeyboard] on usb-0000:00:1d.0-1.2/input0

If there appear, there is ok for now. The final test is add a button and send a key pressing it. The code is available on this other gist.

With this code, when the button is pushed, is like type “hello world” on the keyboard. There is two little bugs here:
1. If you keep the button pressed, it’s not like keep pressing a button on the keyboard. It could be a problem (if t a player are using the keyboard, he can press and keep a key for some time).
2. The keys are sent twice (at least). But this is not a bug for the v-usb: if you keep the button pressed, this will keep sending the text…

To solve the #1, a change was made adding keyUp and KeyDown methods to the library, forked on GitHub.

The #2, the solution is keep some control variables to identify the press and release events of the button. This code show how it can be done (including the changes on the fork).

Until now, this is how the project looks like (I know, there is too much cables there):

Arduino Keyboard - first working prototype

If you look closely, you will notice the red wire into the ground and the black into +5v. This is because this cable is wrong (but this is specific for this cable) and I lost a couple hours to handle this… ¬¬

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s