Showing posts with label ADK. Show all posts
Showing posts with label ADK. Show all posts

Thursday, October 15, 2015

Android control Arduino Due LED, using ADK (Accessory Development Kit)

I have old posts of "Android code sending command to Arduino Due to turn LED On/Off (Android side)" and "Control Arduino Due LED from Android using ADK (Arduino Due side)" to show a simple control from Android to Arduino Due using ADK (Accessory Development Kit), at 2013. At both Android and Arduino development tools updated, I re-visit the example code again.



Arduino Due Side:

In current Arduino IDE 1.6.5, both Arduino Due and ADK library are not include by default, so you have to:
- Install Arduino Due to Arduino IDE
- Install USBHost library to Arduino IDE

DurAdkLed.ino (same as before)
#include "variant.h"
#include <stdio.h>
#include <adk.h>

// Accessory descriptor. It's how Arduino identifies itself to Android.
char applicationName[] = "HelloADKLED"; // the app on your phone
char accessoryName[] = "Arduino Due"; // your Arduino board
char companyName[] = "Arduino-er";
 
// Make up anything you want for these
char versionNumber[] = "0.1";
char serialNumber[] = "1";
char url[] = "https://sites.google.com/site/arduinosite/exercise/androidadkled/AndroidADKLED_0.1.apk";
 
USBHost Usb;
ADK adk(&Usb, companyName, applicationName, accessoryName,versionNumber,url,serialNumber);
 
// Pin 13 has an LED connected on most Arduino boards.
int led = 13;
 
void setup() {
    Serial.begin(9600);
    cpu_irq_enable();
   
    pinMode(led, OUTPUT);
    //Indicate start of program
    digitalWrite(led, LOW);
    delay(2000);
    digitalWrite(led, HIGH);
    for(int i = 0; i <= 2; i++){
        digitalWrite(led, HIGH);
        delay(250);
        digitalWrite(led, LOW);
        delay(250);
    }
}
 
#define RCVSIZE 128
 
void loop() {
   
    char helloworld[] = "Hello World!\r\n";
   
    uint8_t buf[RCVSIZE];
    uint32_t nbread = 0;
   
    Usb.Task();
     
    if (adk.isReady()){
      
        adk.read(&nbread, RCVSIZE, buf);
        if (nbread > 0){
            adk.write(nbread, buf);
            
            //Convert nbread to String
            String s = "";
            for (uint32_t i = 0; i < nbread; ++i) {
              s += (char)buf[i];
            }
            
            if(s == "LEDON"){
              digitalWrite(led, HIGH);
            }else if(s == "LEDOFF"){
              digitalWrite(led, LOW);
            }
        }
         
    }
     
}


Android Side:

AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.blogspot.android_er.androidadkled" >

    <uses-feature android:name="android.hardware.usb.accessory"/>

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme" >
        <activity android:name=".MainActivity" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED" />
            </intent-filter>
            <meta-data android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED"
                android:resource="@xml/myfilter"/>
        </activity>
    </application>

</manifest>


xml/myfilter.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <usb-accessory
        manufacturer="Arduino-er"
        model="HelloADKLED"
        version="0.1"/>
</resources>

layout/activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="16dp"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:autoLink="web"
        android:text="http://android-er.blogspot.com/"
        android:textStyle="bold" />
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:autoLink="web"
        android:text="http://arduino-er.blogspot.com/"
        android:textStyle="bold" />

    <TextView
        android:id="@+id/textin"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
    <RadioGroup
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">
        <RadioButton
            android:id="@+id/LedOn"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="LED On" />
        <RadioButton
            android:id="@+id/LedOff"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="LED Off" />
    </RadioGroup>
</LinearLayout>


AbstractAdkActivity.java
package com.blogspot.android_er.androidadkled;

import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.hardware.usb.UsbAccessory;
import android.hardware.usb.UsbManager;
import android.os.Bundle;
import android.os.ParcelFileDescriptor;
import android.support.v7.app.AppCompatActivity;

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

public abstract  class AbstractAdkActivity extends AppCompatActivity {

    private static int RQS_USB_PERMISSION = 0;
    private static final String ACTION_USB_PERMISSION = "arduino-er.usb_permission";
    private PendingIntent PendingIntent_UsbPermission;

    private UsbManager myUsbManager;
    private UsbAccessory myUsbAccessory;
    private ParcelFileDescriptor myAdkParcelFileDescriptor;
    private FileInputStream myAdkInputStream;
    private FileOutputStream myAdkOutputStream;
    boolean firstRqsPermission;

    //do something in onCreate()
    protected abstract void doOnCreate(Bundle savedInstanceState);
    //do something after adk read
    protected abstract void doAdkRead(String stringIn);

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //setContentView(R.layout.activity_main);

        myUsbManager = (UsbManager)getSystemService(Context.USB_SERVICE);
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(UsbManager.ACTION_USB_ACCESSORY_DETACHED);
        registerReceiver(myUsbReceiver, intentFilter);

        //Ask USB Permission from user
        Intent intent_UsbPermission = new Intent(ACTION_USB_PERMISSION);
        PendingIntent_UsbPermission = PendingIntent.getBroadcast(
                this,      //context
                RQS_USB_PERMISSION,  //request code
                intent_UsbPermission, //intent
                0);      //flags
        IntentFilter intentFilter_UsbPermission = new IntentFilter(ACTION_USB_PERMISSION);
        registerReceiver(myUsbPermissionReceiver, intentFilter_UsbPermission);

