-
Notifications
You must be signed in to change notification settings - Fork 355
IOIOLib Basics
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.
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 theAndroidManifest.xml
file found at your project's root, going to the Permissions tab > Add... > Uses Permission > Selectandroid.permission.INTERNET
under "Name". - Make sure you enabled USB debugging on your Android device, by going to Settings > Applications > Development > Enable USB Debugging.
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.
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:
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.
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 a soft reset is very fast. 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 - your application wants to initiate a firmware upgrade. In the future, applications (or IOIOLib) will be able to request an 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 hard reset is performed by calling: ioio.hardReset();
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 inonPause()
of anActivity
. - 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 theopenXYZ()
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 theioio_
field as itsIOIO
interface. - Implement the
loop()
method, which gets called repetitively as long as IOIO is connected. It should use theioio_
field as itsIOIO
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
.