Category: Main page » Arduino

USB data transfer between Android and Arduino

In a previous articles we looked at control an Arduino from Android device and control an .

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.

Ultrasonic Distance Sensor

Arduino Code

#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); 
  }
}

Android code

For our Activity we need following elements: TextView, Button, ProgressBar and ImageView.

Graphical Layout

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.

-->