Wednesday 21 August 2013

Samples and API: getting started

Several people have already received their samples. I've got more requests about samples, so I think about going for a short pick-and-place assembly run. Hand-soldering is OK for 1-2 prototypes, otherwise it just takes way too much time. Currently I'm waiting to get quotes.

Here's a simple "getting started" guide:

Device Manager (InputStickUtility):

To use InputStick you have to install DeviceManager app on your Android phone.

  • Make sure that "allow installation of non-market applications" is checked in your devices settings.
  • Copy DeviceManager.apk to your device and install it.

Pairing with InputStick:
  • Plug InputStick into any USB port in order to power it up.
  • Run DeviceManager, if Bluetooth is disabled it will ask you to enable it. 
  • Manage devices -> Add device -> Discover device -> Select device form the list -> Add device.
  • By default it will be named "Dev-00" and set as "Home", however application will ask you if you want to edit this.

Dialog settings:
  • Always ask: each time you will be asked to manually select InputStick device that you want to connect to. Use this if you want to be sure that no application will be able to connect to InputStick without you knowing.
  • Ask when more than 1 [Default]: you will be asked to select device only when more than one InputStick is paired with your phone. Otherwise it will connect automatically.
  • Never ask: you won't be bothered with dialog. If there is more than one device paired, it will attempt to connect to the one marked as "Default device".
Toast settings:
  • Show all - show all toasts, useful mainly in my case.
  • Show important - show only important toasts, useful for application developers.
  • Show none [Default] : DeviceManager won't be displaying any Toast messages.
Status Bar Notifications:
  • Enabled - notification will be displayed when InputStick device is in use.
  • Disabled - no notifications will be displayed.

Demo apps:

Use Connect/Disconnect button, exact behaviour depends on configuration of DeviceManager.  If it is the first time that you are using your InputStick device you will be asked to enter PIN code (1234), unless you have already paired it manually.

BUG: if attempt to establish Bluetooth connection fails (InputStick not plugged in, out of range etc), pressing "Connect" again will do nothing. You have to kill the app and try again. Next API release will solve this issue.

Depending on USB host, OS, and settings it may take some time to detect new hardware and install drivers.  During this period you won't be able to use application, even though it may appear to be ready. Next time, this should be much faster (OS will recognize the device using PID/VID pair).

API & Demos:

Import InputStickLibrary project into Eclipse:

  • File -> Import -> Existing projects into workspace -> browse -> select InputStickLibrary directory -> check "Copy into workspace" -> Finish

Depending on your ADT version you may get some error messages, in such case go to:
  • Project Properties -> Android -> Select build target -> OK
  • Android Tools -> Fix project properties
This should fix all error messages. Do the same for demo projects.

Starting new project:

  • Create new Android project. Choose minimum SDK > 2.3. 
  • Project Properties -> Android -> Add -> Select InputStickLibrary -> OK

Using API in your project:

Let's take "HelloInputStick" project as an example. This simple app uses USBKeyboard class to type:

Hello world!

This version is a little bit different from the one posted some time ago. Comments should explain everything. (GitHub)

For other device classes see: this post

Friday 2 August 2013

Project update


Current project status:
  • Bootloader: finished.
  • Firmware: works :) (can be upgraded via Bluetooth if necessary).
  • API: works, but needs some improvements.
  • Applications: no changes here, first I have to finish dealing with the API.
 New features:
  • Storing device configuration in flash memory.
  • Storing USB reports in flash memory.
  • OnDisconnect event.
  • Resuming USB session.
 Upcoming features (rather low priority):
  • AES128 encryption.
  • data compression.
Production & availability:
  • I should have some samples available next week (hopefully on Monday).
  • Indiegogo campaign as a form of pre-order?
  • EMC testing (this and all CE related stuff will be covered someday in a separate post).

OK, now if anyone is interested in details:

Storing device configuration in flash memory:
First, I want to remind you how InputStick behaved some time ago:
  1. Plug InputStick into USB port.
  2. Run Android application.
  3. Connect to InputStick.
  4. Configuration data is uploaded.
  5. System enumerates InputStick as some sort of USB device (depending on the configuration).
  6. Do stuff.
  7. Disconnect.
