Remote car — Android Things powered

I am continue to explore my way in the IoT world and now it is a time to do some fun! This time I will explain step by step how to create remote car that powered by Android things and controlled from the Android phone with nearby API.


Building the car

To begin with that you will need two DC motors and motor controller or you can buy a kit for doing it. I ordered simple car kit, you can find a lot of them online and L298N dual motor controller for control the motors.

This how it looks after you assembly the kit

After you successfully assembly the kit lets connect everything, you can follow the diagram.

Diagram for connecting DC motors, bridge controller and the Raspberry Pi board.

Lets start programming

Next step after assembly the hardware and connecting all the wires it is a time to write the code that will control the motors. You can read more about basic steps in my previous article if you want to understand better.

As always we will start from adding dependency to our project, we will need those.

dependencies {
provided 'com.google.android.things:androidthings:0.2-devpreview'
compile 'com.google.android.gms:play-services-nearby:10.2.1'
}

Provided needed for using the android things framework and nearby to have communication between the car and the phone to control the car. Now we will continue to the main activity of the Android things module and add this code to the onCreate.

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

connectivityManager = (ConnectivityManager)
getSystemService(CONNECTIVITY_SERVICE);

googleApiClient = new
GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(Nearby.CONNECTIONS_API)
.build();

PeripheralManagerService service = new
PeripheralManagerService();

try {
gpio1 = service.openGpio("BCM6");
gpio1.setDirection(Gpio.DIRECTION_OUT_INITIALLY_LOW);

gpio2 = service.openGpio("BCM13");
gpio2.setDirection(Gpio.DIRECTION_OUT_INITIALLY_LOW);

gpio3 = service.openGpio("BCM19");
gpio3.setDirection(Gpio.DIRECTION_OUT_INITIALLY_LOW);

gpio4 = service.openGpio("BCM26");
gpio4.setDirection(Gpio.DIRECTION_OUT_INITIALLY_LOW);
} catch (IOException e) {
Log.e(TAG, "Error on PeripheralIO API", e);
}
}

We are defining connection to the board GPIO and now we will need to understand what will happened when we will turn on different GPIO’s.

GPIO1:Move the left wheel forward
GPIO2:Move the left wheel backward
GPIO3:Move the right wheel forward
GPIO4:Move the right wheel backward

To move the car we will need to combine different GPIO’s.

private void controll(int value){
try {
switch (value) {
case 1:
gpio1.setValue(true);
gpio4.setValue(true);
break;
case 2:
gpio3.setValue(true);
break;
case 3:
gpio2.setValue(true);
break;
case 4:
gpio2.setValue(true);
gpio3.setValue(true);
break;
case -1:
gpio1.setValue(false);
gpio2.setValue(false);
gpio3.setValue(false);
gpio4.setValue(false);
}
} catch (IOException e) {
Log.e(TAG, e.getMessage());
}
}

When we will pass value to the method the car will move or stop when passing -1.

Last part is to implement the nearby API to control the car, you can read more about it on the documentation page. The important part is to implement the controller command, we are passing bytes and transferring it to int.

@Override public void onMessageReceived(String s, byte[] bytes, boolean b) {
int value = ByteBuffer.wrap(bytes).getInt();
controll(value);
}

Control part

After finishing the car next step is to create a simple application that will control car movement, for that we will need to create simple screen with five buttons (Forward, Backward, Left, Right and Stop). Same way that we had implemented nearby API we will do it on the app side expect one thing that we will send message and not receive.

private void sendCommand(final int value) {
if (!googleApiClient.isConnected()) {
showApiNotConnected();
return;
}

byte[] bytes = new byte[8];
ByteBuffer.wrap(bytes).putInt(value);

Nearby.Connections
.sendReliableMessage(googleApiClient, otherEndpointId, bytes);
}

We will wrap int value to bytes array and pass it through a connection an button press.

This is how it looks in the end

Looks simple, How I am doing it?

I know that most of the things are not trivial and for people without experience with hardware it can take time to understand everything, but don’t worry, you can do it step by step and eventually you will enjoy like a little boy/girl that get a toy that you was wishing so much :)

For do it easier for you I had published example in Github with some other examples, the part that you will be interested are carmodule and carmoduleapp.

First atempt
Final build

If you find this interesting please share and contribute to my project.