Tuesday 14 May 2013

Fast Keyboard

After making some improvements (mainly related to USB reports buffering) it is time to test InputStick performance. In order to do that, I've modified USBKeyboard class by changing endpoint polling interval form 32ms to 1ms. In theory this should allow to send up to 1000 reports per second and as a result type 1000 characters (under some conditions).

First, take a look at this video:


So here's what happens:
  1. application sends Alt+Insert combination, what starts music playback in Winamp
  2. application types 10000 characters
  3. application sends Alt+Home, what pauses playback. At this time Winamp shows 13 seconds elapsed
Now some simple math: 10000 characters in approximately 13 seconds gives 770 characters per second = 46200 characters per minute. Pretty fast and pretty close to 1000 characters per seconds what is highest possible value. I guess that after some further improvements I should be able to reach that value.

Are there any applications for that? At this rate, typing all four digit PIN codes, each followed by "Enter" key (50000 characters) will take approximately 65 seconds. In some real world scenario it probably will be necessary to add some delay between consecutive attempts, and deal with "Wrong Password" messages (for example: press "Enter" to try again). Also, there is an assumption that target will allow for infinite (OK, 10000 will also do) number of attempts.

Finally, some remarks. As you can see the test has been performed on Windows and I'm not sure how different systems may behave. It may be necessary to send additional USB report after each character ("release" key), or separate "Shift+Key" report into two reports: "Shift" and "Shift+Key". This may reduce final performance by two or three times, but still, even 15000 characters per minute is really fast, see: World Records in Typing.

Sunday 12 May 2013

USB Remote Control

Recently I've added support for USB composite devices, what allows InputStick to have several USB interfaces at the same time. This is extremely useful in applications like remote control, where we need mouse and keyboard interfaces working at the same time. I will leave implementation details for other post, which will cover recent improvements in InputStick firmware and Android library. Here I want to focus on Remote Control application. First let's take a look at how opetaing system sees such device:




As you can see there are three interfaces: mouse (USB endpoint 1), keyboard (USB endpoint 2) and input device consisting of consumer control device (system volume and playback control) and power control (USB endpoint 3). Each interface has already been covered in my previous posts. Now let's take a look at Remote Control application (which originally was supposed to be Remote Keyboard application):




I should spend some more time working on the layout, but for now its just a proof of concept. Here you can see it in action:



Just like I've mentioned in the video, there is no need to install any additional software on controlled device. As a physical device it will also work with any modern operating system (Windows, Linux, Mac OS, Android etc) and it doesn't require installing additional drivers, since it uses standard USB HID (Human Interface Device) class. So just like in the video, all it takes is to plug InputStick into USB port and run Remote Control application on your smartphone.


Thursday 9 May 2013

USB Numeric Keypad

Before starting with USB Remote Control application, which combines: keyboard, mouse and consumer control interfaces (more on that soon), I wanted to practise some layout design. That's why I did Numeric Keypad app. I guess that there is not much to say about this app... it allows you to use your smartphone or tablet as a wireless USB numeric keypad and well... that's all.

NumLock is on.
NumLock is off.

Wednesday 1 May 2013

USB Gamepad

Another thing that I have recently implemented is a USBGamepad class. It's very similar to other previously described HID devices. Let's take a look at report descriptor:
 

 
As you can see, my gamepad implementation supports up to 16 buttons and 4 axes. First byte of USB report is always set to 1 (report ID), next two bytes are an array containing data about state of buttons, followed by 4 bytes, one for each axis. Endpoint 1 has polling interval set to 8 ms in order to reduce latency, what is very important in case of a gamepad device. There are following methods offered by this class:
 

 
In order to demonstrate USBGamepad class in action I have prepared simple GamepadDemo app. As you can see there are 8 buttons (multi-touch is supported). Data for X and Y axes is gathered from accelerometer, Z and rX axes are not used. Application sends data every 25 ms, but I guess any interval greater than 8 ms (endpoint polling interval) should be ok.
 
GamepadDemo app.


Devices and Printers

On the screen above you can see that Windows sees InputStick as a USB game controller device. I didn't check this class on any other operating system beside Windows, but if a physical gamepad is supported, then InputStick will also work.

Here's a video of me playing GRID with my phone as a controller (it's a bit difficult to steer when you have camera between yourself and phone) :