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. 🙂
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)
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
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 (
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…
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):
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… ¬¬