        firstRqsPermission = true;
        doOnCreate(savedInstanceState);
    }

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

        if(myAdkInputStream == null || myAdkOutputStream == null){

            UsbAccessory[] usbAccessoryList = myUsbManager.getAccessoryList();
            UsbAccessory usbAccessory = null;
            if(usbAccessoryList != null){
                usbAccessory = usbAccessoryList[0];

                if(usbAccessory != null){
                    if(myUsbManager.hasPermission(usbAccessory)){
                        //already have permission
                        OpenUsbAccessory(usbAccessory);
                    }else{

                        if(firstRqsPermission){

                            firstRqsPermission = false;

                            synchronized(myUsbReceiver){
                                myUsbManager.requestPermission(usbAccessory,
                                        PendingIntent_UsbPermission);
                            }
                        }

                    }
                }
            }
        }
    }

    //Write String to Adk
    void WriteAdk(String text){

        byte[] buffer = text.getBytes();

        if(myAdkOutputStream != null){

            try {
                myAdkOutputStream.write(buffer);
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        closeUsbAccessory();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        unregisterReceiver(myUsbReceiver);
        unregisterReceiver(myUsbPermissionReceiver);
    }

    Runnable runnableReadAdk = new Runnable(){

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

            while(numberOfByteRead >= 0){

                try {
                    numberOfByteRead = myAdkInputStream.read(buffer, 0, buffer.length);
                    final StringBuilder stringBuilder = new StringBuilder();
                    for(int i=0; i<numberOfByteRead; i++){
                        stringBuilder.append((char)buffer[i]);
                    }

                    runOnUiThread(new Runnable(){

                        @Override
                        public void run() {
                            doAdkRead(stringBuilder.toString());
                        }});


                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                    break;
                }
            }
        }

    };

    private BroadcastReceiver myUsbReceiver = new BroadcastReceiver(){

        @Override
        public void onReceive(Context context, Intent intent) {

            String action = intent.getAction();
            if(action.equals(UsbManager.ACTION_USB_ACCESSORY_DETACHED)){

                UsbAccessory usbAccessory =
                        (UsbAccessory)intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY);

                if(usbAccessory!=null && usbAccessory.equals(myUsbAccessory)){
                    closeUsbAccessory();
                }
            }
        }
    };

    private BroadcastReceiver myUsbPermissionReceiver = new BroadcastReceiver(){

        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if(action.equals(ACTION_USB_PERMISSION)){

                synchronized(this){

                    UsbAccessory usbAccessory =
                            (UsbAccessory)intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY);

                    if(intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)){
                        OpenUsbAccessory(usbAccessory);
                    }else{
                        finish();
                    }
                }
            }
        }

    };

    private void OpenUsbAccessory(UsbAccessory acc){
        myAdkParcelFileDescriptor = myUsbManager.openAccessory(acc);
        if(myAdkParcelFileDescriptor != null){

            myUsbAccessory = acc;
            FileDescriptor fileDescriptor = myAdkParcelFileDescriptor.getFileDescriptor();
            myAdkInputStream = new FileInputStream(fileDescriptor);
            myAdkOutputStream = new FileOutputStream(fileDescriptor);

            Thread thread = new Thread(runnableReadAdk);
            thread.start();
        }
    }

    private void closeUsbAccessory(){

        if(myAdkParcelFileDescriptor != null){
            try {
                myAdkParcelFileDescriptor.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

        myAdkParcelFileDescriptor = null;
        myUsbAccessory = null;
    }
}


MainActivity.java
package com.blogspot.android_er.androidadkled;

import android.os.Bundle;
import android.widget.CompoundButton;
import android.widget.RadioButton;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends AbstractAdkActivity  {

    TextView textIn;
    RadioButton ledOn, ledOff;

    @Override
    protected void doOnCreate(Bundle savedInstanceState) {
        setContentView(R.layout.activity_main);
        textIn = (TextView)findViewById(R.id.textin);
        ledOn = (RadioButton)findViewById(R.id.LedOn);
        ledOff = (RadioButton)findViewById(R.id.LedOff);

        ledOn.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener(){

            @Override
            public void onCheckedChanged(CompoundButton buttonView,
                                         boolean isChecked) {
                if(isChecked){
                    WriteAdk("LEDON");
                    Toast.makeText(getApplicationContext(),
                            "LEDON", Toast.LENGTH_LONG).show();
                }
            }});

        ledOff.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener(){

            @Override
            public void onCheckedChanged(CompoundButton buttonView,
                                         boolean isChecked) {
                if(isChecked){
                    WriteAdk("LEDOFF");
                    Toast.makeText(getApplicationContext(),
                            "LEDOFF", Toast.LENGTH_SHORT).show();
                }
            }});

    }

    @Override
    protected void doAdkRead(String stringIn) {
        textIn.setText(stringIn);
    }
}



adk.h: No such file or directory and Install USBHost library to Arduino IDE


adk.h (Accessory Development Kit) is part of USBHost library. In current Arduino IDE 1.6.5, it's not included by default.

To install USBHost:
> Sketch > Include Library > Manage Libraries
> Search to install USBHost.



Monday, June 17, 2013

Import and setup Android ADK terminal emulator, to work with Arduino ADKTerminalTest example

Last post introduced "Modified ADKTerminalTest example of Arduino 1.5.2", it work with "http://labs.arduino.cc/uploads/ADK/ArduinoTerminal/ThibaultTerminal_ICS_0001.apk" in default. Alternatively, Circuits@Home provide a project "Android ADK terminal emulator for Arduino" with source code, it can work with the modified ADKTerminalTest. This post descript how to import and setup in Eclipse of Android Developer Tools.

