В этой статье мы научимся создавать собственные приложения Android для управления Arduino с помощью онлайн-приложения MIT App Inventor. Для этого урока у нас есть два примера. Первый пример — управление простым светодиодом, а второй — управление шаговым двигателем с помощью смартфона.
Вы можете посмотреть следующее видео, демонстрирующее данный процесс, или прочитать полный текст статьи.
Код Ардуино
Вот краткий обзор этого кода. Итак, через последовательный порт мы получаем входящие данные со смартфона и сохраняем их в переменной state. Если мы получим символ «0», который отправляется со смартфона при нажатии кнопки «LED: OFF», мы выключим светодиод и отправим обратно на смартфон строку «LED: OFF». С другой стороны, если мы получим символ «1», мы включим светодиод и отправим обратно строку «LED: ON».
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
/* Arduino and HC-05 Bluetooth Module Tutorial * * by Dejan Nedelkovski, www.HowToMechatronics.com * */ #define ledPin 7 int state = 0; void setup() { pinMode(ledPin, OUTPUT); digitalWrite(ledPin, LOW); Serial.begin(38400); // Default communication rate of the Bluetooth module } void loop() { if(Serial.available() > 0){ // Checks whether data is comming from the serial port state = Serial.read(); // Reads the data from the serial port } if (state == '0') { digitalWrite(ledPin, LOW); // Turn LED OFF Serial.println("LED: OFF"); // Send back, to the phone, the String "LED: ON" state = 0; } else if (state == '1') { digitalWrite(ledPin, HIGH); Serial.println("LED: ON");; state = 0; } } |
Итак, теперь нам нужно создать наше собственное приложение для Android, которое будет отправлять эти символы «0» и «1» при нажатии определенной кнопки, а также получать входящие строки от Arduino.
Разработчик приложений MIT
На веб-сайте MIT App Inventor нам нужно войти в онлайн-приложение и нажать кнопку “Create apps!” («Создать приложения!»). Для входа в систему нам необходимо иметь учетную запись Gmail. После входа в систему мы можем создать наш первый проект. На рисунке ниже показан внешний вид окна дизайна, и теперь мы можем приступить к созданию нашего приложения.
Но прежде чем сделать это, мы можем подключить наш смартфон к этому проекту, чтобы увидеть, как приложение обретает форму, прямо на нашем смартфоне в режиме реального времени. Для этого сначала нам нужно загрузить приложение MIT AI2 Companion из Play Store и установить его на наш смартфон. Затем в меню «Подключиться» (Connect menu) онлайн-редактора мы выберем AI Companion, и появится штрих-код, который нам просто нужно отсканировать или вставить код в приложение для смартфона, и соединение между онлайн-редактором и приложением для смартфона будет установлено.
Например, если мы вставим кнопку на экран онлайн-редактора, она появится в реальном времени и на смартфоне. Аналогично этому, если вы не хотите использовать свой смартфон при создании приложения, вы можете установить эмулятор Android на свой компьютер и использовать его таким же образом. Более подробную информацию о настройке эмулятора можно найти на их сайте.
Создание приложения – пример 1
Теперь мы готовы построить первый пример. Начнем с макета программы. Сначала мы добавим несколько HorizontalArrangements из палитры макетов и установим их свойства, такие как высота, ширина и выравнивание, чтобы они соответствовали желаемому виду нашей программы. Затем из палитры UserInterface мы добавим ListPicker и прикрепим к нему изображение. ListPicker будет использоваться для выбора устройства Bluetooth, к которому будет подключаться наш смартфон.
Далее мы добавим еще один HorizontalArrangements, в котором разместим метку. Эта метка будет указывать, подключен ли смартфон к модулю Bluetooth или нет, поэтому мы установим первоначальный текст этой метки “Not Connected” («Не подключен»). Следующая метка будет использоваться для отображения состояния светодиода, выключен он или включен. Исходное состояние будет “LED: OFF” («Светодиод: ВЫКЛ»). Далее мы добавим две кнопки: ‘Turn On’ («Включить») и ‘Turn Off’ («Выключить») для управления светодиодом. На этом этапе полезно переименовать компоненты, чтобы их было легче распознавать и использовать позже в редакторе блоков. Теперь осталось добавить BluetoothClient, который является невидимым компонентом, а также часы, которые будут использоваться для индикации состояния соединения в реальном времени.
Редактор блоков
Теперь в редакторе блоков мы готовы дать жизнь нашей программе. С левой стороны мы получили все блоки и функции, связанные с ранее добавленными компонентами.
Мы начнем с BluetoothList ListPicker. Сначала мы добавим блок «BeforePicking» и прикрепим к нему блок ‘set Bluetooth Elements’ («Установить элементы Bluetooth»). Затем из блоков BluetoothClient добавим блок BluetoothClient AddressesAndNames. Этот набор блоков будет устанавливать список устройств Bluetooth, которые уже сопряжены с нашим телефоном, поэтому, когда мы нажмем кнопку «Подключиться» (“Connect Button”) в ListPicker, отобразится список всех сопряженных устройств.
Далее нам нужно установить, что произойдет после того, как мы выберем наш конкретный модуль Bluetooth. Из блока BluetoothClient мы добавим блок ‘call BluetoothClient .Connect address’ («вызов BluetoothClient.Connect адрес») и добавим к нему блок ‘BluetoothList Selection’ («Выбор BluetoothList»), что означает, что наш телефон будет подключаться к адресу Bluetooth, который мы выбрали ранее.
Следующим из блоков Clock («Часы») добавим блок «.Timer». В этом блоке мы будем указывать в режиме реального времени, подключен ли телефон к модулю Bluetooth, используя блок “set Text” («Установить текст») метки “Connected” («Подключено»).
Далее нам нужно оживить две кнопки. Поэтому, когда будет нажата кнопка «TurnOn_Button», мы будем использовать клиентскую функцию Bluetooth «Send1ByteNumber» для отправки номера в модуль Arduino Bluetooth. В нашем случае это число 49, которое соответствует символу «1» в соответствии с таблицей ASCII и включает светодиод. Сразу после этого мы воспользуемся функцией BluetoothClient «ReceiveText» для получения входящей строки, которая отправляется обратно с Arduino на телефон. Эта строка имеет значение метки «LED_Status».
Та же процедура применяется для «TurnOff_Button», где номер отправки должен быть изменен на 48, что соответствует символу «0». Теперь осталось скачать и установить программу на наш смартфон. Мы можем сделать это из меню «Создать», либо сохранив его на нашем компьютере, а затем перенеся на телефон, либо отсканировав QR-код для загрузки программы онлайн.
Вот загружаемый файл вышеупомянутого проекта MIT App Inventor.
Пример управления шаговым двигателем
Теперь давайте рассмотрим второй пример - управления шаговым двигателем. В верхней части экрана у нас есть те же компоненты для подключения Bluetooth, что и в предыдущем примере. Далее у нас есть компонент Canvas, который используется для рисования и вставки изображений. Я вставил два прозрачных изображения, которые ранее нарисовал. Первый — это изображение датчика, который будет зафиксирован на месте, а второй — изображение указателя, который будет вращаться. Далее у нас есть кнопка «Проверка» для переключения между ручным и автоматическим режимами или режимом непрерывной работы, а также кнопка для изменения направления вращения. У кнопки у нас есть ползунок изменения скорости вращения шагового двигателя.
Вот блоки и код Arduino, лежащие в основе этого примера. Итак, в редакторе блоков у нас снова те же блоки для Bluetooth-соединения, что и в предыдущем примере.
Теперь для поворота изображения указателя мы используем функцию ImageSprite «.PointInDirection», которая поворачивает изображение от положения 0 ° до координат X и Y, в которых было затронуто Canvas. В то же время мы устанавливаем повернутый заголовок ImageSprite на текстовую метку выше. После этого мы вызываем специальную процедуру или функцию, которая на самом деле имеет задержку в 10 минут.
Наконец, мы отправляем значение заголовка в виде текста на Arduino с помощью функции Bluetooth «SendText». Это значение будет принято Arduino и соответствующим образом будет вращать шаговый двигатель.
Далее идет блок CheckBox. Поэтому, если флажок установлен, мы отправим текст “Auto” («Авто») на Arduino, который активирует постоянное вращение шагового двигателя. Находясь в этом режиме, если мы нажмем кнопку “Reverse” («Реверс»), мы отправим текст “Reverse” («Реверс») на Arduino, который изменит направление вращения двигателя. Также, находясь в этом режиме, мы можем менять скорость вращения. Если мы изменим положение ползунка, текущее значение положения ползунка будет отправлено на Arduino, что изменит скорость вращения шагового двигателя. Если мы снимем флажок с флажка, мы вернемся в ручной режим. Вот демонстрация примера.
Вы можете скачать загружаемый файл вышеуказанного проекта MIT App Inventor, а также два изображения, использованные в проекте.
Вот код Arduino для примера с шаговым двигателем:
1 2 3 4 5 6 7 8 9 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 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
/* Stepper Motor Control via HC-05 Bluetooth Module * * by Dejan Nedelkovski, www.HowToMechatronics.com * */ // Defining variables const int stepPin = 7; const int dirPin = 6; String state = ""; int currentHeading=0; int currentAngle=0; int lastAngle=0; int angle=0; int rotate=0; int runContinuously=0; String mode = "Manual"; boolean dirRotation = HIGH; int rotSpeed = 1500; void setup() { // Sets the two pins as Outputs pinMode(stepPin,OUTPUT); pinMode(dirPin,OUTPUT); Serial.begin(38400); // Default communication rate of the Bluetooth module } void loop() { delayMicroseconds(1); if(Serial.available() > 0){ // Checks whether data is comming from the serial port state = Serial.readString(); // Reads the data from the serial port } // When Auto Button is pressed if (mode == "Auto") { if (state == "Reverse") { delay(10); if (dirRotation == HIGH) { dirRotation = LOW; } else { dirRotation = HIGH; } digitalWrite(dirPin,dirRotation); delay(10); state = ""; } rotSpeed = state.toInt(); if (rotSpeed >= 300 && rotSpeed <= 3000) { digitalWrite(stepPin,HIGH); delayMicroseconds(rotSpeed); digitalWrite(stepPin,LOW); delayMicroseconds(rotSpeed); } else { digitalWrite(stepPin,HIGH); delayMicroseconds(1500); digitalWrite(stepPin,LOW); delayMicroseconds(1500); } if (state == "Manual"){ mode = state; } } // When Program is in Manual mode else if (mode == "Manual"){ currentHeading = state.toInt(); //Serial.println(angle); //Serial.println(state); if (currentHeading < 0 ){ currentHeading = 360+currentHeading; } currentAngle = map(currentHeading,0,359,0,200); digitalWrite(dirPin,HIGH); // Enables the motor to move in a particular direction // Makes 200 pulses for making one full cycle rotation if (currentAngle != lastAngle){ if(currentAngle > lastAngle){ rotate = currentAngle - lastAngle; for(int x = 0; x < rotate; x++) { digitalWrite(stepPin,HIGH); delayMicroseconds(500); digitalWrite(stepPin,LOW); delayMicroseconds(500); } } if(currentAngle < lastAngle){ rotate = lastAngle - currentAngle; digitalWrite(dirPin,LOW); //Changes the rotations direction for(int x = 0; x < rotate; x++) { digitalWrite(stepPin,HIGH); delayMicroseconds(500); digitalWrite(stepPin,LOW); delayMicroseconds(500); } } } lastAngle = currentAngle; if (state == "Auto"){ mode = state; } } } |