Amarino Embed (a.k.a. OBI)

From SolidStateDepot
Jump to: navigation, search

Amarino-Embed is originally based on Amarino. Amarino was not available on Android Market (before Google Play) when I discovered it in 2011 and could only be used as an external app, through intents. I was building a bluetooth telescope controller in Android and I wanted everything self-contained, in one app with a background service. Hence Amarino-Embed was born. I've used it for several unpublished Android apps including a multiplayer app. The code for Amarino-Embed can be downloaded from github at https://github.com/tenaciousRas/amarino-embed.


Why Use Amarino-Embed

  • Amarino-Embed can be embedded as a background service in your app, or used like the original Amarino, as an application that serves Android intents and talks to an Arduino with bluetooth.
  • Amarino-Embed and its ancestor were created before introduction of the Android Development Kit (ADK) - which had bluetooth capability added in a later release. The ADK bluetooth capabilities are superior to Amarino Embed in some ways, however some may find Amarino Embed easier to use than the ADK because all of the code is up-front, extensible, and editable.
  • Amarino-Embed uses and old bluetooth library that gives it wider backwards compatibility (at least for now).
  • Amarino is not a realistic option for most Google Play publishers - it isn't even available on Google Play, and even if it was user's can't be expected to download multiple applications to get the features of one app...that will never be popular.

On the other hand, the ADK saves a few steps in terms of having an integrated bluetooth library for Arduino, and its communication protocol may be better - I haven't evaluated that. Amarino-Embed supports custom communication protocols but none have been implemented for it yet.

Roadmap

There's a roadmap to migrate Amarino Embed to a new application name, called Open Bluetooth Intents. If Amarino Embed is ever published to Google Play this new name will be adopted, and its bluetooth intents will be registered at openintents.org.


Code Breakdown

A presentation I gave at Boulder and Denver Android Meetup Group meetings in 2011 can be viewed at Google Drive. Also there's a Google Group for support.

Amarino-Embed originally supported builds from both ADT and Ant. I'm not sure if the Ant builds still work - I've been using ADT builds for the project for a while. The ANT build never worked as intended for a standalone JAR distribution, thanks to Android. The codebase is broken into four (4) major applications:

  • amarino-app - at.abraxas bluetooth library
  • amarino-examples - original Amarino samples refactored to work with Amarino embed. Only two examples actually use an embedded Amarino-Embed service, the others just expect the classic seperate app behavior as in the original.
  • amarino-plugins - original Amarino plugins refactored to work with Amarino Embed. I can't vouch for this folder, it compiles, but I've never had a way to test it. I don't believe the plugins concept has ever worked very well in Amarino...
  • amarino - the Amarino library - contains the background service implementation (class) and interfaces you'll need to run Amarino-Embed in your app.

All of the code in the ancestor Amarino was refactored to work with the decoupled service architecture in Amarino-Embed. The classic separate-app behavior was tested when the code was refactored, but has become stale.

RGBLEDPickers Demo

The RGBLEDPickers Demo application can be found in the amarino-examples folder in the Amarino-Embed project. RGBLEDPickers demonstrates how to control the color of 3 RGB LEDs from an Android device. The RGB LEDs are connected to an Arduino using a small circuit that contains a decade counter IC. The Android application starts and immediately connects to the bluetooth device using Amarino-Embed and displays the connection status in the notification bar. This section documents how to install and run the RGBLEDPickers demo application.