Prepare:

- It's assumed you have Android SDK installed on your PC.

- Download and unzip source code of ArduinoTerminalSrc.zip from "Android ADK terminal emulator for Arduino page", it can also be download here directly.

- Make sure Android 2.3.3 (API 10) and associated Google APIs are installed in your Android Developer Tools. In Eclipse, select Window in menu bar, -> Android SDK Manager.


Import downloaded ArduinoTerminalSrc:

- Click File -> Import...


-  Select "Existing Android Code into Workspace" under Android section.



- Browse to select downloaded and unziped folder.


- Optionally check "Copy projects into workspace" and click Finish.


- After a moment of auto-build, many error of something like "The import com.android.future cannot be resolved" will be reported.


- Right click your project - > Properties.


- Select Target Google APIs of Platform 2.3.3, and click OK.


- After finished and re-built, you can download it to your Android device. It can work with the modified ADKTerminalTest.

remark:
- Tested on Nexus One with Android 2.3.6. But not work on HTC One X with Android 4.1.1, dur to issues of Theme!


Test ADKTerminalTest example of Arduino 1.5.2, with Android ADK terminal emulator for Arduino

Arduino 1.5.2 provide a ADKTerminalTest example to demonstrates USB Host connectivity between an Android phone and an Arduino Due. It provide source code in Arduino Due side, and url to load Android APK from "http://labs.arduino.cc/uploads/ADK/ArduinoTerminal/ThibaultTerminal_ICS_0001.apk". But I can't find the source code of ThibaultTerminal_ICS_0001. Alternatively, I found "Android ADK terminal emulator for Arduino (ArduinoTerminal)" with source code provided.

In this post, I will describe how to make ADKTerminalTest example work with ArduinoTerminal. In next post, I will show how to import and setup ArduinoTerminalSrc in Android Developer Tools. After finished, you can connect and send text between Arduino Due and Nexus One running Android 2.3.6.

Arduino Due work with Nexus One
Arduino Due work with Nexus One
To load ADKTerminalTest example of Arduino 1.5.2, select File -> Examples -> USBHost -> ADKTerminalTest.

ADKTerminalTest example in Arduino 1.5.2
ADKTerminalTest example in Arduino 1.5.2

Modify on Arduino code:
  • Modify adk() parameters to match with Android side. To acknowledge the originator of Android ADK terminal emulator for Arduino, I use the original counter part.
  • Add the code Serial.begin(9600) in setup() method.
/*

 ADK Terminal Test

 This demonstrates USB Host connectivity between an 
 Android phone and an Arduino Due.

 The ADK for the Arduino Due is a work in progress
 For additional information on the Arduino ADK visit 
 http://labs.arduino.cc/ADK/Index

 created 27 June 2012
 by Cristian Maglie

*/

#include "variant.h"
#include <stdio.h>
#include <adk.h>
/*
// Accessory descriptor. It's how Arduino identifies itself to Android.
char applicationName[] = "Arduino_Terminal"; // the app on your phone
char accessoryName[] = "Arduino Due"; // your Arduino board
char companyName[] = "Arduino SA";

// Make up anything you want for these
char versionNumber[] = "1.0";
char serialNumber[] = "1";
char url[] = "http://labs.arduino.cc/uploads/ADK/ArduinoTerminal/ThibaultTerminal_ICS_0001.apk";
*/

USBHost Usb;
//ADK adk(&Usb, companyName, applicationName, accessoryName,versionNumber,url,serialNumber);

ADK adk(&Usb,"Circuits@Home, ltd.",
            "USB Host Shield",
            "Arduino Terminal for Android",
            "1.0",
            "http://www.circuitsathome.com",
            "0000000000000001");

void setup()
{
  
      Serial.begin(9600);  //<-- need to add
      
 cpu_irq_enable();
 printf("\r\nADK demo start\r\n");
 delay(200);
}

#define RCVSIZE 128

void loop()
{
 uint8_t buf[RCVSIZE];
 uint32_t nbread = 0;
 char helloworld[] = "Hello World!\r\n";

 Usb.Task();

 if (adk.isReady())
 {
  /* Write hello string to ADK */
  adk.write(strlen(helloworld), (uint8_t *)helloworld);

  delay(1000);

  /* Read data from ADK and print to UART */
  adk.read(&nbread, RCVSIZE, buf);
  if (nbread > 0)
  {
   printf("RCV: ");
   for (uint32_t i = 0; i < nbread; ++i)
   {
    printf("%c", (char)buf[i]);
   }
   printf("\r\n");
  }
 }
}


Next:
- Import and setup Android ADK terminal emulator, to work with Arduino ADKTerminalTest example

Friday, June 14, 2013

Download ADK Source in Ubuntu

The document "Downloading the ADK Source" describe how to obtain the source material for the ADK. Before that, we have to install curl, git and repo. The steps below show how to install the tools and also ADK source in Ubuntu (13.04).

- Open Terminal.

- Install curl
$sudo apt-get install curl

- Install git
$sudo apt-get install git

- Then create bin/ directory in home directory, and include it in your path.
$mkdir ~/bin
$PATH=~/bin:$PATH

- Install Repo
$curl https://dl-ssl.google.com/dl/googlesource/git-repo/repo > ~/bin/repo
$chmod a+x ~/bin/repo

- Finally, create a new directory for the downloaded ADK source files, initialize and synchronize a local repository:
$mkdir android-accessories
$cd android-accessories
$repo init -u https://android.googlesource.com/accessories/manifest
$repo sync

After successfully completing this process, you should have the source code and tools for working with the ADK 2012:

