Send more than 2 values from arduino Mega ADk to android.

Hi all,

I have found a tutorial on sending values using arduino to the android device:
http://allaboutee.com/2011/12/31/arduino-adk-board-how-send-data-from-the-board-to-the-android-device/

This is my current codes now:
Android:

package com.FYP.arduinotestreceivedata;

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

 
 
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.Handler;
import android.os.Message;
import android.os.ParcelFileDescriptor;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.widget.TextView;
import android.widget.ToggleButton;
 
import android.hardware.usb.UsbAccessory;
import android.hardware.usb.UsbManager;;

public class MainActivity extends Activity implements Runnable {

	// Required to connect android with arduino
	
	private static final String ACTION_USB_PERMISSION = "com.FYP.arduinotestreceivedata.USB_PERMISSION";
	private UsbManager mUsbManager;
	private PendingIntent mPermissionIntent;
	private boolean mPermissionRequestPending;
	UsbAccessory mAccessory;
	ParcelFileDescriptor mFileDescriptor;
	FileInputStream mInputStream;
	FileOutputStream mOutputStream;
	private TextView mResponseField;
	private ToggleButton buttonLED;
	// Required to connect android with arduino
	// Require Methods to connect android with arduino
	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 {
						// USB permission denied
					}
				}
			} else if (UsbManager.ACTION_USB_ACCESSORY_DETACHED.equals(action)) {
				UsbAccessory accessory = (UsbAccessory) intent
						.getParcelableExtra(UsbManager.EXTRA_ACCESSORY);
				if (accessory != null && accessory.equals(mAccessory)) {
					// accessory detached
					android.os.Process.killProcess(android.os.Process.myPid());
					closeAccessory();
				}
			}
		}
	};

	// Require Methods to connect android with arduino

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		mUsbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
		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);
 
		if (getLastNonConfigurationInstance() != null) {
			mAccessory = (UsbAccessory) getLastNonConfigurationInstance();
			openAccessory(mAccessory);
		}
		setContentView(R.layout.activity_main);
		mResponseField = (TextView) findViewById(R.id.arduinoresponse);
		buttonLED = (ToggleButton) findViewById(R.id.toggleButton1);
		setupAccessory();
	}

	@Override
	public Object onRetainNonConfigurationInstance() {
		if (mAccessory != null) {
			return mAccessory;
		} else {
			return super.onRetainNonConfigurationInstance();
		}
	}

	@Override
	public void onResume() {
		super.onResume();

		if (mInputStream != null && mOutputStream != null) {
			// streams were not null");
			return;
		}
		// streams were null");
		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 {
			// null accessory
		}
	}

	@Override
	public void onPause() {
		super.onPause();
	}

	@Override
	public void onDestroy() {
		unregisterReceiver(mUsbReceiver);
		super.onDestroy();
	}
	

	Handler mHandler = new Handler() {
		@Override
		public void handleMessage(Message msg) {
			ValueMsg t = (ValueMsg)msg.obj;
			
			// this is where you handle the data you sent. You get it by calling
			// the getReading() function
			mResponseField.setText("Flag: " + t.getFlag() + "; Reading: "
					+ t.getReading());
		}
	};

	private void setupAccessory() {
		mUsbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
		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);
		if (getLastNonConfigurationInstance() != null) {
			mAccessory = (UsbAccessory) getLastNonConfigurationInstance();
			openAccessory(mAccessory);
		}
	}

	public void run() {
		int ret = 0;
		byte[] buffer = new byte[16384];
		int i;

		while (true) { // read data
			try {
				ret = mInputStream.read(buffer);
			} catch (IOException e) {
				break;
			}

			i = 0;
			while (i < ret) {
				int len = ret - i;
				if (len >= 1) {
					Message m = Message.obtain(mHandler);
					int value = (int) buffer[i];
					// 'f' is the flag, use for your own logic
					// value is the value from the arduino
					m.obj = new ValueMsg('f', value);
					mHandler.sendMessage(m);
					
				}
				i += 1; // number of bytes sent from arduino
			}

		}
	}

	// Require Methods to connect android with arduino
	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, this, "OpenAccessoryTest");
			thread.start();
			// Accessory opened
		} else {
			// failed to open accessory
		}
	}

	// Require Methods to connect android with arduino
	// Require Methods to connect android with arduino
	private void closeAccessory() {
		try {
			if (mFileDescriptor != null) {
				mFileDescriptor.close();
			}
		} catch (IOException e) {
		} finally {
			mFileDescriptor = null;
			mAccessory = null;
		}
	}
	// Require Methods to connect android with arduino
	
	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		if (keyCode == KeyEvent.KEYCODE_BACK) {
			
			android.os.Process.killProcess(android.os.Process.myPid());
		}

		return super.onKeyDown(keyCode, event);
	}
	
}

