Создание Bluetooth-джойпада с помощью App Inventor 2

https://alashed-media.s3.eu-north-1.amazonaws.com/wiki/martyncurrey/create-a-bluetooth-joypad-30.png

Здесь мы создаём базовый Bluetooth-джойпад (Classic Bluetooth) для Android-устройства, предназначенный для управления микроконтроллером (Arduino), подключённым к Bluetooth-модулю. Приложение довольно простое. Два экрана: первый — основная панель управления, второй — страница подключения.

При нажатии кнопки CONNECT на главном экране открывается второй экран, позволяющий пользователю подключиться к Bluetooth-устройству. Кнопки направления при нажатии передают коды на Arduino.

App Inventor 2

Приложение создано в App Inventor 2 с использованием Bluetooth Classic.

App Inventor 2 — простой способ начать создавать Android-приложения. Он предназначен в первую очередь для обучения, но с его помощью можно создавать удивительно продвинутые и сложные приложения. App Inventor основан на блоках. Это означает, что программы создаются с помощью визуальных элементов, которые перетаскиваются, а не текста. Он облачный — вы используете веб-браузер.

Я не вдаюсь во все подробности App Inventor и предполагаю, что у вас есть базовый опыт работы с ним. Как минимум, у вас должен быть аккаунт Google и вы должны знать, где находится сайт App Inventor.

Дизайн

Bluetooth-джойпад имеет простой интерфейс и используется в ландшафтном режиме.

  • 4 кнопки направления

  • 3 обычные кнопки

  • индикатор подключения

  • кнопка подключения

https://alashed-media.s3.eu-north-1.amazonaws.com/wiki/martyncurrey/create-a-bluetooth-joypad-30.png

При нажатии кнопки CONNECT открывается второй экран. Второй экран обрабатывает Bluetooth-соединение и скорость обновления.

https://alashed-media.s3.eu-north-1.amazonaws.com/wiki/martyncurrey/create-a-bluetooth-joypad-33.png

Второй экран имеет:

  • кнопку для инициации Bluetooth-подключения

  • ползунок для управления скоростью обновления приложения

  • кнопку BACK для возврата на главный экран

Как и во многих вещах в App Inventor, существуют разные способы получить одинаковый макет. Чтобы макет был максимально простым, я использую строку вверху для индикатора подключения и кнопки меню. Далее 4 столбца для кнопок управления. Всё содержится во внешней вертикальной компоновке, что позволяет легко показывать/скрывать все элементы управления одним действием.

https://alashed-media.s3.eu-north-1.amazonaws.com/wiki/martyncurrey/create-a-bluetooth-joypad-31.jpg
Первые 3 вертикальные компоновки выровнены по центру по вертикали.
Последний столбец выровнен по нижнему краю.
Метки используются как разделители и помогают позиционированию.

Коды управления

Я использую односимвольные коды управления — это упрощает коммуникацию и помогает со скоростью. Вместо одного события нажатия кнопки я использую события «кнопка нажата» и «кнопка отпущена». Это означает, что каждая кнопка требует 2 кода:

Кнопки направления

U — кнопка вверх нажата

u — кнопка вверх отпущена

D — кнопка вниз нажата

d — кнопка вниз отпущена

L — кнопка влево нажата

l — кнопка влево отпущена

R — кнопка вправо нажата

r — кнопка вправо отпущена

Кнопки управления

R — красная нажата

r — красная отпущена

G — зелёная нажата

g — зелёная отпущена

B — синяя нажата

b — синяя отпущена

Кнопка CONNECT запускает внутренние события в приложении и не требует кода.

На стороне Arduino, когда она получает символ «U», она знает, что кнопка вверх нажата, а когда получает символ «u» — что кнопка отпущена. Если получен «U», но не «u», значит кнопка удерживается нажатой. Это удобно, например, при управлении дистанционной машинкой. «U» может означать «ехать вперёд и продолжать, пока не получено «u»». «R» — «поворачивать вправо, пока не получено «r»».