adk2012/board - Source code and hardware design files for the ADK 2012
adk2012/app - Source code for the ADK 2012 Android companion application
external/ide - Source code for the ADK 2012 Integrated Development Environment (IDE)
external/toolchain - The toolchain used by the ADK 2012 IDE

Tuesday, June 4, 2013

write failed: ENODEV (No such device)



In this previous exercise "Android code for Communication between Android and Arduino Due", it work as expected after plug in Android device into Arduino Due board.



The problem is:

Once I switch out and back the app, and perform onResume()... The app can get fileDescriptor, myAdkInputStream and myAdkOutputStream. But when it try to write to myAdkOutputStream in WriteAdk(String text) method, IOException of "write failed: ENODEV (No such device)" thrown!

Anybody can advise?

Wednesday, May 1, 2013

Quality of Google ADK 2012 Code


We all want to have more Android automation in our homes. XDA Elite Recognized Developer AdamOutler set out to do just that and spent around 40 hours attempting to reduce and rewrite the code driving the ADK2012 into something which would be more moldable and bendable. He failed and he explains why in his rant which he calls the ADK2012 "The Worst Code Ever".

So if you've ever wanted to work with Google Accessory Development Kit makes ure to check out this video. This will give you a little insight as to what trials and tribulations you may have with this resource. Before you engage in a head desk collision session, check out what Adam has to say.

Sunday, March 31, 2013

Android code sending command to Arduino Due to turn LED On/Off

It's the coding in Android side to send command to Arduino Due to control LED On/Off.


Modify AndroidManifest.xml to add <uses-feature> of "android.hardware.usb.accessory", <intent-filter> of "android.hardware.usb.action.USB_ACCESSORY_ATTACHED", and <meta-data> of resource="@xml/myfilter".
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.androidadkled"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="12"
        android:targetSdkVersion="17" />

    <uses-feature android:name="android.hardware.usb.accessory"/>
    
    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.example.androidadkled.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED" />
            </intent-filter>
            <meta-data android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED"
                android:resource="@xml/myfilter"/>
        </activity>
    </application>

</manifest>


Create file /res/xml/myfilter.xml
<?xml version="1.0" encoding="UTF-8"?>
<resources>
    <usb-accessory
        manufacturer="Arduino-er"
        model="HelloADKLED"
        version="0.1"/>
</resources>


Layout file, /res/layout/activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:orientation="vertical"
    tools:context=".MainActivity" >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Arduino LED Control" />
    <TextView
        android:id="@+id/textin"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
    <RadioGroup
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">
        <RadioButton
            android:id="@+id/LedOn"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="LED On" />
        <RadioButton
            android:id="@+id/LedOff"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="LED Off" />
    </RadioGroup>

</LinearLayout>


Create a abstract class AbstractAdkActivity.java to extend Activity, implement the function of ADK; such that we can easy re-use it in furture and reduce the ADK related job in MainActivity.java.
/*
 * abstract class for Activities have to read ADK
 * for android:minSdkVersion="12"
 * 
 */

package com.example.androidadkled;

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.hardware.usb.UsbAccessory;
import android.hardware.usb.UsbManager;
import android.os.Bundle;
import android.os.ParcelFileDescriptor;

public abstract class AbstractAdkActivity extends Activity {
 
 private static int RQS_USB_PERMISSION = 0;
 private static final String ACTION_USB_PERMISSION = "arduino-er.usb_permission";
 private PendingIntent PendingIntent_UsbPermission;
 
 private UsbManager myUsbManager;
 private UsbAccessory myUsbAccessory;
 private ParcelFileDescriptor myAdkParcelFileDescriptor;
 private FileInputStream myAdkInputStream;
 private FileOutputStream myAdkOutputStream;
 boolean firstRqsPermission;

 //do something in onCreate()
 protected abstract void doOnCreate(Bundle savedInstanceState);
 //do something after adk read
 protected abstract void doAdkRead(String stringIn); 
 
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  //setContentView(R.layout.activity_main);
  
  myUsbManager = (UsbManager)getSystemService(Context.USB_SERVICE);
  IntentFilter intentFilter = new IntentFilter();
  intentFilter.addAction(UsbManager.ACTION_USB_ACCESSORY_DETACHED);
  registerReceiver(myUsbReceiver, intentFilter);
  
  //Ask USB Permission from user
  Intent intent_UsbPermission = new Intent(ACTION_USB_PERMISSION);
  PendingIntent_UsbPermission = PendingIntent.getBroadcast(
    this,      //context
    RQS_USB_PERMISSION,  //request code
    intent_UsbPermission, //intent 
    0);      //flags
  IntentFilter intentFilter_UsbPermission = new IntentFilter(ACTION_USB_PERMISSION);
  registerReceiver(myUsbPermissionReceiver, intentFilter_UsbPermission);
  
