Arduino Android USB Serial Communication With OTG Cable

by vamsikurre in Circuits > Software

188745 Views, 75 Favorites, 0 Comments

Arduino Android USB Serial Communication With OTG Cable

title.jpg
_DSC7769.jpg
_DSC7771.jpg
20160117_144704.jpg

I have made an Arduino based night lamp using photo resistor and problem with that is light levels was different from place to place, when I am testing I have used a value as a threshold to switch on the light and after fixing it in its final position that value is way off.

So, to get the correct value I have to data log the photo resistor reading after fixing the light in place, which was a bit harder, because I cannot leave my laptop outside for data logging for a whole day. So I need a portable solution to my problem.

Another project was, water supply near my place was limited, we get water only at fixed timings. so I made a device to turn on water motor at a fixed timings of day. I haven’t made any user interface for that device to change timings because timings get to change very infrequently. So I need a way to change timings without connecting laptop and recompiling Arduino code, that would be complicated for my parents.

So I decided to make an android app that would send serial data to Arduino to change timings of water motor.

In this instructable, I will explain how to create an android app that can communicate with Arduino by USB OTG cable, If you dont care about how to just download .apk file and install it in your phone to communicate with arduino.

Downloads

Downloading Android Studio

Screenshot (295).png
Screenshot (297).png
Screenshot (298).png
  1. Get the android studio from http://developer.android.com/sdk/index.html
  2. Click on “download android studio” button to start downloading
  3. Agree to terms and conditions and your download should start

File will be an exe file and size would be around a gig

Installing Android Studio

Untitled2.png
Untitled3.png
Untitled4.png
Untitled5.png
Untitled6.png
Untitled7.png
Untitled8.png
Untitled9.png
Untitled10.png
Untitled11.png
Untitled12.png
Untitled13.png

Install the exe file by going through some basic installation steps

At the end it will install latest SDK version automatically, let it complete.

Finally you should get welcome screen for android studio.

Setting Up Android Studio

1.png
2.png
3.png
44.png
55.png
Screenshot_2016-01-26-14-42-19.jpg

In the welcome screen you should see configure button, by selecting it you should go to configuration page. There first option would be “SDK Manager”, by clicking that a new window will open by showing the details of current SDK. There would be an option to “launch standalone SDK Manager“, by clicking that good old SDK manager will be opened there you can add new SDK tool as required.

Android studio has an emulator to test the android code, but unfortunately we cannot use that for this scenario because this involves a physical device talking to another device. Instead we can use an android phone itself to debug the code.

Since we are using android device to debug the code we can just download “SDK Platform” of that specific version of the device, first know the android OS version of the phone. In my case I am using Samsung note3 which has 5.0 (lollipop) so just download “SDK Platform” from “Android 5.0.1 (API 21)” that should be enough.

About the Library

Untitled.png

The library I was using to make the communication is called physicaloid from http://www.physicaloid.com/ which was last updated 2 years ago and final update was not working (for me at least). So after discussing with people in github repository I managed to get the old working jar file for that library.

By using this library we can not only communicate with Arduino but we can upload compiled hex files into Arduino, this library has avrdude functionality built-in.

Creating New Project in Android Studio

Untitled13.png
Untitled14.png
Untitled15.png
Untitled16.png
Untitled17.png
Untitled18.png
Untitled19.png

First I want to make an app that looks same as Arduino's serial monitor window.

In the welcome screen of android studio there will be an option to create new project, select “Start a new android studio project”

In the next page give your project name and location, then click next

In the next page select the platform for which we are developing application and select correct version of your phone and click next

In the next page by default “Blank activity” will be selected and leave it as it is for now. And in the next page name your activity (your main screen in the app).

Then click finish, newly created project will be opened in android studio and we can work on it now

Adding Library to New Project

Untitled19.png
Untitled20.png
Untitled21.png
Untitled22.png
Untitled23.png
Untitled24.png
Untitled25.png
Untitled26.png
Untitled27.png
Untitled29.png
Untitled30.png
Untitled31.png

In the top left side of the main screen there will be a drop down menu ladled as android, change the option to project to see the directory structure of the project.

In the directory structure by expanding “app” folder you can find lib folder that is the default folder to place our libraries.

Copy the physicaloidlibrary.jar file and paste it in libs folder

After pasting click “sync project with gradle files” button on the top.

Now the library is added we can use its features in our code.

