Android Things GPIO pins

Android Things GPIO pins are used to control peripherals. GPIO stands for General Purpose Input Output and it is an interface to read the state of an external device. In this article, we will discover how we can use Android Things GPIO pins to control DC motors. While we will analyze how to use GPIO pins, we will build a remote-controlled car so that you can get a deeper knowledge about how to use Android GPIO pins in a real project. At the end of this article, you will learn how to use Android GPIO pins to control peripherals and you will build an Android Things car that is able to move in all the directions and you can control it using your smartphone or your browser.

Android Things provides a set of APIs we can use to interact with two-state devices like buttons or LEDs using Android Things GPIO. Moreover, through Android Things GPIO API we can simply read the state of a pin or set its value. In more details, in this Android Things tutorial, we will use Android Things GPIO pin to interact with motors. This tutorial uses Android Things with Raspberry Pi as a development and prototyping board, anyway, you can use this project with other Android Things compatible boards as long as you change the GPIO pins reference.

As you may already know, there are other ways to use to control motors. Using Android Things GPIO pins we can only turn it on or off because these pins are two-state pins. Therefore, we can not control the motor velocity.  If we want to have more control over the motors applying a proportional control we can use Android Things PWM pins.

 

In this context, we want only to control the motors turning them on or off so that we can move our Android Things remote controlled car in all directions.

The final result is shown in the picture below:

android things gpio controlled car

Android Things GPIO pins

Before describing how to build an Android Things remote car, it is useful to give an overview of how to use GPIO pins in Android Things. The first step to control an Android Things GPIO pin is getting the reference to the PeripheralManagerService:

PeripheralManager service = PeripheralManager.getInstance();

be aware that the Android Things 1.0 has introduced an incompatibility with previous beta versions. Check the release note to know how more about Android Things 1.0. One important thing that is changed is the way we get the reference to PeripheralManagerService. Before Android Things DP7 you have to use the code shown above while in the Android Things 1.0 you have to use getInstance().

The next step is opening the connection to the pin:

pin = service.openGpio(pin_name);

To know which pins are GPIO, according to your Android Things board, you can referer to the Android Things pinout. As stated before, this project uses Raspberry Pi so the pins referenced here are Raspberry Pi GPIO pins.

Once the connection is open we can set the value of the pin using this commands:

pin.setDirection(Gpio.DIRECTION_OUT_INITIALLY_LOW);
pin.setValue(true); // High

To know more how to use Android Things GPIO pins you can refer to my book “Android Things Projects“.

Before digging into the project details you should read my other articles about Android Things:

How to control a motor using Android Things GPIO pins

Usually, we connect directly the device to the Android Things board. Anyway, when we use motors this is not possible because a motor may require much more current than a GPIO pin can provide. In this case, we have to provide an external source power and use the Android Things GPIO pins to control the state of a motor. Furthermore, we want to control the motor rotation direction. For these reasons, it is advisable to use a simple motor driver that simplifies our work.

In this project, we will use L298N a simple driver that can control two motors and their directions:

L298N driver

This driver supports not the PWM signals too, anyway in this project we will not use this feature.

The L298N driver requires two signals for each motor, therefore it is necessary to use four Android Things GPIO pins. The state combination of these two signals enable us to control the motor directions for each motor:

  • Forward
  • Backward
  • Stop

The schema below shows how to connect the Android Things GPIO pins to the L298N and then the motors to the driver:

 

Android Things GPIO motors

Even if the schema could seem a little bit complex, it is very simples: this project uses four different Android Things GPIO pins:

The Raspberry Pi GPIO pins are:

Right motor:

  • BCM17
  • BCM27

Left motor:

  • BCM23
  • BCM24

If you are using a different board than Raspberry Pi3 you have to change the pin names. You can refer to the official documentation to know how to build a portable  Android Things app.

At this time, we can create a simple java class that handles the motors:

public class MotorController {

    PeripheralManagerService service = new PeripheralManagerService(); // be aware DP7 breaks compatibility
    private Gpio pin1Motor1;
    private Gpio pin2Motor1;

    private Gpio pin1Motor2;
    private Gpio pin2Motor2;

