Android Things 教程:使用 GPIO 构建远程控制汽车

Android Things GPIO 引脚用于与外部设备进行交互。GPIO 代表通用输入输出,它是读取外部设备状态的接口。在这篇文章中,我们将会发现我们如何使用 Android Things GPIO 引脚来控制直流电机,使我们能够构建一个遥控汽车。在本文的最后,您将构建一个可以全方位移动的 Android Things 汽车,您可以使用智能手机或浏览器来控制它。

Android Things 提供了一系列 API,我们可以使用 Android Things GPIO 与按钮、LED 等双状态的设备进行交互。使用 Android Things GPIO API,我们可以简单地读取引脚的状态或设置其值。更多细节,就在本文中,我们将探讨如何使用 Android Things GPIO 来控制电机。也许你已经知道,还有其他方法来控制电机。使用 Android Things GPIO 引脚,我们可以打开或关闭,但我们无法控制电机的速度。GPIO 引脚只有两种状态:开或关,关或低。如果我们想要更多的控制比例控制的电机,我们可以使用 Android Things PWM 引脚。

无论如何,在这种情况下,我们只想控制电机并打开或关闭,这样我们就可以将我们的 Android Things 遥控汽车全方位地移动。最终结果如题图所示:

Android Things GPIO

在介绍如何构建 Android Things 远程汽车之前,先概述一下如何使用 GPIO 引脚。控制 Android Things GPIO 引脚的第一步是,获取对 PeripheralManagerService 的引用:

PeripheralManagerService service = new PeripheralManagerService();

下一步是打开连接到引脚:

pin = service.openGpio(pin_name);

要知道哪些引脚是 GPIO,根据您的 Android Things 开发板,您可以参考 Android Things 引脚。一旦连接打开,我们可以使用这些命令设置引脚的值:

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

有关如何使用 Android Things GPIO 引脚的更多信息,请参阅我的书 “Android Things Projects”。

如何使用 Android Things 控制电机

通常,我们将设备直接连接到 Android Things 开发板。 无论如何,当我们使用电机时,这是不可能的,因为电机可能需要比 GPIO 引脚更多的电流。在这种情况下,我们必须提供外部电源,并使用 Android Things GPIO 引脚来控制电机。而且,我们要控制电机的旋转方向。由于这些原因,建议使用一个简单的电机驱动器来简化我们的工作。

在这个项目中,我们将使用 L298N,一个简单的驱动程序,可以控制两个电机及其方向。

这个驱动程序也可以使用 PWM 来控制电机,但在这个项目中,我们不会使用这些功能。每个电机使用两个 Android Things GPIO 引脚,我们可以控制其旋转方向或停止。

让我们看看如何将这个驱动程序连接到我们的 Android Things 开发板。下面的模式显示了如何将 GPIO 引脚连接到 L298N 和电机:

电路连接图

即使这个模式看起来有点复杂,但这非常简单:这个项目使用了四种不同的 Android Things GPIO 引脚:

右电机:

  • BCM17
  • BCM27

左电机:

  • BCM23
  • BCM24

如果您使用的不是 Raspberry Pi 3 开发板,则必须更改引脚名称。

在这个时候,我们可以创建一个简单的 Java 类来控制电机:

public class MotorController {
    PeripheralManagerService service = new PeripheralManagerService();
    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();
        }
    }
}

这个类完成这些任务:

  • 它获得对 PeripheralManagerService 的引用。
  • 它打开 GPIO 引脚。
  • 它设定方向和初始值。

此外,它定义了四种不同的方法来控制汽车如何移动:

  • 前进
  • 后退
  • 左转
  • 右转

所有这些动作都可以通过打开或关闭上面定义的每个引脚来控制。

就这样。现在是时候实施我们将如何控制汽车。我们可以为此实现几个选项。 我们可以使用一个简单的具有 HTML 接口的 Web 服务器,或者我们可以使用 Android Nearby API,或者甚至是蓝牙连接。

在本教程中,我们将使用一个简单的 Web 界面。

如何实现一个 Android Things HTTP 接口

如前所述,我们将实现一个 HTTP 接口,所以我们可以使用它来控制 Android Things 远程汽车。为了实现一个简单的 HTTP Web服务器,我们可以使用 NanoHTTPD,它是一个简单轻量级的 HTTP 服务器。要做到这一点,需要修改 build.gradle 文件,并添加:

compile 'org.nanohttpd:nanohttpd:2.2.0'

现在让我们创建一个名为 RobotHTTPServer 的新类来处理传入的 HTTP 请求:

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) {
        Map<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());
    }
..
}

HTML 页面非常简单,由 5 个代表四个方向的按钮和停止按钮组成。

我们将 HTML 页面添加到 assets/ 目录。最后一部分是定义一个 CommandListener,它是每次 HTTP 服务器收到命令时调用的回调函数:

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

组装应用程序来控制 Android Things 遥控车

最后一步是组装所有东西并粘合这些类,以便我们可以最终构建 Android Things 遥控车。为此,有必要创建一个 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();
            }
        });
    }
}

正如你所看到的,代码非常简单,每次 CommandListener 接收到一个新的命令,它调用一个处理马达来控制马达的类的方法。

这个简单的项目可以进一步扩大。 我们可以添加一组新功能,如视觉,机器学习等等。出于这个原因,我们使用 Android Things,而不是 Arduino 或 ESP8266。

您现在知道如何与 Android Things GPIO 引脚进行交互,以及如何打开或关闭它们。 而且,你学会了如何使用电机。您获得的所有这些信息都可以用来构建您的第一个 Android Things 遥控车。

现在你可以玩玩具了!

英语原文链接:https://dzone.com/articles/how-to-use-android-things-gpio-pins-to-build-a-rem

尚未评分
您的评分将帮助我们做出更好的玩法

观光\评论区

Copyright © 2017 玩点什么. All Rights Reserved.