Creating a Serial to USB driver using the Android USB-Host API

Lately we have received many concerns about using the serial interface on Android (Honeycomb with USB-Host). The way to usually communicate with a USB-Serial device in Linux, is to create a virtual serial interface and use it like a normal serial interface. For instance if you connect an FTDI controller via USB, a device /dev/ttyUSBX will be created.

USB-Serial Connection connects streams to Bulk Endpoints

However, behind the scenes you are actually communicating with the device using plain USB Bulk transfers. This job is done by the USB-Serial driver for you (ftdi_sio for instance). If you like to avoid using the kernel driver for some reason you can do this by using a library based on libusb called “libftdi”.

If you look at the source code you will notice that this library manages the connection (depending on the chip type) to the serial controller. Part of this task for instance is resetting TX/RX or setting the baudrate, which is not entirely trivial as it turns out.

Reading data is pretty simple (if your IN packet returns more than two bytes there is data ready). While when sending data you have to be sure not to write more than the max packet size defined by the controller. For details see the source code of libftdi.

Looking at Android there is a core problem with serial devices. As shown in a previous article it is pretty complicated to get started with building the driver. However, the even more painful part is, that there is no API-featured way to receive permissions for the /dev/USBX device node! So root is required.

But Hey! With libftdi, or it’s implementation it is now possible to write your own driver using the Android USB Host API. In the attached example application a connection to a VNC2 Controller is opened and each seconds one byte is transferred. For the example LEDs on the board are toggled. Using the Bulk OUT EP a rs232 “write” is emulated.

Download the Android source
Note that you should change the VID_PID String according to your device “VVVV:PPPP”.
Also note that if you would like to test if this works on your computer you should first remove the ftdi_sio driver using:
$ sudo rmmod ftdi_sio.

Debugging on your Ubuntu machine:
It’s probably much easier to debug on your workstation. Recently I found pyusb pretty helpful:
$ sudo apt-get install python-usb.
Here is a python script that will get you started: main.py.

Honeycomb Tablet optimized version of the Android Oscilloscope

The ultimate goal of our Bachelors Thesis one year ago was to deliver a “market-ready” version of our oscilloscope project where you can just install an app from the market and connect the oscilloscope over USB.

Before the “Tablet Age” our idea was to set up the OTG port of a phone for host mode. However, this requires rooting the phone as well as adding a voltage supply to the connector. Not a very elegant solution.

When the first tablets with honeycomb arrived (3.0) we managed to use the host port on a rooted device to get our oscilloscope working. Still, root was required.

With Honeycomb 3.1 it was not only possible to acquire permission of the USB device it also became possible to program USB with the Java API rather than to go native with libusb.

Therefore we have written a tablet optimized version of our oscilloscope. With the all new user interface comes the ability to connect to our USB oscilloscope. You can get the application from the Android Market with your 3.0 and up tablet. Get the source code: HoneyOsciPrime.tar.gz, or the APK HoneyOsciPrime.apk. You can always download our Layout Files here and build your own oscilloscope or contact us for support.

Acer A500 running OsciPrime
Screenshot of the new Honeycomb OsciPrime App

Creating a remote Scroll Wheel for your Linux Machine using Android, Bluetooth and uinput

Scrolling long documents can be tiring for your index finger on a mouse wheel or on a touch pad. What if you could use your phones touch screen to scroll a document on your computer? While maybe not the most ergonomically solution it may well be a good example of how to work with bluetooth, uinput and Android.

Setup
Android Phone ( >= 2.1)
Ubuntu Laptop with Bluetooth
Two great Tutorials:
Bluez: http://people.csail.mit.edu/albert/bluez-intro/x604.html
uinput: http://thiemonge.org/getting-started-with-uinput

Concept
The application consists of two parts:

  • A client side on the phone that serves as touch pad to scroll.
  • A server part on the computer that receives commands from the phone and emulates scroll movement for uinput.

The Client is a simple Android Activity spawning a Bluetooth Thread. Touch events then result in a Bluetooth packet that tell the server if the user moved up or down. The source code is very straight forward; only Thread synchronization is a bit tricky as well as the way how the application is stopped (locks etc.).

The Server application connects the world of Bluetooth (RFCOMM/SDP) with the uinput event input system. Basically the server registers an SDP entry and then listens on an RFCOMM channel for incoming connections. As soon as a connection is established a new input device is created and scroll events are sent. Note that you probably need to be root (or use sudo) on the Linux machine to feed uinput new events.

Instructions

  • Pair your Android phone with the Linux device
  • Start the server on your Linux device: $ sudo ./btserver (make sure BT is turned on, else there could be a segfault -> working on that)
  • Install and start the app on the phone. In the menus select your Linux device.

Building Dependencies
To build the dev-libbluetooth package was necessary on our Ubuntu machine.

The code is available under GPL. Have fun playing around with it 🙂
Note: It’s very straight forward to create a remote control for your Linux machine with the sources. Key presses can be emulated very easily with uinput.

Source Code
Android Sources
Android APK
Server code for Linux
Our App on the Android Market

Leave a comment if you like what we did or have some improvements 🙂

How to programmatically remove/hide the system bar in Honeycomb (requires root)

Without the system bar it is almost impossible to control your Honeycomb tablet. Since no hardware control buttons are enforced for the tablet the system bar is the only way to control your slate.

However, if your application incorporates a way of removing the bar and on leaving restarting the bar there is no reason why not to support such a feature.

The easy part: Restarting the bar

Restarting the bar is pretty simple, drop to a shell and start the service using the “am” command:
# am startservice -n com.android.systemui/.SystemUIService

The difficult part is to shut it permanently down. One way is to navigate to the application settings and shut it down with the “force close” button. However, attempting to kill the process with

# killall com.android.systemui

will remove the bar for a few seconds. Sadly, it will return eventually since in the applications manifest file the “persistent” parameter enforces the system to restart the service unless it is shut down properly by the “system” user itself.

The following magic line will shut down the bar permanently if executed as root:

# service call activity 79 s16 com.android.systemui

What it does is sending the Activitymanager a shutdown signal for the systemui service.
This method was tested on an Iconia A500 with Android 3.01; although it should work with other devices as well (since the source code that we use is common).

Putting it together

To remove the system bar from your application create and execute a process:

Process proc = Runtime.getRuntime().exec(new String[]{"su","-c","service call activity 79 s16 com.android.systemui"});
proc.waitFor();

To restore the system bar use the following code snippet:

Process proc = Runtime.getRuntime().exec(new String[]{"am","startservice","-n","com.android.systemui/.SystemUIService"});
proc.waitFor();

OsciPrime an Open Source Android Oscilloscope

Today we are releasing our first draft of the new Android Oscilloscope called OsciPrime.
We added a bunch of new features such as:

  • Trigger Offset
  • Signal Offset
  • Cursors for measurement
  • Performance Improvements
  • Running on Beagleboard with Rowboat Gingerbread

The Application is going to run on your phone as well. Although at the moment it requires you be able to record mono at 44100 [Hz] to use Audio.
You might also have to adjust measurement units in the source code.

We packed also libusb if you want to deploy the app on the Beagleboard directly into the APK.

Enjoy 🙂

Download the Source Code

(hint: You can open the menu using the menu button in the application, press once more to close again)