Pre-requisites

  • Eclipse IDE
  • Android SDK
  • Bluetooth capable Android device (emulator doesn't have BT support), with Android Debug via USB enabled
  • Arduino IDE (latest version)
  • You'll need to know the broadcast ID of your Android Bluetooth device - this is hardcoded into the demo app.
  • The RGBLEDPickers demo circuit - probably made on a breadboard.

Android

Step 1

Install the requisites. Installing the Android SDK is non-trivial and can take at least an hour. When you download the SDK from Google you'll get the latest version, but you may need to install an older version of the SDK - depending on your Android device. If you want to reduce the time required then determine the OS version on your Android device and use the ADT within Eclipse to choose to download the older version you need, and only that version.

Step 2

Install the OBI sketch into your Arduino libraries folder. The OBI sketch is based on Amarino, but it does not block on reads and uses the newer serial API. I think there's one other bug fix too. If installing the OBI sketch is problematic you can install the classic Amarino sketch in your Arduino libraries folder.

To find the Arduino libraries folder on OS X and Windows:

Step 3

Checkout the Amarino-Embed codebase from Github. Note that this codebase actually contains four (4) projects. The main ones you're concerned with are "amarino-examples" and "amarino".

Step 4

Import the AmarinoApp and RGBLEDPickers applications into Eclipse. See http://help.eclipse.org/juno/index.jsp?topic=%2Forg.eclipse.platform.doc.user%2Ftasks%2Ftasks-importproject.htm. Choose File -> Import -> Existing Projects into Workspace; then choose "Select root directory" - and browse to the folder where Amarino Embed was cloned. Then click OK and you will see a list of Eclipse projects under the root - choose AmarinoApp and RGBLEDPickers.

Step 5

You should find that the RGBLEDPickers application already references the Amarino app as a library project. If it doesn't you'll need to create this reference (see ?). Also, you shouldn't need to add the AndroidBluetooth.jar to your project - that was for older versions of Android library projects and doesn't apply now either.

Demo Circuit

Step 6

Before we launch the project we need to build the RGBLEDPickers demo circuit. The demo circuit consists of a decade counter connected to three (3) sets of NPN transistor and RGB LED. I designed the circuit this way because...I like to misuse electronic components and see if they still work? The intent is to only use three (3) PWM pins on the Arduino to control 3 RGB LEDs (a total of 9 color pins) and still get a decent range of RGB colors. It almost works - kinda - but the colors are a little washed and somewhat coarse.

Slide 16 of the Amarino-Embed Presentation shows a schematic of the RGBLEDPickers demo circuit. Note the connections to Arduino D2 and D4. This schematic was made on some poor CAD software and the pins don't have names, just numbers. D2/D4 are connected to clock/increment (follow up with which is which).

I wouldn't recommend ever using these components the way I've done here unless you have a good reason.

Demo Sketch

Step 7

Connect your Arduino and upload the RGBLEDPickers sketch onto it. The RGBLEDPickers demo Arduino sketch is in the arduino folder of RGBLEDPickers app at Github.

Arduino + Bluetooth

Step 7

You'll need to attach a bluetooth module to the Arduino. The easiest way to do this is to get a Bluesmirf from Sparkfun and attach it to your Arduino. This sketch uses pins 0, 1 for bluetooth communication. Thus, connect Bluetooth TX -> Arduino RX; and Bluetooth RX -> Arduino TX.

NOTE: Since this demo sketch uses the same RX/TX pins on the Arduino as used by USB, you must power-off/disconnect the bluetooth module from the Arduino in order to upload sketches.

Your Own Custom Amarino-Embed App

To build your own custom Amarino-Embed app you'll need an awesome idea for an Arduino-based circuit that just begs to have a way to use it with an Android phone. Let's assume you've got that - the rest is just code right?

RGBLEDPickers provides a template developers can copy to create customized Android applications that communicate with their own Arduino-based hardware using Amarino-embed.

The Amarino-Embed Github Readme.md says that Getting Started boils down to this:

  • You'll need to reference the Amarino project as a library project. In Eclipse this means following the usual steps to import an Android Library project.
  • You'll need to add a the AndroidBluetooth.JAR file found in Amarino/libs as a JAR on the build path of your project.
  • The next step is to create an implementation for the AmarinoServiceIntentConfig interface, providing (Intent) namespaces that work for your app.
  • The next step is to subclass AmarinoService with your implementation that injects your AmarinoServiceIntentConfig implementation (above step).
  • The next step is to setup an intent receiver in your Activity that handles the broadcast Amarino service intents (defined in AmarinoServiceIntentConfig). See the HelloAmarinoWorld or RGBLEDPickers examples.
  • You'll need to modify your AndroidManifest to define your service class and allow for Bluetooth permissions.
  • The final step is to connect and communicate with the Arduino hardware in your Activity.

Let's discuss each point above with respect to the code in RGBLEDPickers.

reference the Amarino project as a library project

To do this you must have imported the Amarino project into your Eclipse workspace. Then follow the typical instructions for adding a library project to an Android project. (link)

add the AndroidBluetooth.JAR file found in Amarino/libs as a JAR on the build path of your project

You don't need to do this in newer versions of the SDK.

create an implementation for the AmarinoServiceIntentConfig interface

You'll need to create a class that implements AmarinoServiceIntentConfig. You'll need this to define app-specific intents so your background service handles bluetooth events properly. It's just a matter of defining the intent strings you want to use. An example is at https://github.com/tenaciousRas/amarino-embed/blob/dev-embed-0.6/amarino-examples/RGBLEDPickers/src/com/longevitysoft/android/rgbledsliders/ServiceIntentConfig.java.

NOTE: if you don't define this interface, you're left with the default/classic Amarino intent definitions - which is usually fine, unless you intend to publish the app.

subclass AmarinoService with your implementation that injects your AmarinoServiceIntentConfig implementation

To use the bluetooth intents you defined in the previous step, you'll need a class that extends AmarinoService. With this subclass you can inject your own AmarinoServiceIntentConfig. There's a good example of this at https://github.com/tenaciousRas/amarino-embed/blob/dev-embed-0.6/amarino-examples/RGBLEDPickers/src/com/longevitysoft/android/rgbledsliders/BTService.java.

next step is to setup an intent receiver in your Activity that handles the broadcast Amarino service intents

Intents are a basic construct of the Android system architecture, and Amarino-Embed works by providing a kind of intent layer to access bluetooth actions and events. To capture the bluetooth intents, you need a BroadcastReceiver subclass. A good example is at https://github.com/tenaciousRas/amarino-embed/blob/dev-embed-0.6/amarino-examples/RGBLEDPickers/src/com/longevitysoft/android/rgbledsliders/Main.java, specifically "public static class ArduinoReceiver".


To register the receiver "public static class ArduinoReceiver" we have this code in the Acitvity's onCreate(...) method:

	private ArduinoReceiver receiver;
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		receiver = new ArduinoReceiver();
		registerReceiver(receiver,
				new IntentFilter(intentConfig.getIntentNameActionConnect()));
		registerReceiver(receiver,
				new IntentFilter(intentConfig.getIntentNameActionReceived()));
         }

This causes your activity to listen to bluetooth intents. Actually, your activity becomes an intent proxy, where the intents captured by the Activity are re-broadcast to the service. Of course...you'll want more code than that in your Activity if it actually does anything, such as present a user interface.

connect and communicate with the Arduino hardware in your Activity

Again, RGBLEDPickers activity Main.java has a good example of this. Basically, you'll want this code in your activity to initiate the bluetooth connection:

	public static final String BT_DEVICE_ADDRESS = "bluetooth-id-of-your-module";

	@Override
	protected void onStart() {
		super.onStart();
		arduinoConnect();
	}

	/**
	 * Connect to Arudino device sans error handling + assume success, yay!
	 */
	private void arduinoConnect() {
		// create an instance of embeddedAmarino to wrap BT
		// intent broadcasts to service
		embeddedAmarino = new AmarinoConfigured(this.getApplicationContext());
		embeddedAmarino.setIntentConfig(intentConfig);
		embeddedAmarino.connect(BT_DEVICE_ADDRESS);
	}

If you're going to use the static connection calls from your activity, as RGBLEDPickers does, then you'll need to inject the intent config from both the activity and the service, as is done in RGBLEDPickers (and above). If you know what you're doing you should be able to eliminate the local reference to the AmarinoConfiguredService from the activity and just use intent broadcasts from the activity to connect and send data.

send data to Arduino via bluetooth

Sending data to an Arduino device connected via bluetooth is handled the same way in Amarino-Embed as in Amarino. Call the AmarinoConfigured#send(...) method (advanced: or broadcast an intent to the background service). Again an example is at https://github.com/tenaciousRas/amarino-embed/blob/dev-embed-0.6/amarino-examples/RGBLEDPickers/src/com/longevitysoft/android/rgbledsliders/Main.java, specifically the "public void setArduinoLEDColor" method.

Keep in mind that Amarino works with a callback architecture. Therefore the send(...) call includes the callback being invoked, as well as the callback data. This callback is the name of the method registered with the OBI/MeetAndroid library in your Arduino (sketch). The callback signature (method name) is a single byte. You must (1) register the callback in the Arduino sketch (using OBI/MeetAndroid) and (2) call the registered callback from Android. If you don't do both of these things the data won't be processed on the Arduino side.

To register the callback in your Arduino sketch:

#include <MeetAndroid.h>
MeetAndroid meetAndroid;

void setup()  {
  // set the data rate for Amarino - this may differ for your module
  Serial.begin(19200);
  // send init data
  meetAndroid.send("Arduino connected via bluetooth.");
  meetAndroid.registerFunction(setLEDColor, 'c');
}

...

void setLEDColor(byte flag, byte numOfValues) {
  char data[40];
  meetAndroid.getString(data);
  ...
}

And to receive events continuously you need this:

void loop() {
  ...
  meetAndroid.receive(); // receive android events
  ...
}