Wednesday, 19 March 2014

Wireless Hardware Buttons for a Mobile App - for $20

I tried out an idea: using bluetooth (with the Bluefruit EZ-key) to make some real-world hardware buttons wirelessly control an app on my phone using simple and off-the-shelf components.

I successfully made a wireless hardware interface to a custom phone app without learning a new language, without installing a development environment, without doing any sort of low-level configurations, and only spending about $20.  It was both easier and a bit more difficult than I expected, but in the end it worked just fine - albeit with a couple quirks.

What This Is

It's two buttons that wirelessly control a custom-made app on my phone, using a $20 part and no significant configuration or setup.

This was done because the app in question is a timer app to be used with a timed sports event.  The buttons can be abused and mashed, unlike the phone.  All the app logic (and the time display) is on the phone.  The interactive bits are the wireless (and rugged) arcade buttons.

The system consists of using my Android phone (a Nexus S) as a display and simple timer application.  But instead of needing to manipulate the phone's touchscreen itself to start, stop, or reset the timers, I have some custom hardware doing the job simply, economically, and wirelessly: by using Adafruit's Bluefruit EZ-key.  By closing a switch over here, I trigger something to happen on the phone over there.

The EZ-key is basically a wireless bluetooth keyboard.  But it's small and made to be used in custom electronics.

In my simple test, the hardware buttons use the EZ-key to send a "1" or a "2" wirelessly to the phone exactly as though it was entered on the phone's keyboard (the EZ-key *is* a keyboard, after all, even if it doesn't look like one.)

The custom app on the phone simply uses a form that accepts keyboard input, and decides what to do depending on what gets "typed" in.

This is so far the cheapest, easiest, and simplest way I've found to get an interface rolling between a phone app and real world hardware.   After all, sometimes you just want a button here to do something on your phone there quickly and easily because you have an idea to try, dammit!

The Hardware

The hardware side (besides my Android phone) consists of: Two arcade-style buttons, a 2xAA battery holder with on/off switch, and a Bluefruit EZ-key.

The EZ-key is used in its default configuration.  The buttons are wired to pins 6 and 7 on the EZ-key.  When pin 6 is pulled to ground, it sends a "1".  When pin 7 is pulled to ground, it sends a "2".

The EZ-key is paired to my phone like any other bluetooth peripheral and recognized as a keyboard with no special drivers or handling whatsoever.

After pairing, every time the EZ-key is powered up it will automatically connect to the phone, so making everything work is as simple as flipping the ON switch.

The Software

I used the MIT App Inventor to build a timer application and put it onto my phone.  It's a development environment for making Android applications.

My application works like this:
  • There are two timers shown side by side, one for each player.  They begin at zero.
  • As soon as one player hits the start button, the app goes into standby.
  • 1-5 seconds (random) later, a start beep is played and both timers start counting up from zero.
  • A player stops his counter by hitting his or her button.  The other counter continues until the other player also stops their counter by hitting their button.
  • Both (stopped) times are displayed to allow them to be recorded.
  • Players must hit their respective buttons to reset the times to "0.00".
  • The next button hit restarts the process (1-5 seconds for a Start beep, at which point the timers begin.)

Of course, instead of pressing the buttons on the phone's touchscreen, the real-world (and wireless) buttons are used.  They are far easier (and less fragile!) to mash and hit by players.

About the App Inventor:
The MIT App Inventor (now version 2) is really impressive.  A wi-fi connection to your phone for development means that the app is shown and updated live on your phone as you build it.  And when you're ready to finish it up, it's as simple as scanning a QR code and just like that, the standalone app is on your phone.

Limitations and Getting Around Them

Whenever you mash together pre-made things (possibly in ways they weren't intended) and you don't have low-level control over every piece of it, you get quirks.  This system is no different.

1. Controlling the App with Keyboard input

The App Inventor (with which I made the program for the Android phone) has no way to accept keyboard input as shortcuts to launch functions, so I had to get creative.  How to accept a "1" (or "2") from a keyboard and trigger something to happen?

I solved this by making a text entry form in the app, then colored both the text and the form the same as the background so that it was present, but not visible.  As long as that field has focus, keyboard input goes there.

The program scans for new input to arrive in that field, and when it does, it compares it to "1" or "2" to decide what to do with it, then clears it.

2. Dealing with keyboard auto-repeat

When you press and hold a key on the keyboard, it will repeat.  Whether and how quickly to repeat is up to the OS of the device, they keyboard simply sends when the key goes down and when it comes back up.

My phone has a VERY short repeat delay, so short that if you lingered a little when pressing the button it would go into auto-repeat.  There also doesn't seem to be any way to disable or change it, so I needed another way around the issue.

I solved it by adding an "ignore delay" on inputs from the EZ-key.  When a "1" comes in, additional "1"s are ignored for a little less than a second.  Same goes for the "2"s.  In this application, it makes no difference because the users don't need to hit their buttons in rapid succession.

3. Making sure the keyboard input goes to the right place

The text entry field mentioned in #1 need to have focus, otherwise the app won't receive the keyboard input.

4. While the EZ-Key is connected, the device thinks you have an actual keyboard available

If you're not using the app and haven't turned off the EZ-Key, the device still thinks there is a a keyboard attached.  This leads to things like the screen keyboard not getting launched because it thinks a physical keyboard is being used.  Workaround: turn off the EZ-Key when not in use.

Results and Things Learned

Using the Bluefruit EZ-key to wirelessly send (limited) inputs to a phone or tablet works like a charm.  It works just like a bluetooth HID device (like a keyboard) with nothing special needed to make it work.

Those keypresses it sends can successfully be used to control a custom app, even with a relatively high-level development environment like the MIT App Inventor.  

A few quirks and limitations are present but can be dealt with one way or another.  As long as the system doesn't need to be bulletproof, it can be perfectly functional.