Main activity that was automatically created when we first created project will be located in
App > src > main > java > YOUR_ACTIVITY

And layout will be located at

App > src > main > res > layout > activity_serial_monitor.xml

Editing Manifest.xml

Untitled34.png

Manifest file is like main properties file for our project, It contains permissions details and activity details

Manifest file is located in App > src > main > AndroidManifest.xml

Open the file and add

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

Line above

my manifest file looks like

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

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

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity
            android:name=".Serial_monitor"
            android:label="@string/app_name"
            android:theme="@style/AppTheme.NoActionBar">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>

By adding that line we are asking permission of the user every time we connect a USB device to OTG port

Designing Layout

Untitled33.png
Untitled32.png
Untitled31.png
Untitled35.png
Untitled39.png
Untitled40.png
Untitled41.png

Editing should be done in “content_serial_monitor.xml” file

I have dragged 3 buttons, 1 edit text, 1 text view on to screen then renamed and placed them in correct order.

Open – opens the connection to USB device

Close – closes the connection to USB device

Send – sends data to Arduino

I also added a spinner to select baud rate and auto scroll feature as available in serial monitor

Added this string array to strings.xml file located in app > src > main > res > values > strings.xml

<resources>
    <string name="app_name">Serial Monitor</string>
    <string name="action_settings">Settings</string>
    <string name="baud_prompt">Choose Baudrate</string>
    <string-array name="baud_arrays">
        <item>300 baud</item>
        <item>1200 baud</item>
        <item>2400 baud</item>
        <item>4800 baud</item>
        <item>9600 baud</item>
        <item>19200 baud</item>
        <item>38400 baud</item>
        <item>576600 baud</item>
        <item>744880 baud</item>
        <item>115200 baud</item>
        <item>230400 baud</item>
        <item>250000 baud</item>
    </string-array>
</resources>

Lets add good icon to our app

right click on the app > new > image asset

now browse the image file you want and set it as ic_launcher it will override the default android icon

Adding Code to UI Elements

Untitled36.png

I have attached complete java file Serial_monitor.java first download it and compare it to these small code segments.

First we have create all our UI elements and library variables

    Button btOpen, btClose,  btWrite;
    EditText etWrite;
    TextView tvRead;
    Spinner spBaud;
    CheckBox cbAutoscroll;

    Physicaloid mPhysicaloid; 		// initialising library

next, in onCreate method we can initialise those variables we have created

        btOpen  = (Button) findViewById(R.id.btOpen);
        btClose = (Button) findViewById(R.id.btClose);
        btWrite = (Button) findViewById(R.id.btWrite);
        etWrite = (EditText) findViewById(R.id.etWrite);
        tvRead  = (TextView) findViewById(R.id.tvRead);
        spBaud = (Spinner) findViewById(R.id.spBaud);
        cbAutoscroll = (CheckBox)findViewById(R.id.autoscroll);

        mPhysicaloid = new Physicaloid(this); 		// setting the context for library

now we can display Required UI elements on screen, I am calling a method to do this

That method takes boolean argument which specifies weather app is connected to Arduino or not

setEnabledUi(false); // not connected to Arduino so false

//setEnabledUi method to set UI elements on screen
private void setEnabledUi(boolean on) {
        if(on) {                            // if connected to device
            btOpen.setEnabled(false);       //hide open button (already opened)
            spBaud.setEnabled(false);       //hide baudrate selector
            cbAutoscroll.setEnabled(false); // hide autoscroll
            btClose.setEnabled(true);       // display close button
            btWrite.setEnabled(true);       // display send button
            etWrite.setEnabled(true);       // display edittext field
        } else {                            // if not connected to device
            btOpen.setEnabled(true);        //display open button
            spBaud.setEnabled(true);        //display baudrate selector
            cbAutoscroll.setEnabled(true);  //display autoscroll
            btClose.setEnabled(false);      // hide close button (already closed)
            btWrite.setEnabled(false);      // hide send button
            etWrite.setEnabled(false);      // hide edittext field
        }
    }

Now we displayed everything as needed, now we can add actions to our buttons.

