-
Notifications
You must be signed in to change notification settings - Fork 355
IOIOLib Application Framework
This page will introduce you to some basic concepts of authoring IOIO-based applications, using the utilities provided with the IOIO Java-based software bundle. Regardless of wether you are developing Android applications or PC applications, the IOIOLib Core API is exactly the same and the provided application frameworks share many of the concepts and code. We will cover only the application frameworks here.
Whenever a IOIO application starts, the application framework will determine all the possible connections to IOIO boards. These can be all the IOIO boards that are paired over Bluetooth, certain USB-based connections that can potentially be used, etc. The specifics are platform-dependent. For each such possible connection, the framework will callback a client-provided createLooper()
method, through which the client will typically (but not necessarily) interact with the IOIO board. The client may reject a certain possible connection by returning null
from this method. The IOIOLooper
is a simple interface that allows the client to be notified when a IOIO connection has been established or closed and be provided with context for execution of IOIO-related code outside of the application's main execution context.
For each such a IOIOLooper
returned by the client, the framework will create a dedicated thread, on which the looper methods will be invoked. This thread will have roughly the following logic:
-
Wait for a IOIO connection to get established.
-
Check that the firmware version running on the IOIO is compatible with the IOIOLib version we are running.
-
If compatible:
- Call the
setup()
method of theIOIOLooper
, providing it with an instance of aIOIO
interface for working with the IOIO during this connection lifetime. From this method, the client will typically open I/O pins and do any per-connection initialization. - Repeatedly call the
loop()
method of theIOIOLooper
. From this method the client will typically execute any ongoing IOIO-related tasks.
- Call the
-
If not compatible:
- Call the
incompatible()
method of theIOIOLooper
. From this method the client can report the user of the problem.
- Call the
-
As soon as the IOIO connection is dropped, as result of a physical disconnection or of exiting the application, call the
disconnected()
method. TheIOIO
instance is no longer usable from this method. The framework will also callinterrupt()
on the thread, which the client can use to abort any non-IOIO blocking operations (as the IOIO blocking operations will throw an exception on disconnection anyway).
For convenience, the BaseIOIOLooper
class can be extended, which provides default no-op implementations of all the methods, as well as defines a ioio_
field which will hold the IOIO
instance, as soon as setup()
is executed.
Note that the IOIO API is completely thread-safe, so the client is not constrained to perform all interaction with the IOIO
-derived interfaces through the IOIOLooper
. It is perfectly valid to share the ioio_
instance, or any interfaces created from it, with another thread to use.
The setup()
and loop()
methods are allowed to throw a ConnectionLostException
and an InterruptedException
(as well as any runtime exceptions). Throwing any exception from that will cause the IOIO connection to drop and a reconnection attempt will be made immediately.
The following sections of this page will describe how to create different kinds of IOIO-based applications on different platforms.
This explanation assumes your development environment is setup for developing Android applications and that you have basic familiarity with Android development tools and techniques. If this is not the case, [http://developer.android.com](the Android developer site) has great tutorials and instructions to get you started.
On the Android platform, several types of connections to IOIO can be used:
- ADB over USB. This is the standard connection type, supported on every Android device. It requires you to connect the IOIO board over USB and to have USB debugging enabled on the Android.
- Bluetooth. This is used for a wireless connection. It requires a compatible dongle to be plugged into the IOIO, Bluetooth pairing to be done and the IOIOLibBT library to be linked against your application. See this page for more information. Note that the framework will try to establish a connection to every paired IOIO. Trying to connect to a non-existing device may interfere with existing connection, so make sure to un-pair any IOIO devices not in use.
- OpenAccessory. This required an OpenAccessory-capable Android devices, USB debugging to be off and the IOIOLibAccessory to be linked against your application. See this page for more information.
The IOIO application framework for Android lives in the IOIOLibAndroid package, which is available from the IOIO software bundle or (starting at version 5.05) from the Maven Central repository. The relevant classes and interfaces can be found in the ioio.lib.util.android
Java package. The framework provides utility classes for easy creation of IOIO-based Android Activity
's and Service
's.
To implement a IOIO-based activity, simply extend the IOIOActivity
class and implement the createLooper()
method with your IOIOLooper
logic. Similarly, a IOIOService
class exists for IOIO-based services. Make sure to call the super-class methods (e.g. onStart()
, onStop()
) if you override them. The HelloIOIO
, IOIOSimpleApp
and HelloIOIOService
sample applications demonstrate the usage of these classes.
For advanced use-cases not covered by these utilities (for example if you want your IOIO connection to persist beyond the scope of a single activity, or if you have to have your activity class extend a different super-class), the IOIOAndroidApplicationHelper
class provides a lower-level framework. You should instantiate this class and pass in the relevant Android events, and in turn, this class will callback on your createIOIOLooper()
and on the looper's methods whenever appropriate. You can study the implementation of IOIOActivity
and IOIOService
, which use IOIOAndroidApplicationHelper
under the hood.
For more details, consult the Javadocs of aforementioned classes.
Note: If you're looking for the old documentation of the now-deprecated
AbstractIOIOActivity
class, it is [here](Using-AbstractIOIOActivity-(deprecated)). It is recommended that you switch toIOIOActivity
- the migration process is close to trivial.
Controlling the IOIO board from a Java application running on a PC has been introduced with the release of the IOIO-OTG board and its accompanying software libraries. While mainly intended for IOIO-OTG devices, the original IOIO boards can be used with this library over Bluetooth.
On the PC platform, several types of connections to IOIO can be used:
- USB device. This is supported only with IOIO-OTG boards. In this mode, the IOIO is connected to the PC as a USB device, using a USB A-to-micro-B cable. This IOIO can be powered either from the host PC or from a separate power supply (required if more than 500mA are used). Proper drivers need to be installed INSERT LINK on the host. The mode selection switch on the IOIO must be set to the A (auto) position.
- Bluetooth. This is supported both by IOIO-OTG and older boards (running application firmware V3.x or higher). It requires a compatible dongle to be plugged into the IOIO and Bluetooth pairing to be done with the host. See this page for more information. Note that the framework will try to establish a connection to every paired IOIO. Thus, it is recommended to un-pair any IOIO devices not in use. With IOIO-OTG devices, make sure to use a micro-A connector on the IOIO side, or otherwise to force host mode by setting the mode switch to the H (host) position.
Both kinds of connections expose the IOIO to the PC as a serial device. The framework will use the following logic to decide which serial device(s) to use:
- The user can explicitly set the system property
ioio.SerialPorts
to a colon-separated list of ports. For example, running the HelloIOIOConsole example from command line, may look like this:
java -Dioio.SerialPorts=COM6 -jar HelloIOIOConsole.jar
More than one port is acceptable. In Eclipse, you can set this argument in Run Configurations > Arguments > VM Arguments (and the the -Dioio.SerialPorts=xxx). - It is possible to set the property using property files (TODO: add explanation).
- If the property is not set, the framework will try to open every possible serial port on the system upon start-up. Every port that was able to open will be considered a potential IOIO connection.
The IOIO application framework for PC lives in the IOIOLibPC package, which is available from the IOIO software bundle or (starting at version 5.05) from the Maven Central repository. The relevant classes and interfaces can be found in the ioio.lib.util.pc
Java package. The framework provides utility classes for easy creation of IOIO-based console applications and GUI applications using the Swing library.
If you need a good introduction to Java, Oracle has some great tutorials here, covering everything from learning the language through building and running your applications to advanced topics.
To implement a IOIO-based console application, follow the following steps:
- Create your main class, extending
IOIOConsoleApp
. - Implement
static void main(String[] args)
in your class by creating an instance of this class, and calling itsvoid go(String[] args)
method. - Implement
void run(String[] args)
with your main thread logic. - Implement
IOIOLooper createIOIOLooper(String connectionType, Object extra)
with code that should run on IOIO-dedicated threads.
For a complete example, see the HelloIOIOConsole example, included in the software bundle.
You can also implement applications with a Graphical User Interface (GUI), using the Java Swing library. If you need a tutorial on developing Swing applications, see the official tutorial. To implement a IOIO-based Swing application, follow the following steps:
- Create your main class, extending
IOIOSwingApp
. - Implement
static void main(String[] args)
in your class by creating an instance of this class, and calling itsvoid go(String[] args)
method. - Implement
Window createMainWindow(String args[])
with code to create your main window. For proper cleanup on exit, make sure to setJFrame.DISPOSE_ON_CLOSE
as the default close operation of your window. - Implement
IOIOLooper createIOIOLooper(String connectionType, Object extra)
with code that should run on IOIO-dedicated threads.
For a complete example, see the HelloIOIOSwing example, included in the software bundle.
For advanced use-cases not covered by the above utilities (e.g. if you want the IOIO connection to be established only at a certain state of your application), the IOIOPcApplicationHelper
class provides a lower-level framework. You should instantiate this class and call its start()
and stop()
methods when you want the IOIO interaction to begin / end. In turn, this class will callback on your createIOIOLooper()
whenever appropriate. You can study the implementation of IOIOConsoleApp
and IOIOSwingApp
, which use IOIOPcApplicationHelper
under the hood.
For more details, consult the Javadocs of the aforementioned classes.