Skip to content

IOIOLib Basics

ytai edited this page Apr 30, 2011 · 36 revisions

IOIOLib Basics

Overview

IOIOLib is an Android library, which enables your Android application to control the IOIO board. It exposes a set of Java interfaces, covering the various features of the board. When you build your application, IOIOLib gets packaged into your target .apk file, so your application is stand-alone and does not require any further installation on the Android device that runs it. The entire code is pure Java, depending solely on the standard Android 1.5 (or later) framework.

IOIOLib is all documented in standard Javadoc format, and this documentation is intended to be comprehensive and be used as reference while coding. In this User Guide, we try to cover usage of the library from a common-use-cases approach rather than be 100% formal.

The library is organized in several Java packages. The ioio.api package contains all the public API for controlling the IOIO. This is the package your application will be using. Within it, the ioio.api.exception package contains some exceptions thrown by the IOIO API. The ioio.impl package contains the implementation of these interfaces and is not intended to be used directly. The ioio.util package contains useful utilities that may make your life a little easier when writing IOIO applications, but do not provide core functionality. At the time of writing this, this package only contains a single class, serving as a base class for your IOIO-based application, which automatically handles proper connection / disconnection to the IOIO board in response for application events.

If you are not familiar with Android application development and/or have not yet setup your development environment, the IOIO Beginner's Guide page may provide useful information.

Obtaining and Using IOIOLib

IOIOLib can be downloaded from this link, along with some other resources.

http://codaset.com/ytai/ioio/source/master/raw/release/IOIO-V10.zip

You probably care only about the stuff that is under software/IOIOLib. We're only going to cover usage with Eclipse here, with the assumption that users not using Eclipse for Android application development probably know what they're doing :)

  • Extract software/IOIOLib to somewhere where you normally want to keep your Android projects.
  • Import it into Eclipse using File > Import... > General > Existing Projects into Workspace..., then choose the IOIOLib directory you just created and click Finish.
  • Reference it from your application project, according to these instructions
  • Make sure your application declares using the android.permission.INTERNET permission. This can set by opening the AndroidManifest.xml file found at your project's root, going to the Permissions tab > Add... > Uses Permission > Select android.permission.INTERNETunder "Name".
  • Make sure you enabled USB debugging on your Android device, by going to Settings > Applications > Development > Enable USB Debugging.

The IOIO Interface

The IOIO interface is the heart of the IOIOLib. An instance of this interface represents a physical IOIO board, and through its methods you can control its various functions, such as reading or writing values to individual physical pins.

Creating a IOIO Instance and Establishing a Connection

In order to create an instance of IOIO, you should use the IOIOFactory.create() method. Simply call: IOIO ioio = IOIOFactory.create(); The call will return immediately, providing you with a valid instance. However, this instance is not yet usable, and any attempt to use it will throw an exception. A connection with the board must first be created, by calling: ioio.waitForConnect(); This call will block until the board is powered, physically connected via USB and establishes communications with your application (if it doesn't, make sure you've got USB debugging turned on).

Once the IOIO is connected, you can start using it (well, that's what you bought it for, probably)! Its various functions are normally accessed via sub-instances obtained from the openXYZ() methods. These sub-instances remain associated with the IOIO instance which created them throughout their lifetime. They all extend the Closeable interface, which simply means your can call close() on them. Calling close() will invalidate the instance on which it was called, and will free and resources (e.g. pins) it used for future use. For documentation on specific functions, please refer to:

Disconnecting

In order to disconnect from the board (automatically resetting its state), or abort an on-going waitForConnect(), simply call: ioio.disconnect(); You can do this, for example, when your application gets paused, or from a TimerTask, if you want to timeout on a connection attempt. The call is asynchronous. The disconnect process is normally very fast, but if you want to make sure all resources have been freed, you can use: ioio.waitForDisconnect(); This call will block until the disconnect process completes. You can also use this call to implement a listener that does something upon disconnect.

From the moment a disconnection occurs, whether due to the client's explicit call to disconnect() or due to a physical disconnection, the instance, as well as any other instances obtained from it, will throw a ConnectionLostException upon every call. A IOIO instance is one-time use. This means that once a connection is lost, the instance is as good as dead. It cannot be recycled. Create a new instance if you want to re-establish connection, and preferably attempt to do some after calling ioio.waitForDisconnect on the old instance, to make sure you are waiting for all resources (such as the underlying network socket used for communication) to be freed.

Resets

There are two kinds of resets, soft and hard.

A soft reset means "return everything to its initial state". This includes closing all interfaces obtained from this IOIO instance, and in turn freeing all resources. All pins (save the stat LED) will become floating inputs. All modules will be powered off. These operations are done without dropping the connection with the IOIO, thus it is very quick. It is generally not a good practice to replace proper closing of sub-instances with a soft reset. However, under some circumstances, such as tests, this might make sense.

A soft reset is performed by calling: ioio.softReset();

A hard reset is exactly like physically powering off the IOIO board and powering it back on. As a result, the connection with the IOIO will drop and the IOIO instance will become disconnected and unusable. The board will perform a full reboot, including going through the bootloader sequence, i.e. an attempt to update the board's firmware will be made. Hard reset is mostly useful for this very purpose - if your application wants to initiate a firmware upgrade. In the future, applications (or IOIOLib) will be able to request and install of ad-hoc firmware on the board. A hard-reset will then enable the board to pick up the new firmware and start executing it.

A soft reset is performed by calling: ioio.hardReset();

Using the AbstractIOIOActivity Utility

Very often IOIO-based applications will have the following traits:

  • A single thread is dedicated to creating the IOIO instance, establishing connection and then controlling the IOIO. This is possibly done while communicating with other threads, such as the UI thread.
  • This thread will be created in onResume() and aborted in onPause() of an Activity.
  • Aborting the thread involves disconnecting from the IOIO or otherwise cancelling an on-going attempt to connect.
  • In this thread, there will be some operations done once right after a connection is established. Typically these will include creating sub-instances of the IOIO object, by calling some of the openXYZ() methods.
  • Then, there will be on-going tasks done repetitively.

While this behavior surely doesn't cover every possible application, it does cover quite a few of them. So in order to save the boiler-plate code for achieving just that, a utility class has been created, called AbstractIOIOActivity, under the ioio.util package. This is simply an abstract class, extending Activity which does exactly what's written above.

It leaves you, the application author, to extend it and provide the following:

  • Create a (possibly inner-) class extending AbstractIOIOActivity.IOIOThread.
  • Implement the setup() method, which gets called once the IOIO connection is established. It should use the ioio_ field as its IOIO interface.
  • Implement the loop() method, which gets called repetitively as long as IOIO is connected. It should use the ioio_ field as its IOIO interface.
  • Let any ConnectionLostException get thrown from either of these methods - it will be caught and properly handled automatically.
  • Finally, implement the createIOIOThread() method, which simply returns a new instance of your thread class.

The HelloIOIO example provided is a good example of using AbstractIOIOActivity.