Now, some real-life testing revealed following problem:
Device enumeration (step 5) requires some time. Usually it takes, just a few hundreds milliseconds, so you won't even notice any delay, but in some scenarios this can take even several seconds. Example: Windows recognises new device, but even though it is a standard HID keyboard it attempts to search for a driver using Windows Update, what may take some time in case of slow Internet connection. At this moment user has already started Android application, so he/she has to wait for
enumeration process to finish. And most of us don't like to wait... If you once again take a look at steps 1 - 7, you will see that this would be less inconvenient if InputStick was able to start enumeration earlier, preferable right after plugging into USB port. So I came up with following solution: user can store device configuration in microcontrollers flash memory (using DeviceManager app), so it can begin enumeration immediately. In such case, it should be ready to go, even before user runs application. Of course this is optional, so if you are going to use InputStick with single PC, there is no need to do that, however it may be really helpful if you often use different PCs (at work? at school/university?).

Storing USB reports in flash memory:
Now, if you can store device configuration in flash, why not add some USB reports? This allows to execute some actions, without having to use Android application. Example:

Device configuration: generic USB keyboard
USB reports: TrueCrypt password followed by "Enter" key.
so as a result such configuration turns InputStick into keyboard that automatically types my  system partition passwords and allows Windows to boot. What if, at a given moment I don't want it to type my password? For that purpose I've decided to add timeout feature: wait, let's say 10 seconds for incoming connection, if nothing connects during that period, put reports into queue. The question, if storing system partition password this way is a good idea is another thing, this is just an example. Just like in previous case, this is purely optional, I just think that in some cases such feature might be useful.

OnDisconnect event:
Imagine following scenario: user uses RemoteController application, and presses "Enter" key. This sends two USB reports: press Enter key, release enter key. Now, what happens is smartphone crashes or battery runs out after first report (press) is sent, but before second one (release)? It will result in Enter key being constantly pressed. And you really don't want that to happen, especially if you deal with money. This can be partially solved using InputStick API: send such reports only in one transaction, so either both are received or none. But if we want to allow application to press key and hold it for some indefinite period of time, then if something unexpected happens, it will stay like that forever (or at least until InputStick is removed from USB port).
If connection is unexpectedly lost it would be ideal to send USB report which releases all keys. So here's another new feature: you can upload few USB reports which will be put into queue in case if connection is unexpectedly lost. Usually it will be something like releasing all keys, buttons, setting axes to 0 (gamepad) etc. but you can get more creative here, for example: send Win+L combination to lock PC (Windows) if a smartphone gets out of InputStick range.

Resuming USB session:
New firmware allows to resume session, so the device does not need to go through enumeration process again. In case of most HID devices, you can simply disconnect and leave it enumerated, then connect again after some time and resume activity. When session is resumed, InputStick API asks the device to send all latest output reports and information about processed USB requests. This allows to get latest state of the device. Example: USB keyboard class will get information about state of NumLock, CapsLock and ScrollLock LEDs (most recent OUT report) as well as selected protocol (most recent SetProtocol request). In case of devices like simple mouse (without scroll), this step can be skipped, since there is nothing that influences such device.

AES128 encryption:
Although Bluetooth connection is already encrypted, I decided to make some minor changes in communication protocol, which will allow to implement additional layer of encryption later on. So at this moment it is just an idea.

Data compression:
In case of some USB reports, like for example keyboard, there are many bytes which are mostly zeros, so even very simple compression method will allow to reduce payload size by >50%. Because data throughput is heavily limited, this may be a good idea, but just like in previous case, at this moment I'm not going to implement this feature yet.

I hope to have several samples available on Monday. Since firmware and applications are still in beta, I think that samples are mainly for Android developers. Without fully functional apps InputStick will be of little to no use for other people.

So, I think about (finally) starting Indiegogo campaign this month. My first attempt at making a promotional video wasn't too impressive, so I need to give it (at least) one more try. Also, I have to carefully consider all factors, like components prices at different quantities, taxes, shipment rates and so on.

EMC testing:
Recently I've been able to make some quick EMC tests. It looks like current version of InputStick should be able to pass all tests required for CE certification.