Arduino:

#include <Max3421e.h>
#include <Usb.h>
#include <AndroidAccessory.h>
 
AndroidAccessory acc("Manufacturer",
		     "Model",
		     "Description",
		     "1.0",
		     "http://yoursite.com",
		     "0000000012345678");
int SBpin = 22;
int doorPin = 48;
int speedPin = 49;
int SBval = 0;
int DOORval = 0;
int SPEEDval = 0;

void setup()
{
  Serial.begin(115200);
  pinMode(SBpin,INPUT);
  pinMode(doorPin, INPUT);
  pinMode(speedPin, INPUT);
  acc.powerOn();
}
 
void loop()
{
  
  
  byte msg[0]; // one byte
//  int value = 10; // value to send,we'll increment and decrement this variable
  if (acc.isConnected()) 
  {
 
    SBval = digitalRead(SBpin);
//    DOORval = digitalRead(doorPin);
//    SPEEDval = digitalRead(speedPin);
    msg[0] = SBval; 
    acc.write(msg, 1);
 
}

I manage to send one values to the android device. How do i send more than 1 values to the android device and save it as a string or integer?

Thanks in advance.

Regards,
Wei Sheng

  byte msg[0]; // one byte

Wrong. The array can hold 0 elements. This array is useless.

    msg[0] = SBval;

Wrong. This array element does not exist.

The whole byte array, even if sized correctly, to send one value is useless. The function that sends the data can send an array, by knowing the address where the data starts. If you want to send just one byte, tell the function the address where that data is.

acc.write(&SBval, sizeof(SBval));

If you want to send more than 1 value, a 0 element array is not near big enough.

PaulS:

  byte msg[0]; // one byte

Wrong. The array can hold 0 elements. This array is useless.

Okay, i understand this. because the defined array size is 0, am i right?

PaulS:

    msg[0] = SBval;

Wrong. This array element does not exist.

The whole byte array, even if sized correctly, to send one value is useless. The function that sends the data can send an array, by knowing the address where the data starts. If you want to send just one byte, tell the function the address where that data is.

Because the array size if 0 therefore, this array doesn't exist.

PaulS:

acc.write(&SBval, sizeof(SBval));

If you want to send more than 1 value, a 0 element array is not near big enough.

I still don't understand this.

anyway, What i want to achieve is that when i click on the 1st button, a certain value in android change, for example, boolean SBuse = false; is changed to true when the button is clicked.

This is my current setup for arduino(Android and arduino board are communicating using a micro usb cable):

The values that you are trying to send are ints, but they could be bytes, since the values are either 0 or 1.

To send all three in a byte array, the array needs to be big enough to hold three values:

  byte msg[3]; // three bytes

Then, store the values in the array:

   msg[0] = SBval;
   msg[1] = DOORval;
   msg[2] = SPEEDval;

Then, send the array:

    acc.write(msg, 3);

PaulS:
The values that you are trying to send are ints, but they could be bytes, since the values are either 0 or 1.

To send all three in a byte array, the array needs to be big enough to hold three values:

  byte msg[3]; // three bytes

Then, store the values in the array:

   msg[0] = SBval;

msg[1] = DOORval;
  msg[2] = SPEEDval;




Then, send the array:


acc.write(msg, 3);

Thank you very much, i appreciate it a lot... finally achieved what i want. YOU ARE REALLY MY SAVIOUR... HAHA :slight_smile: