Built a USB foot pedal using the Arduino Uno

(W- and I are planning to go to the hacklab.to open house today. Hope to see folks there!)

This weekend was definitely an electronics hacking weekend. Whee!

It started when I found a three-way foot pedal at Active Surplus for the grand total of CAD 7.50. It’s the kind of foot pedal musicians use to control their equipment: metal, sturdy, and with an odd-shaped connector at the end. I’d been meaning to try foot switches as a way to control my computer (handy for transcription and for using multiple computers). I wanted to get into electronics, as W- enjoyed it so much. I was curious about the Arduino. I figured that making my own foot pedal would mean lots of learning, fun, and relationship-building time. Who knows, I might even get a productivity boost out of it.

USB foot pedal, then! I used my Kindle to look up which model of Arduino could be convinced to act as a USB keyboard. The Arduino Uno was the best bet, so I picked one up at Creatron, and W- got one too. With foot pedal and Arduino in hand, it was off to the house to see what I could make from it. First: figure out the switches. I’d forgotten to write down the labels from Active Surplus and the box had no information. No problem. I snipped the ends off the connector, stripped the wires, opened up the foot pedal, and started figuring out the circuit with the help of the 7-segment LED from the lab kit.

Programming the Arduino was straightforward. I’d already played around with debouncing buttons based on the sample code. I extended my code to debounce three buttons. I looked up Arduino USB keyboard resources (http://hunt.net.nz/users/darran/), reflashed the firmware on the USB chip (atmega8u2), looked up the USB keycodes to send, and wrote the code. I set it up so that left sends PageUp, right sends PageDown, and forward sends F13.

To clean up the circuit further, W- and I went to Active Surplus for the second time that weekend. I bought some headers so that I could solder the wires to them and slot them neatly into the Arduino Uno. I ran into people I know, and I found myself directing them towards the components they were looking for. I think we might be spending too much time at Active Surplus. ;) (But it’s fun!)

During the bike ride back, I was thinking about how to make the foot pedal even more awesome. W- had suggested differentiating between short and long presses, so I worked on that. I started getting confused with the different flags and variables I was using. I redid it as a finite state machine, and that was so much easier to write. (By golly, I did get to use that after all.)

So now I have a foot pedal that cost me around CAD 36.50, plus the time I spent learning how to make it. It doesn’t require a driver. It pretends to be a normal keyboard. Because I’m using function keys that don’t conflict with anything on my keyboard, I can use AutoHotkey to translate them to whatever I want: other keys, sequences of keys, commands, even context-sensitive shortcuts. I don’t have to reflash my firmware to change my keyboard settings – I just reload my AutoHotkey script.

It’s awesome. I’ve used it to flip through an e-book while eating lunch. I’m looking forward to using it while transcribing my presentations. I might remap it to other functions while drawing or programming.

One of the limitations is that the long presses can trigger key repeats. This is handy if you’re mapping it to something like down-arrow, but not so handy if you’re trying to use it as a keyboard shortcut prefix. I’d like to figure out how to control key repeat and key delay on a per-keyboard basis. If I can’t, I might either figure out how to selectively debounce the keys in AutoHotkey, or have a toggle that controls whether keys repeat.

Not at all bad for a weekend hack and my first electronic creation! I’ll ask the Powers that Be at IBM for permission to release schematics and code. (Ah, paperwork.) The circuit is basic (umm, switches), and I’m sure people will point out lots of ways it can be improved. In the meantime, here’s a picture:

C360_2011-08-21 22-16-23

Left: Foot pedal (it can rock forward or to either side), middle: really, really long USB printer cable (will replace with shorter one soon), right: Arduino Uno with the cable wired in and the program loaded.

I’m looking forward to catproofing it in my new project box. Not that anything can really be catproof in this house, but at least I can remove the temptation of wire strands and LEDs.

  • Doug

    Curious, you did this over the weekend and yet you have to ask IBM for permission? Are you using IBM Arduino code? Puzzling…

  • http://johncohn.org john cohn

    Sacha,
    You are my hero squared.. I saw the post about the cartoon and loved it.. then I come to your site to see that you’re doing arduino hacking.. you are my favorite nerdette ! Hope all is well with you !
    -jc

  • Pierre

    It sounds like you had a lot of fun with this! If repeated keystrokes are an issue, can you simply use the switch edges to trigger the key-outs? (It might interfere with the debouncing, granted.)

    In the framework of an FSM, you can make switch activation enter state N, which transmits the character and automatically jumps to state N+1 (depends, I guess, on whether you’re dealing with synchronous or asynch FSM), in which it sits until the switch is released (without generating output).

    This is all assuming that you don’t find any per-keyboard configurations for key refresh rate (which I have never heard of, but which would be a cool thing to have!)

    -Pd

  • http://sachachua.com Sacha Chua

    John: All is fantastic! =) You must have tons of good-funny stories about IBM. I’d love to hear them. I don’t want to go down the cynical-trash-the-corporate-life route, so little bits of joy are much appreciated.

    Pierre: I use state transitions to send key presses, so yes, I’m using the edges. =) I detect short presses and long presses. For long presses, I send keyDown after the long-press threshold, then I send keyUp when the switch is released. Windows automatically fills in the repeat rate, though. An easy way to work around this would be for me to send keyUp after a predetermined period and then go into a new long-press-wait state. If it gets on my nerves, I might make this a toggleable mode, so that I can choose to either generate multiple keypresses or just one. Fun hacking!

  • Pierre

    Out of curiosity, what is the purpose of having a long keyDown – keyUp interval, if not to have Windows fill it in with a repeat rate?

    (Oh wait… modifiers, like Ctrl and Alt… okay, got it. I’m just a bit slow on the uptake, sometimes. ;)

    It sounds like it would definitely make sense, depending on the key being sent, to have the choice of one vs. multiple keypresses. But doesn’t that just translate to long vs. short presses on the switch? Maybe I’m missing something here. I’m going to blame sleep dep. ;)

  • http://colah.ca Christopher Olah

    As I said at HL, this is awesome! I’m kind of tempted to make my own…

    Also, thanks for telling me about autohotkey. Looking for Linux alternatives has revealed what may be more powerful possibilities than XCompose.

  • http://www.brockboland.com Brock

    Very cool! I’ve always wanted to learn more about using Arduino – I’ve never really done any kind of hardware hacking, and it’s the kind of thing I’d love to try one day.

  • http://sachachua.com Sacha Chua

    Doug: IBM’s open source participation guidelines require us to get approval before we contribute any code, even if it’s on personal time and it doesn’t use any of IBM’s resources. For things like this or my Emacs snippets, where there’s obviously no work stuff involved, a quick e-mail to my manager usually suffices. I really want to contribute work-related code as well, like our changes to Drupal modules. There’s a lot of paperwork for that sort of stuff, though. =|

    Brock: Totally not scary. The Arduino makes hardware hacking fun and easy.

    Christopher: It’s surprisingly useful. I keep finding new applications every time I sit down with it.

    Pierre: I was thinking along the lines of being able to tap out something like Shave and a Haircut and have that translate into an Emacs keyboard shortcut (F16 F13 F13 F16 F16?), but the keyboard repeat can throw an unknown number of long-presses into it (ending up with something like F16 F16 F13 F13 F16 F16 F16). Oh well!