Connecting Android to Arduino

Hey there! I'm working on a small project where I use my Arduino UNO to sample data and I want to be able to connect my android device and to plot the data there. The problem is, this topic is terribly described on the internet.

What I've read so far is that I can't just connect my Arduino to android and expect it to work because arduino doesn't have usb hosting capabilities. This could be solved by either buying arduino ADK like this one: http://arduino.cc/en/Main/ArduinoBoardMegaADK or by buying a USB host shield that can be attached to the arduino, like those two: http://www.ebay.com/itm/USB-Host-Shield-Support-Google-Android-ADK-UNO-MEGA-Duemilanove-2560-Arduino-/191131777566?pt=LH_DefaultDomain_0&hash=item2c80577a1e and http://arduino.cc/en/Main/ArduinoUSBHostShield

I have chosen to go with the USB host shield, however I have found some differences between these 2 shields that I have hard time understanding: The on on ebay says that its an ADK shield, and the arduino brand is just an USB host shield. What is the difference? Also, the one on ebay says that it only supports these phones: G1, Nexus One, Nexus S, Motorola Droid X, which is rather odd since it shouldnt matter if its even a phone the arduino is going to interface with.

Past post that might have useful info.

https://www.google.com/search?as_q=android&as_epq=&as_oq=&as_eq=&as_nlo=&as_nhi=&lr=&cr=&as_qdr=all&as_sitesearch=http%3A%2F%2Fforum.arduino.cc%2Findex&as_occt=any&safe=images&tbs=&as_filetype=&as_rights=&gws_rd=ssl

Those posts are of no help, since they all use Bluetooth or other form of wireless communication. I need it to communicate through USB port, using a USB host shield

jammasterz: I need it to communicate through USB port, using a USB host shield

I wonder why - and which app you intend to use to plot the data

jammasterz: Hey there! I'm working on a small project where I use my Arduino UNO to sample data and I want to be able to connect my android device and to plot the data there. The problem is, this topic is terribly described on the internet.

What I've read so far is that I can't just connect my Arduino to android and expect it to work because arduino doesn't have usb hosting capabilities. This could be solved by either buying arduino ADK like this one: http://arduino.cc/en/Main/ArduinoBoardMegaADK or by buying a USB host shield that can be attached to the arduino, like those two: http://www.ebay.com/itm/USB-Host-Shield-Support-Google-Android-ADK-UNO-MEGA-Duemilanove-2560-Arduino-/191131777566?pt=LH_DefaultDomain_0&hash=item2c80577a1e and http://arduino.cc/en/Main/ArduinoUSBHostShield

I have chosen to go with the USB host shield, however I have found some differences between these 2 shields that I have hard time understanding: The on on ebay says that its an ADK shield, and the arduino brand is just an USB host shield. What is the difference? Also, the one on ebay says that it only supports these phones: G1, Nexus One, Nexus S, Motorola Droid X, which is rather odd since it shouldnt matter if its even a phone the arduino is going to interface with.

At a guess the usb shield comes with software which only supports the mentioned devices. The mega adk and host shield from ahardware pov just supply power and a usb interface. Not checked the links though

Those posts are of no help, since they all use Bluetooth or other form of wireless communication.

Not seeing any USB in the discussions is probably natures warning sign for you.

I think you have it the wrong way round.

You would want to connect the Arduino (any Arduino) to the OTG port on your Android. It becomes a serial port.

The tricky part is writing the software on the Android device.

If it has an otg port. Vast majority of devices dont last time i looked. Ibelieve its gradually creeping in with newer devices.

Boardburner2: If it has an otg port. Vast majority of devices dont last time i looked. Ibelieve its gradually creeping in with newer devices.

Yes but you can just connect it through a mico USB OTG cable, can't you?

EDIT: Oh, provided that the phone supports OTG, that might be a problem on some devices.

Yes its the same usb connection, usb otg was very uncommon last time i looked.

What if I decide to switch from Android to PC, i heard there is a java library called RXTX, that allows for serial communication between arduino and my java application. Will this allow me to communicate both ways through a USB cable?

Hello
Im using the code :
(CODE TAGS PLEASE!)
Part Android :

package com.example.helloworld;

import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

import android.app.Activity;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.ParcelFileDescriptor;
import android.util.Log;
import android.widget.TextView;
import android.hardware.usb.UsbManager;
import android.hardware.usb.UsbAccessory;


public class HelloWorldActivity extends Activity {

	private static final String TAG = HelloWorldActivity.class.getSimpleName();

	private PendingIntent mPermissionIntent;
	private static final String ACTION_USB_PERMISSION = "com.android.example.USB_PERMISSION";
	private boolean mPermissionRequestPending;

	private UsbManager mUsbManager;
	private UsbAccessory mAccessory;
	private ParcelFileDescriptor mFileDescriptor;
	private FileInputStream mInputStream;
	private FileOutputStream mOutputStream;

	private static final byte COMMAND_TEXT = 0xF;
	private static final byte TARGET_DEFAULT = 0xF;