Использование односимвольных кодов также позволяет значительно упростить код Arduino.

App Inventor 2 и Bluetooth

App Inventor позволяет создавать приложения с несколькими экранами, но при использовании Bluetooth есть предостережение. Каждый экран должен иметь собственное Bluetooth-соединение. Это значит, что если мы используем экран 2 для открытия Bluetooth-соединения, после возврата на экран 1 мы уже не подключены. Чтобы обойти это, я использую псевдо-экраны. Приложение будет выглядеть так, будто мы используем 2 экрана, но на самом деле мы используем только 1 и скрываем/показываем элементы, чтобы создать иллюзию смены экранов.

PAGE1_OUTER_VA действует как страница 1, а PAGE2_OUTER_VA — как страница 2. При первом запуске приложения отображается только PAGE1_OUTER_VA. При нажатии кнопки CONNECT PAGE1_OUTER_VA скрывается, а PAGE2_OUTER_VA отображается.

Размер экрана

App Inventor имеет ограничения по размеру экрана и расположению элементов. Хорошая практика — использовать пропорциональные размеры (размер в процентах от экрана, а не в пикселях).

Кнопки направления занимают около 18% ширины экрана, цветные кнопки — 20%. Вы можете изменить размеры по своему вкусу.

Во время разработки я использовал Samsung S7, но также проверял на Sony Compact Z3 и Samsung 7» планшете. Хотя есть небольшие различия в отображении на 3 разных устройствах, общая компоновка одинакова.

Создание макета

Я не описываю каждый шаг работы с App Inventor и ожидаю, что у вас есть опыт работы с ним. Если нет — начните с онлайн-руководств и примеров.

Откройте браузер, перейдите в App Inventor по адресу http://ai2.appinventor.mit.edu/ и начните новый проект Joypad_001. Я добавляю номера версий к имени приложения и увеличиваю их по мере прогресса.

Экран приложения без прокрутки (я обнаружил, что лучше оставить экран прокручиваемым и отключить прокрутку в коде). Установите экран в Landscape и Responsive. Отключите заголовок экрана, сняв флажок TitleVisible. Включите Display hidden components in view.

Затем создайте макет.

https://alashed-media.s3.eu-north-1.amazonaws.com/wiki/martyncurrey/create-a-bluetooth-joypad-31.jpg

Начните с внешних элементов, установите правильное выравнивание, а затем создайте внутренние элементы — кнопки и метки. Или, если хотите, скачайте файл aia с макетом.

Заметки о макете:

Screen1 выровнен по центру, PAGE1_OUTER_VA установлен на 95% ширины — небольшой отступ по бокам.
https://alashed-media.s3.eu-north-1.amazonaws.com/wiki/martyncurrey/create-a-bluetooth-joypad-32.jpg https://alashed-media.s3.eu-north-1.amazonaws.com/wiki/martyncurrey/create-a-bluetooth-joypad-37.jpg

VerticalArrangement1, VerticalArrangement2, VerticalArrangement3

https://alashed-media.s3.eu-north-1.amazonaws.com/wiki/martyncurrey/create-a-bluetooth-joypad-38.jpg

VerticalArrangement4

https://alashed-media.s3.eu-north-1.amazonaws.com/wiki/martyncurrey/create-a-bluetooth-joypad-34.jpg

BTN_CONNECT_PAGE размер: высота 12%, ширина 18%.

https://alashed-media.s3.eu-north-1.amazonaws.com/wiki/martyncurrey/create-a-bluetooth-joypad-35.jpg

Кнопки направления: высота 30%, ширина 18%.

https://alashed-media.s3.eu-north-1.amazonaws.com/wiki/martyncurrey/create-a-bluetooth-joypad-36.jpg

Размер кнопок: высота 15%, ширина 20%.

https://alashed-media.s3.eu-north-1.amazonaws.com/wiki/martyncurrey/create-a-bluetooth-joypad-39.jpg

Теперь добавьте изображения (правый клик — Сохранить как):

