NxtLib
 
 

 

Smartphone Pilot (Android)

Purpose: Use an Android smartphone as remote control to drive an EV3 vehicle.

The direct mode of EV3 is perfectly adapted to control the motors from a remote device. The BrickGate server running on the EV3 together with the class library EV3JLib for Android hide the IP socket client-server programming code.

For the purpose of the demonstration the user interface is kept very simple and can be adapted easily to your needs with the JDroidLib graphics support. See the JDroidLib website for more information.

tut01

package ch.aplu.ev3pilot;

import
 ch.aplu.android.*;
import
 ch.aplu.android.ev3.*;
import
 android.graphics.Color;

public
 class EV3Pilot extends GameGrid
  
implements GGPushButtonListener, ConnectionListener
{
  
private LegoRobot robot;
  
private Gear gear;
  
private GGPushButton faster;
  
private GGPushButton slower;
  
private GGPushButton left;
  
private GGPushButton right;
  
private GGPushButton stop;
  
private GGTextField textField;
  
private int speed = 0;
  
private final int speedInc = 2;
  
private int direction;
  
private final int directionInc = 5;

  
public EV3Pilot()
  
{
    
super(21, 21, 0);
    
setScreenOrientation(PORTRAIT);
  
}

  
public void main()
  
{
    
String ipAddress = askIPAddress();
    
getBg().clear(Color.BLUE);
    
new GGTextField("EV3 Pilot",
      
new Location(0, 1), true).show();
    
addButtons();
   
    robot 
= new LegoRobot(this, ipAddress);
    
if (!robot.isConnected())
    
{
      
new GGTextField("Connection failed"new Location(4, 19),
        
true).show();
      
return;
    
}
    textField 
= new GGTextField("Connection established"
            new Location(3, 19), true);
    textField.
show();
    gear 
= new Gear();
    robot.
addPart(gear);
    gear.
setSpeed(0);
    
enableButtons();
  
}
  
  
private String askIPAddress()
  
{
    GGPreferences prefs 
= new GGPreferences(this);
    
String oldName = prefs.retrieveString("IPAddress");
    
String newName = null;
    
while (newName == null || newName.equals(""))
    
{
      newName 
= GGInputDialog.show(this"EV3""Enter IP Address",
        oldName 
== null ? "10.0.1.1" : oldName);
    
}
    prefs.
storeString("IPAddress", newName);
    
return newName;
  
}

  
private void addButtons()
  
{
    faster 
= new GGPushButton("faster");
    faster.
setRepeatPeriod(100);
    
addActor(faster, new Location(10, 5));
    slower 
= new GGPushButton("slower");
    slower.
setRepeatPeriod(100);
    
addActor(slower, new Location(10, 15));
    left 
= new GGPushButton("left");
    
addActor(left, new Location(3, 10));
    right 
= new GGPushButton("right");
    
addActor(right, new Location(17, 10));
    stop 
= new GGPushButton("stop");
    
addActor(stop, new Location(10, 10));
  
}

  
private void enableButtons()
  
{
    faster.
addPushButtonListener(this);
    slower.
addPushButtonListener(this);
    left.
addPushButtonListener(this);
    right.
addPushButtonListener(this);
    stop.
addPushButtonListener(this);
  
}

  
public void onPause()
  
{
    
if (robot != null)
      robot.
exit();
    
super.onPause();
  
}

  
public void buttonPressed(GGPushButton button)
  
{
    
if (!robot.isConnected())
    
{
      
showToast("Robot not connected");
      
return;
    
}
    
if (button == faster)
      
faster();
    
if (button == slower)
      
slower();
    
if (button == left)
      
turnLeft();
    
if (button == right)
      
turnRight();
    
if (button == stop)
      
doStop();
  
}

  
public void buttonReleased(GGPushButton button)
  
{
  
}

  
public void buttonClicked(GGPushButton button)
  
{
  
}

  
public void buttonRepeated(GGPushButton button)
  
{
    
if (button == faster)
      
faster();
    
if (button == slower)
      
slower();
    
if (button == left)
      
turnLeft();
    
if (button == right)
      
turnRight();
  
}

  
private void faster()
  
{
    
if (speed < 100)
    
{
      speed 
+= speedInc;
      gear.
setSpeed(speed);
      
doIt();
    
}
  
}

  
private void slower()
  
{
    
if (speed > 0)
    
{
      speed 
-= speedInc;
      gear.
setSpeed(speed);
      
doIt();
    
}
  
}

  
private void doStop()
  
{
    speed 
= 0;
    gear.
setSpeed(0);
    gear.
stop();
  
}

  
private void turnLeft()
  
{
    direction 
+= directionInc;
    
doIt();
  
}

  
private void turnRight()
  
{
    direction 
-= directionInc;
    
doIt();
  
}

  
private void doIt()
  
{
    
double radius;
    
if (direction == 0)
      radius 
= 1000;  // Quasi-straight
    
else
      radius 
= Math.abs(0.1 / Math.sin(Math.toRadians(direction)));
    
if (direction > 0)
      gear.
leftArc(radius);
    
else
      gear.
rightArc(radius);
  
}
  
  
public void notifyConnection(boolean connected)
  
{
    
showToast(connected? 
        "Connection established" : "Connection lost"true);
    
if (!connected)
    
{  
      textField.
hide();      
      
new GGTextField("Connection lost"new Location(4, 19),
         
true).show();
    
}
  
}
}

Compilation/download using the OnlineEditor of PHBern (Bern University of Teacher Education)

Create QR code to download Android app to your smartphone.

downlink source (EV3Pilot.zip).
downlink Android app for installation on a smartphone or emulator.