Статьи

Создание автомобиля с дистанционным управлением с помощью Android Things GPIO

Вещи Android Things GPIO используются для взаимодействия с внешними устройствами. GPIO означает « Входной выход общего назначения» и представляет собой интерфейс для чтения состояния внешнего устройства. В этой статье мы узнаем, как мы можем использовать контакты Android Things GPIO для управления двигателями постоянного тока при создании автомобиля с дистанционным управлением. В конце этой статьи вы создадите автомобиль Android Things, который движется во всех направлениях, и вы можете управлять им с помощью своего смартфона или браузера.

Android Things предоставляет набор API, которые мы можем использовать для взаимодействия с устройствами с двумя состояниями, такими как кнопки или светодиоды, с помощью Android Things GPIO. Используя API Android Things GPIO, мы можем просто прочитать состояние булавки или установить ее значение. Более подробно в этой статье мы рассмотрим, как использовать Android Things GPIO для управления двигателями. Может быть, вы уже знаете, есть и другие способы управления двигателями. С помощью выводов Android Things GPIO мы можем только включать или выключать его, но мы не можем контролировать скорость двигателя. Выводы GPIO имеют только два состояния: включено или высоко и выключено или низко. Если мы хотим иметь больший контроль над двигателями с применением пропорционального управления, мы можем использовать штырьки Android Things PWM.

В любом случае, в этом контексте мы хотим только управлять моторами и включать или выключать их, чтобы мы могли перемещать наш автомобиль с Android-вещами с дистанционным управлением во всех направлениях. Окончательный результат показан на рисунке ниже:

Контакты для Android вещей GPIO

Прежде чем описать, как построить удаленную машину Android Things, полезно дать краткий обзор того, как использовать контакты GPIO. Первым шагом для управления выводом Android Things GPIO является получение ссылки на PeripheralManagerService :

1
PeripheralManagerService service = new PeripheralManagerService();

Следующим шагом является открытие соединения с контактом:

1
pin = service.openGpio(pin_name);

Чтобы узнать, какие выводы являются GPIO, в соответствии с вашей платой Android Things вы можете обратиться к распиновке Android Things. После того, как соединение открыто, мы можем установить значение контакта, используя следующие команды:

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

Чтобы узнать больше о том, как использовать контакты Android Things GPIO, вы можете обратиться к моей книге « Проекты Android Things ».

Прежде чем копаться в деталях проекта, вы должны прочитать мои другие статьи об Android Things:

Как управлять мотором с помощью Android Things

Обычно мы подключаем устройство напрямую к плате Android Things. В любом случае, когда мы используем двигатели, это невозможно, потому что для двигателя может потребоваться гораздо больший ток, который может обеспечить вывод GPIO. В этом случае мы должны обеспечить внешний источник питания и использовать контакты Android Things GPIO для управления двигателем. Кроме того, мы хотим контролировать направление вращения двигателя. По этим причинам рекомендуется использовать простой драйвер двигателя, который упрощает нашу работу.

В этом проекте мы будем использовать L298N простой драйвер, который может управлять двумя двигателями и их направлениями:

Этот драйвер также может управлять двигателями с помощью ШИМ, в любом случае в этом проекте мы не будем использовать эти функции. Используя два вывода Android Things GPIO для каждого двигателя, мы можем контролировать направление его вращения или останавливать его.

Давайте посмотрим, как подключить этот драйвер к плате Android Things. На схеме ниже показано, как подключить контакты GPIO к L298N и двигателям:

Даже если схема может показаться немного сложной, она очень проста: в этом проекте используются четыре разных вывода для Android Things GPIO:

Правый мотор:

  • BCM17
  • BCM27

Левый мотор:

  • BCM23
  • BCM24

Если вы используете плату, отличную от Raspberry Pi3, вы должны изменить названия выводов.

В настоящее время мы можем создать простой класс Java, который управляет двигателями:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
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();
        }
    }
 
}

Этот класс выполняет следующие задачи:

  1. Получает ссылку на PeripheralManagerService
  2. Открывает контакты GPIO
  3. Он установил направления и начальное значение

Кроме того, он определяет четыре различных метода, которые управляют движением автомобиля:

  • Вперед
  • назад
  • Поверните налево
  • Поверните направо

Всеми этими движениями можно управлять включением или выключением каждого штифта, определенного выше.

Это все. Теперь пришло время реализовать, как мы будем управлять автомобилем. Есть несколько вариантов, которые мы можем реализовать для этой цели. Мы могли бы использовать простой веб-сервер с интерфейсом HTML или использовать, например, Android Nearby API или даже соединение Bluetooth.

В этом уроке мы будем использовать простой веб-интерфейс.

Как реализовать HTTP-интерфейс Android Things

Как уже было сказано, мы реализуем HTTP-интерфейс, чтобы использовать его для управления удаленной машиной Android Things. Для реализации простого веб-сервера HTTP мы можем использовать NanoHTTPD, который является простым и легким HTTP-сервером. Для этого необходимо изменить файл build.gradle добавив в него:

1
compile 'org.nanohttpd:nanohttpd:2.2.0'

Теперь давайте создадим новый класс с именем RobotHTTPServer который обрабатывает входящие HTTP-запросы:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
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-сервер получает команду:

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

Сборка приложения для управления удаленным автомобилем Android Things

Последний шаг — это собрать все и склеить эти классы, чтобы мы наконец смогли создать автомобиль с дистанционным управлением Android Things. Для этого необходимо создать MainActivity :

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
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 получает новую команду, он вызывает метод класса, который управляет двигателем для управления двигателями.

Этот простой проект может быть расширен. Мы могли бы добавить набор новых функций, таких как Vision, Machine learning и так далее. По этой причине мы использовали Android Things вместо Arduino или ESP8266.

В конце этой статьи вы узнаете, как взаимодействовать с выводами GPU Android Things и как их включать и выключать. Более того, вы узнали, как использовать моторы. Вся эта информация, которую вы получили, используется для создания вашего первого автомобиля Android Things с дистанционным управлением.
Теперь вы можете играть со своей игрушкой!

Опубликовано на Java Code Geeks с разрешения Франческо Аццолы, партнера по нашей программе JCG. Смотрите оригинальную статью здесь: Создание автомобиля с дистанционным управлением с помощью Android Things GPIO

Мнения, высказанные участниками Java Code Geeks, являются их собственными.