https://alashed-media.s3.eu-north-1.amazonaws.com/wiki/martyncurrey/create-a-bluetooth-joypad-4.jpg https://alashed-media.s3.eu-north-1.amazonaws.com/wiki/martyncurrey/create-a-bluetooth-joypad-3.jpg https://alashed-media.s3.eu-north-1.amazonaws.com/wiki/martyncurrey/create-a-bluetooth-joypad-2.jpg https://alashed-media.s3.eu-north-1.amazonaws.com/wiki/martyncurrey/create-a-bluetooth-joypad-1.jpg https://alashed-media.s3.eu-north-1.amazonaws.com/wiki/martyncurrey/create-a-bluetooth-joypad-41.png https://alashed-media.s3.eu-north-1.amazonaws.com/wiki/martyncurrey/create-a-bluetooth-joypad-42.png

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

https://alashed-media.s3.eu-north-1.amazonaws.com/wiki/martyncurrey/create-a-bluetooth-joypad-5.jpg

Эти блоки делают:

1. При запуске приложения (screen1.initialize)
— делают экран без прокрутки
— скрывают PAGE2_OUTER_VA
2. Следующий блок обрабатывает кнопку BTN_CONNECT_PAGE. При нажатии отображается страница 2:
— PAGE1_OUTER_VA скрывается (visible = false)
— PAGE2_OUTER_VA отображается (visible = true)
  1. Третий блок обрабатывает BTN_BACK. При нажатии приложение возвращается на страницу 1, скрывая PAGE2_OUTER_VA и отображая PAGE1_OUTER_VA.

Создание приложения

Мы будем строить приложение по частям. Сначала настроим Bluetooth-подключение, затем добавим функции кнопок. Поскольку приложение будет иметь только одностороннюю связь (от приложения к Arduino), нам не нужен код для обработки приёма данных, только отправки. Всё, что нужно — установить соединение, дождаться нажатия кнопки и отправить код.

В Bluetooth Classic удалённое устройство должно быть сопряжено перед установлением соединения. Процесс сопряжения обрабатывается Android-устройством через настройки. После сопряжения устройство остаётся в списке сопряжённых устройств.

В дизайнере добавьте BluetoothClient в проект. В палитре выберите BluetoothClient и перетащите в главное окно.

https://alashed-media.s3.eu-north-1.amazonaws.com/wiki/martyncurrey/create-a-bluetooth-joypad-13.jpg https://alashed-media.s3.eu-north-1.amazonaws.com/wiki/martyncurrey/create-a-bluetooth-joypad-14.jpg

Добавьте ListPicker в самый низ макета. В TEXT введите «Bluetooth device list» и снимите флажок Visible. Мы будем использовать кнопку CONNECT для активации ListPicker.

https://alashed-media.s3.eu-north-1.amazonaws.com/wiki/martyncurrey/create-a-bluetooth-joypad-16.jpg https://alashed-media.s3.eu-north-1.amazonaws.com/wiki/martyncurrey/create-a-bluetooth-joypad-17.jpg

Далее добавьте Notifier:

https://alashed-media.s3.eu-north-1.amazonaws.com/wiki/martyncurrey/create-a-bluetooth-joypad-18.jpg https://alashed-media.s3.eu-north-1.amazonaws.com/wiki/martyncurrey/create-a-bluetooth-joypad-19.jpg

Notifier будет использоваться для отображения сообщений об ошибках — например, когда Bluetooth выключен или соединение не может быть установлено.

В редакторе блоков, после добавления BluetoothClient, мы можем получить доступ к Bluetooth-блокам.

https://alashed-media.s3.eu-north-1.amazonaws.com/wiki/martyncurrey/create-a-bluetooth-joypad-15.jpg

Я не буду описывать каждый шаг, но покажу блоки и объясню, что они делают.

Bluetooth-подключение

https://alashed-media.s3.eu-north-1.amazonaws.com/wiki/martyncurrey/create-a-bluetooth-joypad-40.png

