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
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
- Get the android studio from http://developer.android.com/sdk/index.html
- Click on “download android studio” button to start downloading
- 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
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
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
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.
Downloads
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
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
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
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
Downloads
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.
Downloads
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
Downloads
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.