Arduino Android USB Serial Communication With OTG Cable

142,572

64

34

Introduction: Arduino Android USB Serial Communication With OTG Cable

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.

Step 1: Downloading Android Studio

  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

Step 2: Installing Android Studio

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.

Step 3: Setting Up Android Studio

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.

Step 4: About the Library

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.

Step 5: Creating New Project in Android Studio

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

Step 6: Adding Library to New Project

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

Step 7: Editing Manifest.xml

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

Step 8: Designing Layout

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

Step 9: Adding Code to UI Elements

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.

Step 10: Testing the App

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

Step 11: Other Uses

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.

Full Spectrum Laser Contest 2016

Participated in the
Full Spectrum Laser Contest 2016

Digital Life 101 Challenge

Participated in the
Digital Life 101 Challenge

Be the First to Share

    Recommendations

    • The 1000th Contest

      The 1000th Contest
    • Battery Powered Contest

      Battery Powered Contest
    • Hand Tools Only Challenge

      Hand Tools Only Challenge

    34 Discussions

    0
    abbottanp1369
    abbottanp1369

    3 months ago

    When the Serial_monitor.apk is installed (Samsung Tab2) and then invoked with OTG-Arduino Uno the only thing that happens is the "Serial monitor has stopped." message is popped with a query "Restart app." Its a pleasure to test your work for you.

    Bottom-line it appears to be a waste of time.

    0
    MakeMat
    MakeMat

    Reply 2 months ago

    4 years and a half is just too long a period in computer science... the apk doesn't launch anymore on android 9. I'll try the long way by writing the code following the example: this tutorial is still a great help to start using Android Studio.

    0
    abbottanp1369
    abbottanp1369

    Reply 2 months ago

    MakeMat, tell me about it, I have code still floating around from Window3.2 which occasionally prompts a "user's query. Your work was still beneficial because it eventually pointed my to another slightly more helpful solution. Although I could not use Hariharan Mathavan solution: https://www.allaboutcircuits.com/projects/communi... a spike proved that it worked and that it could be "reused" to help with my need. His solution uses Hans Felhr's library rather than the Physicaloid library. UsbSerial Library https://www.allaboutcircuits.com/projects/communi...

    Bottom-bottom-line: Thanks for being a pathfinder and taking the risk to broadcast your work.

    p011_assy_btnTest.pngp019_test_assy.png
    0
    QuangT27
    QuangT27

    3 months ago

    Arduino mega2560 : "can not open" , Android 5.1.1

    0
    georgequine
    georgequine

    6 months ago

    Receiving 'cannot open' message when clicking Open. Receive nothing when clicking send - can someone please get back to me?

    0
    ablazekhn
    ablazekhn

    1 year ago

    Thanks for this code......
    Is it only for main activity??
    I am trying to get system time and send to arduino serial it is not working.

    0
    biswajitr_
    biswajitr_

    1 year ago

    Your app doesn't even start. Rest is futile, dear !

    0
    jbray12
    jbray12

    1 year ago

    Thanks - that was a very useful primer on how to install Android Studio and get started writing code - even if I'm also having a "cannot open" issue. I note that the LEDs which are normally on when the arduino is plugged into the computer are not on in this case, so it might be a lack of power (the Bluno I'm using needs 7 volts DC) - think I've seen OTG cables which supply extra juice which might do it.

    0
    vit1967
    vit1967

    2 years ago

    the
    sketch and the cable work fine, since messages from the built-in "terminal" in
    the ArduinoDroid application are returned successfully. But your android program returns only "Cannot Open". :( Huaway Honor 9 Lite LLD-L31 Android 8.0 sdk26
    After adding

    <intent-filter>
    <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
    </intent-filter>

    in manifest ,

    nothing changed

    0
    Kaviyashiva
    Kaviyashiva

    2 years ago

    Most needed one for me. And I have to connect ch340g to the mobile app ,is it possible with APP INVENTOR 2? please help me.

    0
    ahmedmahrous
    ahmedmahrous

    Question 2 years ago

    I am trying to use this tutorial to interface with another usb device through OTG cable but i don't want to connect always says "can't open" although i changed the vendor and product id. can you please let me know if i should modify anything else ? (Note: my device that i want to communicate with only reply when i send something to it, not like arduino always sending data from start)

    0
    ChaymaL
    ChaymaL

    Question 2 years ago on Step 10

    the problem i get is the "not found " is it due to the library ?

    0
    장우석
    장우석

    2 years ago

    Thank you for your information.

    Actually, I'm having trouble in getting permission from Android.

    When I plugging in a USB cable, the App pops up and runs well.

    While the USB cable left as it was, I turn off my app manually and launch it again, then the communication is not going well.

    So I have to unplug and plug again to communicate with my Arduino.

    Any advices are welcome! please help.

    Thank you.

    1
    karthikJ25
    karthikJ25

    3 years ago

    Can this library be used to send text to PC via a USB to serial converter?.
    I tried, but the app stops working, is this a mistake from my side?

    0
    behmoh
    behmoh

    3 years ago

    excellent and fantastic

    0
    Mad_MaxT
    Mad_MaxT

    3 years ago

    Nice project working for Arduino Mega (drivers from Arduino Inc.), but not working for my Nano Board (uses CH340 ) which has drivers from wch.cn .Please suggest a solution for this issue.

    0
    mesora
    mesora

    3 years ago

    hi there, thank you very much for your work and effort!

    unfortunately i've the same "cannot open" issue as others few days ago.
    i just spent hours to check every single step and cannot find the problem.

    i've a galaxy s6 (SM-G920F) with android 5.1.1. please help

    0
    mesora
    mesora

    Reply 3 years ago

    Still trying to find the problem, is it possibly because i don't use an arduino but a Nodemcu v3 board (ESP8266)?

    it's arduino compatible so if, then only the USB_Vendor could be wrong.. how to find and where to replace the NodeMCU vendor_id?

    or am i wrong?

    0
    DreamW2
    DreamW2

    3 years ago

    Can anyone help me to make a function that receives data in Android so I can call it on other activities and use that data there?