  firstRqsPermission = true;
  doOnCreate(savedInstanceState);
 }
 
 @Override
 protected void onResume() {
  super.onResume();
  
  if(myAdkInputStream == null || myAdkOutputStream == null){
   
   UsbAccessory[] usbAccessoryList = myUsbManager.getAccessoryList();
   UsbAccessory usbAccessory = null;
   if(usbAccessoryList != null){
    usbAccessory = usbAccessoryList[0];
    
    if(usbAccessory != null){
     if(myUsbManager.hasPermission(usbAccessory)){
      //already have permission
      OpenUsbAccessory(usbAccessory);
     }else{
      
      if(firstRqsPermission){
       
       firstRqsPermission = false;
       
       synchronized(myUsbReceiver){
        myUsbManager.requestPermission(usbAccessory, 
          PendingIntent_UsbPermission);
       }
      }
      
     }
    }
   }
  }
 }
 
 //Write String to Adk
 void WriteAdk(String text){

  byte[] buffer = text.getBytes();

  if(myAdkOutputStream != null){
   
   try {
    myAdkOutputStream.write(buffer);
   } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   } 
  }
 }
 
 @Override
 protected void onPause() {
  super.onPause();
  closeUsbAccessory();
 }

 @Override
 protected void onDestroy() {
  super.onDestroy();
  unregisterReceiver(myUsbReceiver);
  unregisterReceiver(myUsbPermissionReceiver);
 }
 
 Runnable runnableReadAdk = new Runnable(){

  @Override
  public void run() {
   int numberOfByteRead = 0;
   byte[] buffer = new byte[255];
   
   while(numberOfByteRead >= 0){
    
    try {
     numberOfByteRead = myAdkInputStream.read(buffer, 0, buffer.length);
     final StringBuilder stringBuilder = new StringBuilder();
     for(int i=0; i<numberOfByteRead; i++){
      stringBuilder.append((char)buffer[i]);
     }
     
     runOnUiThread(new Runnable(){

      @Override
      public void run() {
       doAdkRead(stringBuilder.toString());
      }});
     
     
    } catch (IOException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
     break;
    }
   }
  }
  
 };
 
 private BroadcastReceiver myUsbReceiver = new BroadcastReceiver(){
  
  @Override
  public void onReceive(Context context, Intent intent) {

   String action = intent.getAction();
   if(action.equals(UsbManager.ACTION_USB_ACCESSORY_DETACHED)){

    UsbAccessory usbAccessory = 
      (UsbAccessory)intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY);
    
    if(usbAccessory!=null && usbAccessory.equals(myUsbAccessory)){
     closeUsbAccessory();
    }
   }
  }
 };
 
 private BroadcastReceiver myUsbPermissionReceiver = new BroadcastReceiver(){

  @Override
  public void onReceive(Context context, Intent intent) {
   String action = intent.getAction();
   if(action.equals(ACTION_USB_PERMISSION)){

    synchronized(this){
     
     UsbAccessory usbAccessory = 
       (UsbAccessory)intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY);
     
     if(intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)){
      OpenUsbAccessory(usbAccessory);
     }else{
      finish();
     }
    }
   }
  }
  
 };
 
 private void OpenUsbAccessory(UsbAccessory acc){
  myAdkParcelFileDescriptor = myUsbManager.openAccessory(acc);
  if(myAdkParcelFileDescriptor != null){
   
   myUsbAccessory = acc;
   FileDescriptor fileDescriptor = myAdkParcelFileDescriptor.getFileDescriptor();
   myAdkInputStream = new FileInputStream(fileDescriptor);
   myAdkOutputStream = new FileOutputStream(fileDescriptor);
   
   Thread thread = new Thread(runnableReadAdk);
   thread.start();
  }
 }
 
 private void closeUsbAccessory(){
  
  if(myAdkParcelFileDescriptor != null){
   try {
    myAdkParcelFileDescriptor.close();
   } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }
  }
  
  myAdkParcelFileDescriptor = null;
  myUsbAccessory = null;
 }
}


Modify MainActivity.java to extend AbstractAdkActivity, and extend Activity in-turn. With AbstractAdkActivity handle most of the ADK related job, we only have to override the methods doOnCreate()(called in onCreate() method) and doAdkRead()(called after command read from ADK). To send command to ADK, call WriteAdk() method.
package com.example.androidadkled;

import android.os.Bundle;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.RadioButton;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends AbstractAdkActivity {
 
 TextView textIn;
 RadioButton ledOn, ledOff;

 @Override
 protected void doOnCreate(Bundle savedInstanceState) {
  setContentView(R.layout.activity_main);
  textIn = (TextView)findViewById(R.id.textin);
  ledOn = (RadioButton)findViewById(R.id.LedOn);
  ledOff = (RadioButton)findViewById(R.id.LedOff);
  
  ledOn.setOnCheckedChangeListener(new OnCheckedChangeListener(){

   @Override
   public void onCheckedChanged(CompoundButton buttonView,
     boolean isChecked) {
    if(isChecked){
     WriteAdk("LEDON");
     Toast.makeText(getApplicationContext(), 
       "LEDON", Toast.LENGTH_LONG).show();
    }
   }});
  
  ledOff.setOnCheckedChangeListener(new OnCheckedChangeListener(){

   @Override
   public void onCheckedChanged(CompoundButton buttonView,
     boolean isChecked) {
    if(isChecked){
     WriteAdk("LEDOFF");
     Toast.makeText(getApplicationContext(), 
       "LEDOFF", Toast.LENGTH_SHORT).show();
    }
   }});

 }

 @Override
 protected void doAdkRead(String stringIn) {
  textIn.setText(stringIn);
 }

}


download filesDownload the files.

Refer the another post for the code in Arduino Due side.


Updated@2015-10-15Android control Arduino Due LED, using ADK (Accessory Development Kit)

Monday, March 11, 2013

Hello World ADK: Android code

Last post demonstrate my Hello World ADK, with sample code in Arduino Due side. Here is the sample code in Android side.

Hello World ADK: Communication between Arduino Due and Android device
Check last post to view demo video and sample code in Arduino Due side



