In a previous articles we looked at control an Arduino from Android device and control an Android device from Arduino.
In this article we will discuss how to implement two-way data transfer between Android and Arduino in MicroBridge mode (ADB over USB). For this, we make a simple circuit using a Ultrasonic Distance Sensor and Piezo Buzzer.

#include#include Connection * connection; // Adb connection. #define COMMAND_SEND_TRUE 1 // allow transfer #define COMMAND_SEND_FALSE 2 // disallow transfer #define COMMAND_PLAY_BEEP 3 // buzzer ON const int numOfReadings = 10; // number of readings to take/ items in the array int readings[numOfReadings]; // stores the distance readings in an array int arrayIndex = 0; // arrayIndex of the current item in the array int total = 0; // stores the cumlative total int averageDistance = 0; // stores the average value // setup pins and variables for DYP_ME007 sonar device int echoPin = 2; // DYP_ME007 ECHO pin int initPin = 3; // DYP_ME007 TRIG pin int BeeperPin = 8; // Buzzer pin unsigned long pulseTime = 0; // stores the pulse in Micro Seconds unsigned long distance = 0; // variable for storing the distance (cm) boolean SendToAndroid = false; void setup() { pinMode(initPin, OUTPUT); pinMode(echoPin, INPUT); pinMode(BeeperPin, OUTPUT); // Buzzer // create array loop for (int thisReading = 0; thisReading < numOfReadings; thisReading++) { readings[thisReading] = 0; } Serial.begin(115200); // Initialization ADB. ADB::init(); // Open an ADB stream to the phone's shell. Auto-reconnect. Use any unused port number eg:4568 connection = ADB::addConnection("tcp:4568", true, adbEventHandler); } void loop() { if(SendToAndroid == true) makeDimension(); ADB::poll(); // Poll the ADB subsystem. } void adbEventHandler(Connection * connection, adb_eventType event, uint16_t length, uint8_t * data) { if (event == ADB_CONNECTION_RECEIVE) // Если приняли данные { Serial.print("data:"); // for Debug Serial.println(data[0],DEC); if((data[0]) == COMMAND_SEND_TRUE) SendToAndroid = true; // Transfer - true else if ((data[0]) == COMMAND_SEND_FALSE) SendToAndroid = false; else if ((data[0]) == COMMAND_PLAY_BEEP) playBeep(); } else if (event == ADB_CONNECTION_OPEN) Serial.println("ADB connection open"); else if (event == ADB_CONNECTION_CLOSE) Serial.println("ADB connection close"); else { Serial.println(event); } } void makeDimension() { for (int i = 0; i < numOfReadings; i++) { digitalWrite(initPin, HIGH); // send 10 microsecond pulse delayMicroseconds(10); digitalWrite(initPin, LOW); pulseTime = pulseIn(echoPin, HIGH); // look for a return pulse, it should be high as the pulse goes low-high-low distance = pulseTime/58; // Distance = pulse time / 58 to convert to cm. total= total - readings[arrayIndex]; readings[arrayIndex] = distance; total= total + readings[arrayIndex]; arrayIndex = arrayIndex + 1; // At the end of the array (10 items) then start again if (arrayIndex >= numOfReadings) { arrayIndex = 0; } //Serial.println(distance, DEC); } averageDistance = total / numOfReadings; // calculate the average distance //Serial.println(averageDistance, DEC); connection->write(2,(uint8_t*)&averageDistance); // Send 2 bytes to Android delay(10); } void playBeep() { // Buzzer for (int j = 0; j < 10; j++) { analogWrite(BeeperPin, 20); delay(50); analogWrite(BeeperPin, 0); delay(150); } }
For our Activity we need following elements: TextView, Button, ProgressBar and ImageView.