	private TextView textView;

	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		mUsbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
//		mUsbManager = UsbManager.getInstance(this);
		mPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(
				ACTION_USB_PERMISSION), 0);
		IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
		filter.addAction(UsbManager.ACTION_USB_ACCESSORY_DETACHED);
		registerReceiver(mUsbReceiver, filter);

		setContentView(R.layout.activity_hello_world);
		textView = (TextView) findViewById(R.id.textView);
	}

	/**
	 * Called when the activity is resumed from its paused state and immediately
	 * after onCreate().
	 */
	@Override
	public void onResume() {
		super.onResume();

		if (mInputStream != null && mOutputStream != null) {
			return;
		}

		UsbAccessory[] accessories = mUsbManager.getAccessoryList();
		UsbAccessory accessory = (accessories == null ? null : accessories[0]);
		if (accessory != null) {
			if (mUsbManager.hasPermission(accessory)) {
				openAccessory(accessory);
			} else {
				synchronized (mUsbReceiver) {
					if (!mPermissionRequestPending) {
						mUsbManager.requestPermission(accessory,
								mPermissionIntent);
						mPermissionRequestPending = true;
					}
				}
			}
		} else {
			Log.d(TAG, "mAccessory is null");
		}
	}

	/** Called when the activity is paused by the system. */
	@Override
	public void onPause() {
		super.onPause();
		closeAccessory();
	}

	/**
	 * Called when the activity is no longer needed prior to being removed from
	 * the activity stack.
	 */
	@Override
	public void onDestroy() {
		super.onDestroy();
		unregisterReceiver(mUsbReceiver);
	}

	private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
		@Override
		public void onReceive(Context context, Intent intent) {
			String action = intent.getAction();
			if (ACTION_USB_PERMISSION.equals(action)) {
				synchronized (this) {
					UsbAccessory accessory = (UsbAccessory) intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY);
					if (intent.getBooleanExtra(
							UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
						openAccessory(accessory);
					} else {
						Log.d(TAG, "permission denied for accessory "
								+ accessory);
					}
					mPermissionRequestPending = false;
				}
			} else if (UsbManager.ACTION_USB_ACCESSORY_DETACHED.equals(action)) {
				UsbAccessory accessory = (UsbAccessory) intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY);
				if (accessory != null && accessory.equals(mAccessory)) {
					closeAccessory();
				}
			}
		}
	};

	private void openAccessory(UsbAccessory accessory) {
		mFileDescriptor = mUsbManager.openAccessory(accessory);
		if (mFileDescriptor != null) {
			mAccessory = accessory;
			FileDescriptor fd = mFileDescriptor.getFileDescriptor();
			mInputStream = new FileInputStream(fd);
			mOutputStream = new FileOutputStream(fd);
			Thread thread = new Thread(null, commRunnable, TAG);
			thread.start();
			Log.d(TAG, "accessory opened");
		} else {
			Log.d(TAG, "accessory open fail");
		}
	}

	private void closeAccessory() {
		try {
			if (mFileDescriptor != null) {
				mFileDescriptor.close();
			}
		} catch (IOException e) {
		} finally {
			mFileDescriptor = null;
			mAccessory = null;
		}
	}

	Runnable commRunnable = new Runnable() {

		@Override
		public void run() {
			int ret = 0;
			byte[] buffer = new byte[255];

			while (ret >= 0) {
				try {
					ret = mInputStream.read(buffer);
				} catch (IOException e) {
					break;
				}

				switch (buffer[0]) {
				case COMMAND_TEXT:

					final StringBuilder textBuilder = new StringBuilder();
					int textLength = buffer[2];
					int textEndIndex = 3 + textLength;
					for (int x = 3; x < textEndIndex; x++) {
						textBuilder.append((char) buffer[x]);
					}

					runOnUiThread(new Runnable() {

						@Override
						public void run() {
							textView.setText(textBuilder.toString());
						}
					});
					sendText(COMMAND_TEXT, TARGET_DEFAULT,
							"Hello World from Android!");
					break;

				default:
					Log.d(TAG, "unknown msg: " + buffer[0]);

					break;
				}

			}
		}
	};

	public void sendText(byte command, byte target, String text) {
		int textLength = text.length();
		byte[] buffer = new byte[3 + textLength];
		if (textLength <= 252) {
			buffer[0] = command;
			buffer[1] = target;
			buffer[2] = (byte) textLength;
			byte[] textInBytes = text.getBytes();
			for (int x = 0; x < textLength; x++) {
				buffer[3 + x] = textInBytes[x];
			}
			if (mOutputStream != null) {
				try {
					mOutputStream.write(buffer);
				} catch (IOException e) {
					Log.e(TAG, "write failed", e);
				}
			}
		}
	}
}

Part Arduino :

#include <Max3421e.h>
#include <Usb.h>
#include <AndroidAccessory.h>

#define ARRAY_SIZE 12

AndroidAccessory acc("Manufacturer", "Model", "Description",
                      "Version", "URI", "Serial");

char hello[ARRAY_SIZE] = {'H', 'e', 'l', 'l', 'o', ' ', 
                          'W', 'o', 'r', 'l', 'd'};
                          
void setup() {
  Serial.begin(115200);
  acc.powerOn();
}

void loop() {
  if (acc.isConnected()) {
    for (int x=0; x<ARRAY_SIZE; x++) {
      Serial.print(hello[x]);
      delay(250); 
    }
     Serial.println();
     delay(250);
  }
}

but in monitor serial I have an error (Error: OSCOKIRQ failed to assert)
You can help me please

Hi,

Hi, You can look at this app : code source app inventor + arduino , Usb Bridge for app inventor 2 android . Control arduino card with an android device and app inventor. Very easy to use.

Good luck