- Modify AndroidManifest.xml to <uses-festure>, <uses-library>, <intent-filter>, and <meta-data>.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.helloadk"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="10"
        android:targetSdkVersion="17" />
    
    <uses-feature android:name="android.hardware.usb.accessory"/>

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <uses-library android:name="com.android.future.usb.accessory"/>
        <activity
            android:name="com.example.helloadk.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED" />
            </intent-filter>
            <meta-data android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED"
                android:resource="@xml/myfilter"/>
        </activity>
    </application>

</manifest>


- Craete /res/xml/myfilter.xml to to define resource of usb-accessory (update version="0.1" to match latest versionNumber in HelloADK Arduino code).

<?xml version="1.0" encoding="UTF-8"?>
<resources>
    <usb-accessory
        manufacturer="Arduino-er"
        model="HelloADK"
        version="0.1"/>
</resources>


Main Java code, MainActivity.java.

/*
 * manufacturer="Arduino-er"
 * model="HelloADK"
 * version="0.1"
 */

package com.example.helloadk;

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

import com.android.future.usb.UsbAccessory;
import com.android.future.usb.UsbManager;

import android.os.Bundle;
import android.os.ParcelFileDescriptor;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity {
 
 EditText textOut;
 TextView textIn;
 Button btnSend;
 
 private UsbManager myUsbManager;
 private UsbAccessory myUsbAccessory;
 private ParcelFileDescriptor myParcelFileDescriptor;
 private FileInputStream myFileInputStream;
 private FileOutputStream myFileOutputStream;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  
  textOut = (EditText)findViewById(R.id.textout);
  textIn = (TextView)findViewById(R.id.textin);
  btnSend = (Button)findViewById(R.id.btnsend);
  
  myUsbManager = UsbManager.getInstance(this);
  IntentFilter intentFilter = new IntentFilter();
  intentFilter.addAction(UsbManager.ACTION_USB_ACCESSORY_DETACHED);
  registerReceiver(myUsbReceiver, intentFilter);
  
  btnSend.setOnClickListener(new OnClickListener() {
   
   @Override
   public void onClick(View v) {
    
    String textToSend = textOut.getEditableText().toString();
    if(!textToSend.equals("")){
     sendText(textToSend);
    }
   }
  });
  
 }

 @Override
 protected void onResume() {
  super.onResume();
  
  if(myFileInputStream == null || myFileOutputStream == null){
   
   UsbAccessory[] usbAccessoryList = myUsbManager.getAccessoryList();
   UsbAccessory usbAccessory = null;
   if(usbAccessoryList != null){
    usbAccessory = usbAccessoryList[0];
    OpenUsbAccessory(usbAccessory);
   }
  }
 }
 
 Runnable myRunnable = new Runnable(){

  @Override
  public void run() {
   int numberOfByteRead = 0;
   byte[] buffer = new byte[255];
   
   while(numberOfByteRead >= 0){
    
    try {
     numberOfByteRead = myFileInputStream.read(buffer, 0, buffer.length);
     final StringBuilder stringBuilder = new StringBuilder();
     for(int i=0; i<numberOfByteRead; i++){
      stringBuilder.append((char)buffer[i]);
     }
     
     runOnUiThread(new Runnable(){

      @Override
      public void run() {
       textIn.setText(stringBuilder.toString());
      }});
     
     
    } catch (IOException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
     break;
    }
   }
  }
  
 };
 
 private void OpenUsbAccessory(UsbAccessory acc){
  myParcelFileDescriptor = myUsbManager.openAccessory(acc);
  if(myParcelFileDescriptor != null){
   
   myUsbAccessory = acc;
   FileDescriptor fileDescriptor = myParcelFileDescriptor.getFileDescriptor();
   myFileInputStream = new FileInputStream(fileDescriptor);
   myFileOutputStream = new FileOutputStream(fileDescriptor);
   
   Thread thread = new Thread(myRunnable);
   thread.start();
  }
 }
 
 private void closeUsbAccessory(){
  
  if(myParcelFileDescriptor != null){
   try {
    myParcelFileDescriptor.close();
   } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }
  }
  
  myParcelFileDescriptor = null;
  myUsbAccessory = null;
 }

 @Override
 protected void onPause() {
  super.onPause();
  closeUsbAccessory();
 }

 @Override
 protected void onDestroy() {
  super.onDestroy();
  unregisterReceiver(myUsbReceiver);
 }
 
 private BroadcastReceiver myUsbReceiver = new BroadcastReceiver(){
  
  @Override
  public void onReceive(Context context, Intent intent) {

   String action = intent.getAction();
   if(action.equals(UsbManager.ACTION_USB_ACCESSORY_DETACHED)){
    
    Toast.makeText(MainActivity.this, "onReceive: ACTION_USB_ACCESSORY_DETACHED", Toast.LENGTH_LONG).show();
    
    UsbAccessory usbAccessory = UsbManager.getAccessory(intent);
    
    if(usbAccessory!=null && usbAccessory.equals(myUsbAccessory)){
     closeUsbAccessory();
    }
   }
  }
 };

 private void sendText(String text){

  byte[] buffer = text.getBytes();

  if(myFileOutputStream != null){
   
   try {
    myFileOutputStream.write(buffer);
   } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   } 
  }
 }

}


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:orientation="vertical"
    tools:context=".MainActivity" >

    <EditText
        android:id="@+id/textout"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"/>
    <Button
        android:id="@+id/btnsend"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Send"/>
    <TextView
        android:id="@+id/textin"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"/>

</LinearLayout>