Для Bluetooth-подключения у нас есть 2 элемента экрана: кнопка CONNECT и ListPicker. ListPicker невидим. Также есть пустой список PAIRED_BT_DEVICE_LIST. При нажатии кнопки CONNECT вызывается функция BTN_CONNECT_BT.Click.

https://alashed-media.s3.eu-north-1.amazonaws.com/wiki/martyncurrey/create-a-bluetooth-joypad-20.png

Сначала проверяется, включён ли Bluetooth. Если нет — отображается сообщение об ошибке. Затем проверяется, есть ли уже соединение — если есть, пользователю предлагается его закрыть.

Если Bluetooth включён и соединения нет, все сопряжённые устройства копируются в PAIRED_BT_DEVICE_LIST, и если длина списка > 0, значит есть хотя бы 1 сопряжённое устройство. Если список пуст — отображается ошибка. Если список не пуст, он копируется в ListPicker, и ListPicker активируется.

Использование списка может показаться излишним, но оно позволяет проверить наличие сопряжённых устройств. Без этого приложение может отобразить пустой список. Вместо отображения ListPicker и разрешения пользователю нажимать на него, я использую кнопку для его активации. Это даёт приложению дополнительную гибкость.

После выбора устройства из ListPicker вызывается блок ListPicker1.AfterPicking — здесь мы пытаемся установить соединение.

https://alashed-media.s3.eu-north-1.amazonaws.com/wiki/martyncurrey/create-a-bluetooth-joypad-21.png

Если соединение успешно, изображение IMG_BT_INDICAT меняется на «circle_blue_100x100.png», а текст кнопки BT — на «CONNECTED». Если подключение не удалось — отображается ошибка.

При активном соединении нажатие кнопки CONNECT предлагает закрыть соединение. Notifier1.AfterChoosing обрабатывает ответ пользователя. При нажатии YES соединение закрывается, индикатор меняется на красный, а текст — на «NOT CONNECTED».

https://alashed-media.s3.eu-north-1.amazonaws.com/wiki/martyncurrey/create-a-bluetooth-joypad-22.png

Если хотите проверить — настройте HC-06 или HC-05 (Arduino не нужен) и на Android-устройстве через Настройки => Bluetooth выполните сопряжение с Bluetooth-модулем. После этого запустите приложение и попробуйте подключиться.

Нажатия кнопок

Нажатия кнопок имеют 2 состояния — нажата и отпущена. В App Inventor 2 это реализуется блоками Button.TouchDown и Button.TouchUp.

https://alashed-media.s3.eu-north-1.amazonaws.com/wiki/martyncurrey/create-a-bluetooth-joypad-23.jpg

Нам нужны оба блока для каждой кнопки, и каждая кнопка отправляет свою команду. Мы могли бы просто отправлять команду внутри этих блоков, но поскольку мы проверяем статус подключения перед отправкой, лучше создать отдельную процедуру sendCommand.

https://alashed-media.s3.eu-north-1.amazonaws.com/wiki/martyncurrey/create-a-bluetooth-joypad-24.jpg

sendCommand получает команду для отправки, проверяет статус подключения и, если подключено, отправляет команду. Всегда полезно проверять статус перед отправкой — при попытке отправить данные без активного соединения вы получите системную ошибку.

Используйте процедуру sendCommand, вызвав её с передачей команды:

https://alashed-media.s3.eu-north-1.amazonaws.com/wiki/martyncurrey/create-a-bluetooth-joypad-25.jpg

Теперь добавляем блоки для обработки нажатий кнопок. Помните — заглавные буквы для TouchDown, строчные для TouchUp.

https://alashed-media.s3.eu-north-1.amazonaws.com/wiki/martyncurrey/create-a-bluetooth-joypad-26.jpg https://alashed-media.s3.eu-north-1.amazonaws.com/wiki/martyncurrey/create-a-bluetooth-joypad-27.jpg

Arduino

Основная часть приложения готова, можно приступить к стороне Arduino.

