mtnwestruby: Ruby USB

mtnwestruby: Ruby USB by Michael Hewner
16 March 2007

Nerds love to customize their software — their shell prompt, adding vim plugins, emacs, etc. After a while, they run out of things to customize. What do they do now? Customize USB hardware!

Ruby USB is about fun, about controlling USB devices using Ruby. No
one paid him to work on it. USB devices are self describing. You can even build
your own USB devices, which has nothing to do with Ruby. The most interesting
USB spec is the one for Human Interface Devices. For HID, the device sends a
description of the format of the data that it’s going to send and what it means
— before it actually sends the data. No reverse engineering necessary!

Ruby USB simplifies the interpretation of the meta-data coming from a USB
device.

mouse_interface.all_input_usages => [Button (9)::Button ...]
keyboard_interface.all_input_usages # will list ever key available on the keyboard

Michael did not write libUSB; his Ruby library merely uses it. It supposedly
supports all UNIX operating systems, although he’s only tested it on Linux.

Lessons learned:

  • Don’t write the USB HID parsing library in C++ and patch it into Ruby — it’s too much work. He should have written it directly in Ruby.
  • Write unit tests.

AVRUSB: Build your own custom USB device — requires that you have a soldering iron and an AVR microcontroller.

Evdev uses the linux-level USB device layer to let you talk to USB devices. It’s easier to use, more rock solid, but doesn’t let you do as many cool things.

Q: Is Ruby USB ruby-thread safe?
A: Haven’t tested it. There are probably some bugs.

Q: Do you have the ability to send output to USB devices?
A: He’s working on it. It’s almost ready.

Q: What’s the craziest thing you’ve done with Ruby USB?
A: Glued two keyboards together. Made one work for Vi insert mode, and one for Vi command mode. It didn’t work out well because he would frequently type on the wrong keyboard, and because it was too large to fit on his lap comfortably.