Please notice that this example have no permission obtained to communicating with the USB device in Java code, but include <intent-filter> of "android.hardware.usb.action.USB_DEVICE_ATTACHED" in AndroidManifest.xml. The result is: When the Android device plus in Arduino Due board, and user click OK to start this App in confirm dialog, it work as expected. If user click Cancel, and then start this app manually, it will be stopped. Permission obtaining feature will be improved in next post, "Request Permission to access USB accessory".



Saturday, March 9, 2013

Hello World ADK: Communication between Arduino Due and Android device

The former post demonstrate half "Pre-Hello World for ADK". It's further implemented to include communication between Arduino Due and Android Device.



  • In Arduino Due side: it monitor any incoming data from accessory, and send it back.
  • In Android side, it will send out the text when Send button clicked. And display the text received from USB.
It implement the function of bi-direction communication between Arduino Due and Android Device.

The code in Arduino side is listed here:
#include "variant.h"
#include <stdio.h>
#include <adk.h>


// Accessory descriptor. It's how Arduino identifies itself to Android.
char applicationName[] = "HelloADK"; // the app on your phone
char accessoryName[] = "Arduino Due"; // your Arduino board
char companyName[] = "Arduino-er";

// Make up anything you want for these
char versionNumber[] = "0.1";
char serialNumber[] = "1";
char url[] = "https://sites.google.com/site/arduinosite/exercise/helloadk/HelloADK_0.1.apk";

USBHost Usb;
ADK adk(&Usb, companyName, applicationName, accessoryName,versionNumber,url,serialNumber);

// Pin 13 has an LED connected on most Arduino boards.
int led = 13;

void setup() {
    Serial.begin(9600);
    cpu_irq_enable();
  
    pinMode(led, OUTPUT);
    //Indicate start of program
    digitalWrite(led, LOW);
    delay(2000);
    digitalWrite(led, HIGH);
    for(int i = 0; i <= 2; i++){
        digitalWrite(led, HIGH);
        delay(250);
        digitalWrite(led, LOW);
        delay(250);
    }
}

#define RCVSIZE 128

void loop() {
  
    char helloworld[] = "Hello World!\r\n";
  
    uint8_t buf[RCVSIZE];
    uint32_t nbread = 0;
  
    Usb.Task();
    
    if (adk.isReady()){
        digitalWrite(led, HIGH);
        
        adk.read(&nbread, RCVSIZE, buf);
        if (nbread > 0){
            adk.write(nbread, buf);
        }
        
    }else{
        digitalWrite(led, LOW);
    }
    
}

The Android side code will be shown in next post "Hello World ADK: Android code".

Remark: The example tested run on HTC One with Android 4.1.1, but NOT work on Nexus One with Android 2.3.6.

Tuesday, March 5, 2013

Pre-Hello World for ADK

It's a very simple incomplete "Hello World" for ADK, working on Arduino Due with Android Device.



In Arduino Due side, it simple loop to detect if adk isReady(). If adk ready turn on L led, if not turn it off. Also define the URL to download the app if not installed.

#include "variant.h"
#include <stdio.h>
#include <adk.h>

// Accessory descriptor. It's how Arduino identifies itself to Android.
char applicationName[] = "HelloADK"; // the app on your phone
char accessoryName[] = "Arduino Due"; // your Arduino board
char companyName[] = "Arduino-er";

// Make up anything you want for these
char versionNumber[] = "0.0";
char serialNumber[] = "1";
char url[] = "https://sites.google.com/site/arduinosite/exercise/helloadk/HelloADK_0.0.apk";

USBHost Usb;
ADK adk(&Usb, companyName, applicationName, accessoryName,versionNumber,url,serialNumber);

// Pin 13 has an LED connected on most Arduino boards.
int led = 13;

void setup() {
    Serial.begin(9600);
    cpu_irq_enable();
  
    pinMode(led, OUTPUT);
    //Indicate start of program
    digitalWrite(led, LOW);
    delay(2000);
    digitalWrite(led, HIGH);
    for(int i = 0; i <= 2; i++){
        digitalWrite(led, HIGH);
        delay(250);
        digitalWrite(led, LOW);
        delay(250);
    }
}

void loop() {
  
    Usb.Task();
    
    if (adk.isReady()){
        digitalWrite(led, HIGH);
    }else{
        digitalWrite(led, LOW);
    }
    
}

In the Android side, it only prepare itself as a usb accessory and declare intent-filter of "android.hardware.usb.action.USB_ACCESSORY_ATTACHED". Such that when a matched Arduino connected, it will be pop-up. That's all it done.

New a Android Application Project, Compiler With Google APIs.

Modify AndroidManifest.xml

- add <uses-festure> of "android.hardware.usb.accessory".
- add <uses-library> of "com.android.future.usb.accessory".
- add <intent-filter> to define register action of "android.hardware.usb.action.USB_ACCESSORY_ATTACHED".
- add <meta-data> link to resource of "@xml/myfilter".

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.helloadk"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="17" />
    
    <uses-feature android:name="android.hardware.usb.accessory"/>

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <uses-library android:name="com.android.future.usb.accessory"/>
        <activity
            android:name="com.example.helloadk.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED" />
            </intent-filter>
            <meta-data android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED"
                android:resource="@xml/myfilter"/>
        </activity>
    </application>

</manifest>


Create /res/xml/myfilter.xml to define resource of usb-accessory. Notice that manufacturer of "Arduino-er" match with companyName, model of "HelloADK" match with applicationName, and version of "0.0" match with versionNumber in Arduino side.

<?xml version="1.0" encoding="UTF-8"?>
<resources>
    <usb-accessory
        manufacturer="Arduino-er"
        model="HelloADK"
        version="0.0"/>
</resources>


Next:
- Hello World ADK: Communication between Arduino Due and Android device