listener method for open button, In this method we cover baudrate setting, autoscroll option and connecting to device.

 public void onClickOpen(View v) {
	// setting the baudrate based on spinner
        String baudtext = spBaud.getSelectedItem().toString(); 	// get the text from spinner
	//switch statement to check for baud rate
        switch (baudtext) {
            case "300 baud":
                mPhysicaloid.setBaudrate(300);
                break;
            case "1200 baud":
                mPhysicaloid.setBaudrate(1200);
                break;
            case "2400 baud":
                mPhysicaloid.setBaudrate(2400);
                break;
            case "4800 baud":
                mPhysicaloid.setBaudrate(4800);
                break;
            case "9600 baud":
                mPhysicaloid.setBaudrate(9600);
                break;
            case "19200 baud":
                mPhysicaloid.setBaudrate(19200);
                break;
            case "38400 baud":
                mPhysicaloid.setBaudrate(38400);
                break;
            case "576600 baud":
                mPhysicaloid.setBaudrate(576600);
                break;
            case "744880 baud":
                mPhysicaloid.setBaudrate(744880);
                break;
            case "115200 baud":
                mPhysicaloid.setBaudrate(115200);
                break;
            case "230400 baud":
                mPhysicaloid.setBaudrate(230400);
                break;
            case "250000 baud":
                mPhysicaloid.setBaudrate(250000);
                break;
            default: 		// default is 9600
                mPhysicaloid.setBaudrate(9600);
        }

        if(mPhysicaloid.open()) { 	// tries to connect to device and if device was connected
            setEnabledUi(true);

            if(cbAutoscroll.isChecked()) { 	// if auto scroll was selected
                tvRead.setMovementMethod(new ScrollingMovementMethod());
            }   

	   // read listener, When new data is received from Arduino add it to Text view
            mPhysicaloid.addReadListener(new ReadLisener() {
                @Override
                public void onRead(int size) {
                    byte[] buf = new byte[size];
                    mPhysicaloid.read(buf, size);
                    tvAppend(tvRead, Html.fromHtml("<font color=blue>" + new String(buf) + "</fon                     t>")); 		// add data to text viiew
                }
            });

        } else {
		//Error while connecting
            	Toast.makeText(this, "Cannot open", Toast.LENGTH_LONG).show();
        }
    }

tvAppend method to write received data to Textview

Handler mHandler = new Handler();
    private void tvAppend(TextView tv, CharSequence text) {
        final TextView ftv = tv;
        final CharSequence ftext = text;
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                ftv.append(ftext); 	// add text to Text view
            }
        });
    }

Listener for close button

public void onClickClose(View v) {	//when close button is pressed
        if(mPhysicaloid.close()) { 	//close the connection to arduino
            mPhysicaloid.clearReadListener();	//clear read listener
            setEnabledUi(false);	// set UI accordingly
        }
    }

Listeener for Send button

 public void onClickWrite(View v) { 	// when send button is prressed
        String str = etWrite.getText().toString()+"\r\n";	//get text from EditText
        if(str.length()>0) {
            byte[] buf = str.getBytes();	//convert string to byte array
            mPhysicaloid.write(buf, buf.length);	//write data to arduino
        }
    }

That's all everything is completed just connect your phone and run the program it should install and open.

Testing the App

1.jpg
2.jpg
3.jpg

Now connect phone and run the code by using play button on the top, now device chooser dialogue pops up and ask's in which device should this app install.

Note: if you did not find your phone in the list try reinstalling the phone drivers.

If chosen correctly app should automatically install on phone make some necessary adjustments to UI.

Run some test code and upload to arduino

void setup()
{  
 // Open serial communications and wait for port to open:
//  Serial.begin(1200);
//  Serial.begin(2400);
//  Serial.begin(4800);
  Serial.begin(9600);
//  Serial.begin(14400);
//  Serial.begin(19200);
//  Serial.begin(38400);
//  Serial.begin(57600);
//  Serial.begin(115200); 
}
void loop()
{
  while(Serial.available() > 0) {
    Serial.write(Serial.read());
  }
}

Disconnect the phone from pc and connect to Arduino with OTG cable, and send some data it should come back

Downloads

Other Uses

Untitled42.png
Screenshot_2016-01-26-21-25-41.jpg
Screenshot_2016-01-26-21-25-50.jpg

You can modify the layout and code to suit your needs and make an app for each device you make separately

For example I have modified same project to work as a Interface for my motor timer controller.

This can also be used for communicating with raspberry pi serial interface using USB to UART converter as shown in adafruits https://learn.adafruit.com/adafruits-raspberry-pi-lesson-5-using-a-console-cable tutorial.

Downloads