Поскольку эта статья о джойпаде, а не об Arduino, я использую очень простую схему и скетч для тестирования. Схема состоит из Arduino, Bluetooth-модуля HC-06 и делителя напряжения. Приложение отображает полученные данные в мониторе порта.

Схема

https://alashed-media.s3.eu-north-1.amazonaws.com/wiki/martyncurrey/create-a-bluetooth-joypad-28.jpg https://alashed-media.s3.eu-north-1.amazonaws.com/wiki/martyncurrey/create-a-bluetooth-joypad-29.jpg
Arduino D9 (AltSoftSerial TX) к BT RX
Arduino D8 (AltSoftSerial RX) к BT TX
BT-модуль питается от 5V Arduino
GND к GND

Пин RX модуля HC-06 работает на 3.3 В, а пин D9 Arduino — на 5 В. Поэтому нам нужно понизить напряжение с помощью делителя (резисторы 1 кОм и 2 кОм). Arduino видит 3.3 В как HIGH, поэтому на пине TX Bluetooth ничего делать не нужно — подключаем напрямую к D8.

Я использую HC-06 с настройками по умолчанию:

Скорость: 9600 бод
Имя: HC-06_ZG
// basicSerial_AltSoftSerial_01
//
// Использует аппаратный serial для связи с компьютером
// и AltSoftSerial для связи с bluetooth-модулем.
// При получении данных через AltSoftSerial они копируются в монитор порта.
//
// Пины
// Arduino D8 (ASS RX) - BT TX (делитель напряжения не нужен)
// Arduino D9 (ASS TX) - BT RX через делитель напряжения
// Arduino 5V к BT VCC
// GND к GND

#include <AltSoftSerial.h>
AltSoftSerial BTSerial;

char c=' ';

void setup()
{
    Serial.begin(9600);
    Serial.println(" ");

    BTSerial.begin(9600);
    Serial.println("BTserial started at 9600");
}

void loop()
{
    // Чтение из Bluetooth-модуля и отправка в монитор порта Arduino
    if (BTSerial.available())
    {
        c = BTSerial.read();
        Serial.println(c);
    }
}

Приложение в действии

Загрузите код и запустите приложение.

https://alashed-media.s3.eu-north-1.amazonaws.com/wiki/martyncurrey/create-a-bluetooth-joypad-6.png

При открытии приложения нажмите кнопку CONNECT — откроется страница подключения.

https://alashed-media.s3.eu-north-1.amazonaws.com/wiki/martyncurrey/create-a-bluetooth-joypad-7.png

Нажмите кнопку NOT CONNECTED.

https://alashed-media.s3.eu-north-1.amazonaws.com/wiki/martyncurrey/create-a-bluetooth-joypad-8.png

Отобразится список сопряжённых устройств. Выберите HC-06/HC-05 — приложение попытается подключиться.

https://alashed-media.s3.eu-north-1.amazonaws.com/wiki/martyncurrey/create-a-bluetooth-joypad-9.png

Если подключение успешно, текст кнопки меняется на CONNECTED. Нажмите кнопку BACK для возврата на главный экран.

https://alashed-media.s3.eu-north-1.amazonaws.com/wiki/martyncurrey/create-a-bluetooth-joypad-10.png

Индикатор подключения теперь синий.

С открытым монитором порта нажмите кнопки направления — вы должны увидеть коды управления.

https://alashed-media.s3.eu-north-1.amazonaws.com/wiki/martyncurrey/create-a-bluetooth-joypad-11.jpg

Теперь попробуйте кнопки функций.

https://alashed-media.s3.eu-north-1.amazonaws.com/wiki/martyncurrey/create-a-bluetooth-joypad-12.jpg

Что попробовать дальше

Измените кнопки функций так, чтобы у них было одно событие нажатия вместо нажатия и отпускания. Используйте блок button.Click.
Добавьте код подключения в приложение. При установлении соединения отправьте «CONNECTED» на Arduino. Это позволит узнать, что соединение установлено.

Скачать