Sunday, March 3, 2013

Downloading the ADK 2012 Source


Google ADK 2012 board

The Android Accessory Development Kit (ADK) for 2012 is the latest reference implementation of an Android Open Accessory device, designed to help Android hardware accessory builders and software developers create accessories for Android. The ADK 2012 is based on the Arduino open source electronics prototyping platform, with some hardware and software extensions that allow it to communicate with Android devices.

A limited number of these kits were produced and distributed at the Google I/O 2012 developer conference. If you did not receive one of these kits, fear not! The specifications and design files for the hardware were also released for use by manufacturers and hobbyists. You should expect to see kits with similar features available for purchase, or you can build one yourself!

Downloading the ADK Source on Ubuntu

The support software and hardware specifications for the ADK 2012 are available from the Android source repository. Follow the instructions below to obtain the source material for the ADK.

Before download the source, you have to install curl, git and repo. Refer here.

Then you can download the ADK 2012 Source, enter the commands in Terminal.

$mkdir android-accessories
$cd android-accessories
$repo init -u https://android.googlesource.com/accessories/manifest
$repo sync

Source: http://developer.android.com/tools/adk/adk2.html

After successfully completing this process, you should have the source code and tools for working with the ADK 2012:
  • adk2012/board - Source code and hardware design files for the ADK 2012
  • adk2012/app - Source code for the ADK 2012 Android companion application
  • external/ide - Source code for the ADK 2012 Integrated Development Environment (IDE)
  • external/toolchain - The toolchain used by the ADK 2012 IDE

Google I/O 2012 - ADK 2.0

Introducing the new APIs and capabilities in ADK 2.0, with demos.



Know more: Accessory Development Kit 2012 Guide

Friday, March 1, 2013

Test code for ADK on Arduino Due

Arduino 1.5 BETA come with a ADK Terminal Test example to demonstrates USB Host connectivity between an Android phone and an Arduino Due. The ADK for the Arduino Due is a work in progress. For additional information on the Arduino ADK visit http://labs.arduino.cc/ADK/Index.

To load the ADK Terminal Test example, select File in Arduino IDE -> Examples -> USBHost -> ADKTerminalTest.

Open ADK Terminal Test
Open ADK Terminal Test

BUT...it not work in my case! The function Serial.begin(9600) have to be called at the beginning of setup(). After then, it work as expected (view the video). From the thread http://arduino.cc/forum/index.php?PHPSESSID=13eedea106bcfa79b016f120f99a8f34&topic=129390.0

ADKTerminalTest
ADKTerminalTest

/*

 ADK Terminal Test

 This demonstrates USB Host connectivity between an 
 Android phone and an Arduino Due.

 The ADK for the Arduino Due is a work in progress
 For additional information on the Arduino ADK visit 
 http://labs.arduino.cc/ADK/Index

 created 27 June 2012
 by Cristian Maglie

*/

#include "variant.h"
#include <stdio.h>
#include <adk.h>

// Accessory descriptor. It's how Arduino identifies itself to Android.
char applicationName[] = "Arduino_Terminal"; // the app on your phone
char accessoryName[] = "Arduino Due"; // your Arduino board
char companyName[] = "Arduino SA";

// Make up anything you want for these
char versionNumber[] = "1.0";
char serialNumber[] = "1";
char url[] = "http://labs.arduino.cc/uploads/ADK/ArduinoTerminal/ThibaultTerminal_ICS_0001.apk";

USBHost Usb;
ADK adk(&Usb, companyName, applicationName, accessoryName,versionNumber,url,serialNumber);

void setup()
{
        Serial.begin(9600);  //<-- need to add
  
 cpu_irq_enable();
 printf("\r\nADK demo start\r\n");
 delay(200);
}

#define RCVSIZE 128

void loop()
{
 uint8_t buf[RCVSIZE];
 uint32_t nbread = 0;
 char helloworld[] = "Hello World!\r\n";

 Usb.Task();

 if (adk.isReady())
 {
  /* Write hello string to ADK */
  adk.write(strlen(helloworld), (uint8_t *)helloworld);

  delay(1000);

  /* Read data from ADK and print to UART */
  adk.read(&nbread, RCVSIZE, buf);
  if (nbread > 0)
  {
   printf("RCV: ");
   for (uint32_t i = 0; i < nbread; ++i)
   {
    printf("%c", (char)buf[i]);
   }
   printf("\r\n");
  }
 }
}





update@2013-06-17:

Similar Android example with source code found, refer:


Cabling to connect Arduino Due with Android device

In order to connect Arduino Due with Android device to achieve ADK function, a Micro USB OTG Cable is needed, connected to Native USB Port of Arduino Due. Another normal USB cable is used to connect the USB OTG Cable and Android device. In such connection, the Arduino Due act as host, the Android act as accessory.

Connect Arduino Due and Android device with OTG USB Cable
Connect Arduino Due and Android device with OTG USB Cable

ADK running on Arduino Due

After two day of try and test, I finally get the Arduino Due ADK sample sketch Arduino 1.5 BETA work on Arduino Due Board, link with HTC One X.


In coming post, I will explain about:

Related:
- My own Hello World ADK: Communication between Arduino Due and Android device


Friday, February 15, 2013

Arduino MEGA ADK R3 for Android

Arduino MEGA ADK R3 for Android

  • The Arduino ADK is a microcontroller board based on the ATmega2560
  • It has a USB host interface to connect with Android based phones, based on the MAX3421e IC
  • For information on using the board with the Android OS, see Google's ADK documentation.
  • Android Development Board
  • R3 board