Stokes’ ProjBlog

A journal documenting innumerable, mostly terminally in-progress undertakings. Nerdiness abounds.

 

Check out my (Atari key-)Pad, Part 2: HID Hacking September 9, 2013

Filed under: The Atari Keypad Project — Stokes @ 12:05 pm

Modifying the HID APIOnce I figured out the hardware inside the Atari CX85 keypad, all that was left was the software. And by “all that was left,” I mean the remaining 90% of the work. Not long ago, getting a microcontroller to emulate a USB human input device for a prototype would have been an ordeal. With the introduction of boards like the Arduino Leonardo, however, this is almost as easy as writing any other Arduino sketch. Almost.

For some reason, the standard Arduino library offers only limited keyboard emulation. You can ‘print’ characters as key presses, but you can’t send specific key codes: you can send the character 9, which comes out as the 9 key at the top of your keyboard, but you can’t send the number pad 9 key. This can be easily fixed, but it requires modifying part of the Arduino’s standard library.

The method that sends raw key codes is private — that is, only available to other parts of the library, not the user. This is easily fixable, however, by modifying the standard library. On the Mac, the location of the file is (by default) /Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/USBAPI.h; it will have a similar path on other platforms, at least from hardware/ on.

To enable the ability to send low-level keyboard codes, just swap lines 126 and 127 in that file, so they read like so:

Note that this will make the sendReport() method available on an official Arduino board, but other boards may have their own version of USBAPI.h that will also need changing. For example, the version for SparkFun’s ProMicro boards is located in ~/Documents/Arduino/hardware/SF32u4_boards/cores/arduino/. Again, that’s the path on the Mac; it’ll be somewhat different under Windows or Linux.

Exposing sendReport() is only part of the solution. If you look at the method’s signature, you can see that it takes a KeyReport pointer as an argument. To generate the KeyReport, I cribbed some code from someone else’s project, namely their sendKey() function.

Ultimately, I didn’t use their sendKey() entirely verbatim, but enough so that credit is due.

My implementation is next.

 

Leave a Reply

You must be logged in to post a comment.