    public MotorController() {
        try {
            // Right
            pin1Motor1 = service.openGpio("BCM17");
            pin2Motor1 = service.openGpio("BCM27");

            // Left
            pin1Motor2 = service.openGpio("BCM23");
            pin2Motor2 = service.openGpio("BCM24");

            pin1Motor1.setDirection(Gpio.DIRECTION_OUT_INITIALLY_LOW);
            pin2Motor1.setDirection(Gpio.DIRECTION_OUT_INITIALLY_LOW);
            pin1Motor2.setDirection(Gpio.DIRECTION_OUT_INITIALLY_LOW);
            pin2Motor2.setDirection(Gpio.DIRECTION_OUT_INITIALLY_LOW);
            
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    public void forward() {
        setPinValues(true, false, false, true);
    }

    public void backward() {
        setPinValues(false, true, true, false);
    }

    public void stop(){
        setPinValues(false, false,false,false);
    }

    public void turnLeft() {
        setPinValues(false, false, false, true);
    }

    public void turnRight() {
        setPinValues(true, false, false, false);
    }

    private void setPinValues(boolean p11, boolean p12, 
                              boolean p21, boolean p22 ) {

        try {
            pin1Motor1.setValue(p11);
            pin2Motor1.setValue(p12);
            pin1Motor2.setValue(p21);
            pin2Motor2.setValue(p22);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

This class accomplishes these tasks:

  1. It gets a reference to the PeripheralManagerService
  2. It opens the GPIO pins
  3. It set the directions and the initial value

Moreover, it defines four different methods that control how the car will move:

  • Forward
  • Backward
  • Turn left
  • Turn right

All these movements can be controlled by turning on or off each pin defined above. In other words, acting on the four Raspberry Pi GPIO pins it is possible to move the car in all the directions.

That’s all. Now, it is time to implement how we will control the car. There are several options we can implement to this purpose. We could use a simple Web server that has an HTML interface or we can use for example Android Nearby API or even a Bluetooth connection.

In this tutorial, we will use a simple Web Interface.

Building an Android Things HTTP interface

As said before, we will implement an HTTP interface so we can use it to control the Android Things remote car.  To implement a simple HTTP Web server, we can use NanoHTTPD that is a simple and light-weight HTTP server. To this purpose, it is necessary to modify the build.gradle file adding:

compile 'org.nanohttpd:nanohttpd:2.2.0'

Now let us create a new class called RobotHTTPServer that handles the incoming HTTP requests:

public class RobotHttpServer extends NanoHTTPD {
 public RobotHttpServer(int port, 
                        Context context, 
                        CommandListener listener) {
        super(port);
        this.context = context;
        this.listener = listener;
        Log.d(TAG, "Starting Server");
        try {
            start();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

   @Override
    public Response serve(IHTTPSession session) {
        Ma<String, String> params = session.getParms();

        String control = params.get("control");
        String action = params.get("btn");

        Log.d(TAG, "Serve - Control ["+control+"] - Action ["+action+"]");

        if (action != null && !"".equals(action))
          listener.onCommand(action);

        return newFixedLengthResponse(readHTMLFile().toString());
    }
..
}

The HTML page is very simple and it is made by 5 buttons that represent the four directions and the stop button.

We will add the HTML page to the assets/ directory. The last part is defining a CommandListener that is the callback function that is invoked everytime the HTTP server receives a command:

 public static interface CommandListener { 
    public void onCommand(String command); 
} 

Assembling the app to control the Android Things  remote controlled car

The last step is assembling everything and gluing these classes so that we can finally build the Android Things remote controlled car. To this purpose, it is necessary to create a MainActivity:

public class MainActivity extends Activity {

    private String TAG = getClass().getName();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Log.d(TAG, "OnCreate...");

        final MotorController mc = new MotorController();
        RobotHttpServer server = new RobotHttpServer(8090, this,
                  new RobotHttpServer.CommandListener() {
            @Override
            public void onCommand(String command) {
                Log.d(TAG, "Command received ["+command+"]");
                if (command.equals("F"))
                    mc.forward();
                else if (command.equals("B"))
                    mc.backward();
                else if (command.equals("S"))
                    mc.stop();
                else if (command.equals("L"))
                    mc.turnLeft();
                else if (command.equals("R"))
                    mc.turnRight();
            }
        });
    }
}

As you can notice, the code is very simple, everytime the CommandListener receives a new command it calls a method of the class that handles motors to control them.

This simple project can be further expanded. We could add a set of new feature like Vision, Machine learning and so on. For this reason, we have used Android Things instead of Arduino or an ESP8266.

At the end of this post, you know how to interact with Android Things GPIO pins and how to turn them on or off. Moreover, you learned how to use motors. All these information you have acquired are used to build your first Android Things remote controlled car.
Now you can play with your toy!

4 COMMENTS

  1. In case I have 1 servo and 4 motors (in which I would like to control their speed) how could this be implemented?
    PWM pind are 4 as I remember.
    Is it possible to control the speed using any other simple GPIO (not I2C, UART, etc)?

  2. SO BASICALLY HOW IS CONTROLLER.HTML PAGE IS USED TO CHANGE THE DIRECTIONS OF THE CAR? LIKE HOW IS IT WORKING? I AM NOT ABLE TO MAKE MY CAR MOVE!

LEAVE A REPLY

Please enter your comment!
Please enter your name here