Source code of MainActivity:
package com.example.arduino54;
import java.io.IOException;
import org.microbridge.server.Server;
import org.microbridge.server.AbstractServerListener;
import com.example.arduino54.R;
import android.os.AsyncTask;
import android.os.Bundle;
import android.app.Activity;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Button;
public class MainActivity extends Activity {
private int Distance = 0;
public final String APP_NAME = "arduino54";
public final byte COMMAND_SEND_TRUE = 1; // Allow data transfer
public final byte COMMAND_SEND_FALSE = 2; // Disallow data transfer
public final byte COMMAND_PLAY_BEEP = 3; // Buzzer ON
public final int SYS_COMMAND_DATA = 0; // internal command: data transfer
public final int SYS_COMMAND_CONNECTED = 1; // internal command: ClientConnect
public final int SYS_COMMAND_DISCONNECTED = 2; // internal command: ClientDisconnect
Server server = null;
ImageView connectedImage;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Create TCP server (MicroBridge LightWeight)
try
{
server = new Server(4568); //port
server.start();
} catch (IOException e)
{
Log.e(APP_NAME, "Unable to start TCP server", e);
System.exit(-1);
}
connectedImage = (ImageView) findViewById(R.id.imageConnected);
connectedImage.setAlpha(20);
Button Button1 = (Button)findViewById(R.id.button1);
Button1.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
try
{
server.send(new byte[] {(byte) COMMAND_SEND_TRUE}); //Send data
//Log.d(APP_NAME, "data_send:"+bSend);
} catch (IOException e)
{
Log.e(APP_NAME, "Problem sending TCP message", e);
}
}
});
server.addListener(new AbstractServerListener() {
@Override
public void onReceive(org.microbridge.server.Client client, byte[] data)
{
Log.d(APP_NAME, "data0:"+data[0]+"; data1:"+data[1]);
if (data.length<2) Log.e(APP_NAME, "The data less than 2 bytes:"+data.length);
else {
try
{
server.send(new byte[] {(byte) COMMAND_SEND_FALSE}); //Send data
} catch (IOException e)
{
Log.e(APP_NAME, "Problem sending TCP message", e);
}
}
Distance = ((data[1] << 8) | (data[0] & 0xFF)); // Make a word from two bytes
//Any update to UI can not be carried out in a non UI thread like the one used
//for Server. Hence runOnUIThread is used.
runOnUiThread(new Runnable() {
//@Override
public void run() {
new UpdateData().execute(Distance,SYS_COMMAND_DATA);
}
});
}
//@Override
public void onClientConnect(org.microbridge.server.Server server, org.microbridge.server.Client client){
Log.d(APP_NAME, "ClientConnected");
runOnUiThread(new Runnable() {
public void run() {
new UpdateData().execute(0,SYS_COMMAND_CONNECTED);
}
});
}
public void onClientDisconnect(org.microbridge.server.Server server, org.microbridge.server.Client client){
Log.d(APP_NAME, "ClientDisconnected");
runOnUiThread(new Runnable() {
public void run() {
new UpdateData().execute(0,SYS_COMMAND_DISCONNECTED);
}
});
}
});
}
@Override
protected void onDestroy (){
super.onDestroy();
server.stop();
}
class UpdateData extends AsyncTask {
// Called to initiate the background activity
@Override
protected Integer[] doInBackground(Integer... ArdState) {
if((ArdState[0] < 20) && (ArdState[0] != 0)){ //If distance less then 20cm, send command to Arduino for Buzzer ON
try
{
server.send(new byte[] {(byte) COMMAND_PLAY_BEEP});
} catch (IOException e)
{
Log.e(APP_NAME, "Problem sending TCP message", e);
}
}
return (ArdState); //return to onPostExecute()
}
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
// Not used in this case
}
@Override
protected void onPostExecute(Integer... result) {
Log.d(APP_NAME, "onPostExecute[0]:"+result[0]);
Log.d(APP_NAME, "onPostExecute[1]:"+result[1]);
if(result[1] == SYS_COMMAND_CONNECTED){
connectedImage.setAlpha(255);
}
else if(result[1] == SYS_COMMAND_DISCONNECTED){
connectedImage.setAlpha(20);
}
TextView txt_Distance_Arduino = (TextView) findViewById(R.id.textDistance);
txt_Distance_Arduino.setText(String.valueOf(result[0]+" cm")); // Print distance on the Activity
ProgressBar mProgressBar = (ProgressBar)findViewById(R.id.progressBar1);
mProgressBar.setProgress(result[0]); // Set distance on the ProgressBar
}
}
}

Video:
Download source code for Arduino, Android and Libraries
Author: Koltykov A.V.