Машинка на блютус управлении с сервоприводом. CxemCAR на Arduino - Bluetooth управление машинкой с Android. Добавляем основной код

Там же находятся исходники для Android и другая полезная информация. В этой статье я покажу сборку CxemCAR для платформы Arduino. В качестве платы Arduino можно использовать практически любую Arduino-совместимую плату: UNO, Nano, Mega, Leonardo и даже на основе STM32 - Arduino DUE. Я использовал платку Arduino Nano V3, приобретенную на eBay за 9$.

Схема подключения Arduino к Bluetooth модулю HC-06 и драйверу двигателей L298N:

В схеме я использовал джампер (на схеме Jmp1), т.к. при подключенном Bluetooth модуле невозможно было загрузить скетч в Arduino. На время прошивки, снятием перемычки обесточивается Bluetooth-модуль.

В качестве платформы я использовал небольшую RC DIY платформу, купленную на за 25$. Сама платформа представляет из себя алюминиевое основание, куда крепится два двигателя, редуктор и 4 карданные передачи для 4-х колес. Сверху, на 3-х стойках ставится макетная плата.

Платформа не отличается высоким качеством изготовления. После того, как я ее собрал, попробовал подключить питание - двигателя даже не шевельнулись, много перекосов, недоработок и т.п. Пришлось все разбирать, немного ослабить крепления, кое-где подточить, хорошо все промазать смазкой, а также снял 2 кардана с передней оси. Получилась заднеприводная версия машинки.

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

В макетной плате, которая шла вместе с платформой, я просверлил отверстия и закрепил драйвер двигателей L298N. Плату Arduino прикрепил при помощи двухстороннего скотча.

Между алюминиевой платформой машинки и макетной платой я разместил 3 Li-Po аккумулятора 3.7В 1100 мА*Ч. Питание контроллера и двигателей раздельное: Arduino запитывается от одного аккумулятора 3.7В, а моторчики и драйвер L298N от двух последовательно соединенных аккумуляторов 3.7В. Предусмотрено два 2-х позиционных выключателя питания - в одном положение питание идет от аккумуляторов к потребителям, в другом положении на клеммы зарядки.

Фото машинки на подзарядке:

Программное обеспечение

Программа писалась в среде Arduino IDE 1.01. Код программы я постарался хорошо прокомментировать, но если будут вопросы - спрашивайте на форуме, в .

#include "EEPROM.h" #define D1 2 // направление вращение двигателя 1 #define M1 3 // ШИМ вывод для управления двигателем 1 (левый) #define D2 4 // направление вращение двигателя 2 #define M2 5 // направление вращение двигателя 2 (правый) #define HORN 13 // доп. канал 1 подключен к 13 пину //#define autoOFF 2500 // кол-во миллисекунд через которое робот останавливается при потери связи #define cmdL "L" // команда UART для левого двигателя #define cmdR "R" // команда UART для правого двигателя #define cmdH "H" // команда UART для доп. канала 1 (к примеру сигнал Horn) #define cmdF "F" // команда UART для работы с EEPROM памятью МК для хранения настроек #define cmdr "r" // команда UART для работы с EEPROM памятью МК для хранения настроек (чтение) #define cmdw "w" // команда UART для работы с EEPROM памятью МК для хранения настроек (запись) char incomingByte; // входящие данные char L_Data; // строковый массив для данных левого мотора L byte L_index = 0; // индекс массива char R_Data; // строковый массив для данных правого мотора R byte R_index = 0; // индекс массива char H_Data; // строковый массив для доп. канала byte H_index = 0; // индекс массива H char F_Data; // строковый массив данных для работы с EEPROM byte F_index = 0; // индекс массива F char command; // команда: передача координат R, L или конец строки unsigned long currentTime, lastTimeCommand, autoOFF; void setup() { Serial.begin(9600); // инициализация порта pinMode(HORN, OUTPUT); // дополнительный канал pinMode(D1, OUTPUT); // выход для задания направления вращения двигателя pinMode(D2, OUTPUT); // выход для задания направления вращения двигателя /*EEPROM.write(0,255); EEPROM.write(1,255); EEPROM.write(2,255); EEPROM.write(3,255);*/ timer_init(); // инициализируем программный таймер } void timer_init() { uint8_t sw_autoOFF = EEPROM.read(0); // считываем с EEPROM параметр "включена ли ф-ия остановки машинки при потере связи" if(sw_autoOFF == "1"){ // если таймер останова включен char var_Data; var_Data = EEPROM.read(1); var_Data = EEPROM.read(2); var_Data = EEPROM.read(3); autoOFF = atoi(var_Data)*100; // переменная автовыкл. для хранения кол-ва мс } else if(sw_autoOFF == "0"){ autoOFF = 999999; } else if(sw_autoOFF == 255){ autoOFF = 2500; // если в EEPROM ничего не записано, то по умолчанию 2.5 сек } currentTime = millis(); // считываем время, прошедшее с момента запуска программы } void loop() { if (Serial.available() > 0) { // если пришли UART данные incomingByte = Serial.read(); // считываем байт if(incomingByte == cmdL) { // если пришли данные для мотора L command = cmdL; // текущая команда memset(L_Data,0,sizeof(L_Data)); // очистка массива L_index = 0; // сброс индекса массива } else if(incomingByte == cmdR) { // если пришли данные для мотора R command = cmdR; memset(R_Data,0,sizeof(R_Data)); R_index = 0; } else if(incomingByte == cmdH) { // если пришли данные для доп. канала 1 command = cmdH; memset(H_Data,0,sizeof(H_Data)); H_index = 0; } else if(incomingByte == cmdF) { // если пришли данные для работы с памятью command = cmdF; memset(F_Data,0,sizeof(F_Data)); F_index = 0; } else if(incomingByte == "\r") command = "e"; // конец строки else if(incomingByte == "\t") command = "t"; // конец строки для команд работы с памятью if(command == cmdL && incomingByte != cmdL){ L_Data = incomingByte; // сохраняем каждый принятый байт в массив L_index++; // увеличиваем текущий индекс массива } else if(command == cmdR && incomingByte != cmdR){ R_Data = incomingByte; R_index++; } else if(command == cmdH && incomingByte != cmdH){ H_Data = incomingByte; H_index++; } else if(command == cmdF && incomingByte != cmdF){ F_Data = incomingByte; F_index++; } else if(command == "e"){ // если приняли конец строки Control4WD(atoi(L_Data),atoi(R_Data),atoi(H_Data)); delay(10); } else if(command == "t"){ // если приняли конец строки для работы с памятью Flash_Op(F_Data,F_Data,F_Data,F_Data,F_Data); } lastTimeCommand = millis(); // считываем текущее время, прошедшее с момента запуска программы } if(millis() >= (lastTimeCommand + autoOFF)){ // сравниваем текущий таймер с переменной lastTimeCommand + autoOFF Control4WD(0,0,0); // останавливаем машинку } } void Control4WD(int mLeft, int mRight, uint8_t Horn){ bool directionL, directionR; // направление вращение для L298N byte valueL, valueR; // значение ШИМ M1, M2 (0-255) if(mLeft > 0){ valueL = mLeft; directionL = 0; } else if(mLeft < 0){ valueL = 255 - abs(mLeft); directionL = 1; } else { directionL = 0; valueL = 0; } if(mRight > 0){ valueR = mRight; directionR = 0; } else if(mRight < 0){ valueR = 255 - abs(mRight); directionR = 1; } else { directionR = 0; valueR = 0; } analogWrite(M1, valueL); // задаем скорость вращения для L analogWrite(M2, valueR); // задаем скорость вращения для R digitalWrite(D1, directionL); // задаем направление вращения для L digitalWrite(D2, directionR); // задаем направление вращения для R digitalWrite(HORN, Horn); // дополнительный канал } void Flash_Op(char FCMD, uint8_t z1, uint8_t z2, uint8_t z3, uint8_t z4){ if(FCMD == cmdr){ // если команда чтения EEPROM данных Serial.print("FData:"); // посылаем данные с EEPROM Serial.write(EEPROM.read(0)); // считываем значение ячейки памяти с 0 адресом и выводим в UART Serial.write(EEPROM.read(1)); Serial.write(EEPROM.read(2)); Serial.write(EEPROM.read(3)); Serial.print("\r\n"); // маркер конца передачи EEPROM данных } else if(FCMD == cmdw){ // если команда записи EEPROM данных EEPROM.write(0,z1); // запись z1 в ячейку памяти с адресом 0 EEPROM.write(1,z2); EEPROM.write(2,z3); EEPROM.write(3,z4); timer_init(); // переинициализируем таймер Serial.print("FWOK\r\n"); // посылаем сообщение, что данные успешно записаны } }

В коде используется библиотека для работы с EEPROM памятью AVR. В памяти хранится одна настройка: количество миллисекунд через которое машинка останавливается при потери связи. Можно эту настройку "жестко" прописать в программе, для этого раскомментируйте строчку #define autoOFF 2500 (где 2500 кол-во миллисекунд). После этого, функцию Flash_Op можно удалить, также необходимо будет внести небольшие правки в код, отвечающий за прием команд для работы с EEPROM-памятью.

Машинка на Ардуино с Bluetooth управлением от Android телефона — это очень простой, но интересный проект на Arduino UNO с использованием модуля Motor Shield. На этой странице вы узнаете какие потребуются компоненты для изготовления робота машинки на Ардуино своими руками, пошаговую инструкцию по сборке электрической схемы и сможете скачать все необходимые программы для Android и Arduino.

Для этого проекта использовался модуль Motor Shield L293D , два колеса с редукторами, плата Arduino UNO, блютуз модуль HC-05 и два светодиода для фар. Управление происходит дистанционно через Bluetooth сигнал от смартфона или планшета. После сборки модели и установки программ, вы сможете через приложение на смартфоне поворачивать машинкой, ездить вперед и назад, включать и выключать фары.

Машинка на Ардуино своими руками

Для этого проекта нам потребуется:

  • плата Arduino Uno / Arduino Nano / Arduino Mega;
  • Motor Control Shield L293D;
  • Bluetooth модуль HC-05/06;
  • два мотора с редукторами и колесами;
  • аккумулятор 9 Вольт (крона);
  • 2 резистора и 2 светодиода;
  • корпус и колеса от старой машинки;
  • паяльник, термопистолет, провода, припой и т.д.
Детали для робота — машинки на Ардуино УНО

Схема сборки машинки на Ардуино

Если у вас есть все необходимые детали (в проекте можно обойтись без светодиодов и резисторов), то далее мы рассмотрим, как сделать машинку из ардуино своими руками. Для начала следует припаять к контактам моторчиков провода и зафиксировать их изолентой, чтобы контакты не оторвались. Провода необходимо соединить с клеммниками M1 и M2 на Motor Shield (полярность потом можно будет поменять).


Питание на Bluetooth модуль идет от контактов для сервопривода, в проекте серво нам не понадобятся. А на питание идет стабилизированное напряжение 5 Вольт, что нам подходит. К портам TX и RX удобнее будет припаять коннекторы «мама», а к портам «Pin0» и «Pin1» на Motor Shield припаять штырьки (BLS). Таким образом, вы сможете легко отключать Bluetooth модуль от Arduino при необходимости загрузки скетча.

Управление светодиодами идет от порта «Pin2», здесь провод можно припаять напрямую к порту. Если вы делаете несколько машинок с Блютуз, которыми будете управлять одновременно, то рекомендуем сделать перепрошивку модуля HC-05 . Делается прошивка модуля очень просто, а затем вы уже не будете путать машинки, так как у каждой будет отображаться свое уникальное имя на Андроиде.

Приложение и скетч для машинки на Ардуино

После сборки схемы загрузите следующий скетч для машинки (не забудьте отключать Bluetooth модуль от Ардуино при загрузке) и установите приложение на смартфоне. Все файлы для проекта (библиотека AFMotor.h, скетч для машинки и приложение для Android) можно скачать одним архивом по прямой ссылке . Работу скетча можно проверить управлением машинки от компьютера через Serial Monitor по USB.

#include // подключаем библиотеку для шилда AF_DCMotor motor1(1); // подключаем мотор к клеммнику M1 AF_DCMotor motor2(2); // подключаем мотор к клеммнику M2 int val; // освобождаем память в контроллере void setup () { Serial .begin (9600); pinMode (2, OUTPUT ); // Порт для светодиодов motor1.setSpeed (250); motor1.run (RELEASE ); // останавливаем мотор motor2.setSpeed (250); // задаем максимальную скорость мотора motor2.run (RELEASE ); // останавливаем мотор } void loop () { if (Serial .available ()) // проверяем, поступают ли какие-то команды { val = Serial .read (); if (val == "f") { // едем вперед motor1.run (FORWARD ); motor1.setSpeed (250); motor2.run (FORWARD ); motor2.setSpeed (250); } if (val == "b") { // едем назад motor1.run (BACKWARD ); motor1.setSpeed (200); motor2.run (BACKWARD ); motor2.setSpeed (200); } if (val == "s") { // останавливаемся motor1.run (RELEASE ); motor2.run (RELEASE ); } if (val == "l") { // поворачиваем налево motor1.run (FORWARD ); motor1.setSpeed (100); motor2.run (BACKWARD ); motor2.setSpeed (250); } if (val == "r") { // поворачиваем направо motor1.run (BACKWARD ); motor1.setSpeed (250); motor2.run (FORWARD ); motor2.setSpeed (100); } if (val == "1") { // включаем светодиоды digitalWrite (2,HIGH ); } if (val == "0") { // выключаем светодиоды digitalWrite (2,LOW ); } } }

Пояснения к коду:

  1. для тестирования, можно отправлять команды с компьютера через USB;
  2. вращение моторов при подключении к аккумулятору будут отличаться;
  3. вы можете задавать свою скорость вращения моторами.

После проверки работы машинки, установите приложение на смартфон или планшет. При первом подключении к Bluetooth модулю HC-05/06, потребуется сделать сопряжение с Андроид (затем сопряжение будет выполняться автоматически). Если у вас возникли сложности с подключением — прочитайте эту статью

Очень часто в ваших проектах возникает необходимость в дистанционном управлении или передачи данных с ваших телефонных гаджетов.

Один из самых популярных и распространенных методов обмена данными посредством Bluetooth.

Сегодня мы разберем простые примеры как можно подключить Bluetooth модуль к Arduino и настроить дистанционное управление с телефона.

Нам понадобится:

  • Набор проводов ПАПА-МАМА
  • HC-06 Bluetooth

Подключать Bluetooth модуль к микроконтроллеру Arduino удобнее всего с помощью проводков ПАПА-МАМА .

Arduino Bluetooth
Pin 1 (TX) RXD
Pin 0 (RX) TXD
GND GND
5V VCC

Будьте внимательны, подключать подключать нужно TX -> RXD ,RX -> TXD .

Теперь необходимо записать пробный код программы:

Во время загрузки скетча необходимо что бы Bluetooth модуль был отключен от микроконтроллера arduino. В противном случае скетч не запишется, потому что связь с Bluetooth модулем происходит по одному и томуже порту RX и TX, что и USB.

Int val; int LED = 13; void setup() { Serial.begin(9600); pinMode(LED, OUTPUT); digitalWrite(LED, HIGH); } void loop() { if (Serial.available()) { val = Serial.read(); // При символе "1" включаем светодиод if (val == "1") { digitalWrite(LED, HIGH); } // При символе "0" выключаем светодиод if (val == "0") { digitalWrite(LED, LOW); } } }

После того как скетч записан и Bluetooth модуль подключен к Arduino, можно перейти к следующему шагу.

Подключение Bluetooth к телефону

Желательно в качестве источника питания для arduino использовать не USB, а внешний Блок питания на 9 В.

  1. Включаем Bluetooth на телефоне и ищем новые устройства
  2. Находим в списке расстройств "HC-06" и подключаемся к нему.
  3. Телефон спросит пин-код. необходимо ввести "1234 " или "0000 "
  4. Ура. Устройство подключено.

Теперь нужно скачать bluetooth terminal на ваш телефон. Мы рассмотрим на примере платформы Android.



Вы можете установить разные bluetooth терминалы, как правило они отличаются только разными дизайнами, функционал от этого не меняется. Так же можно найти и терминал и для продуктов ios.

После того как мы установили терминал, запускаем его выбираем наш bluetooth модуль HC-06 и подключаемся к нему.

Пришло время попробовать проект в деле. Пишем в терминале цифру "0" и отправляем. Светодиод L который находится на плате arduino рядом с pin 13, должен погаснуть. Теперь отправим через терминал цифру "1" и светодиод L должен зажечься.

Демонстрация работы:


Домашняя работа:

  • Изменить скетч так, что бы светодиод зажигался и потухал с помощью одной и той же команды например "G".
  • Дописать скетч и научить его преобразовывать текстовые данные приходящие через блютус в цифровые и реализовать димер, зажигать светодиод с помощью ШИМ, на заданную яркость от 0 до 254 приходящую через bluetooth.

В статье рассмотрим подключение и управление Arduino по bluetooth.

В качестве блютуз-модуля будет использоваться широко распространенный hc-06.

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

Начнем с написания приложения на android-смартфон. Приложение будет писаться в удобной и простой среде программирования App Inventor. Программы будут составляться онлайн.

Пройдите по ссылке http://ai2.appinventor.mit.edu/ . Там вас попросят войти в Google-аккаунт, который вам придется завести, если его еще нет.

После входа вы попадете в программу, где сможете создать проект нажав «start new project». Вам потребуется ввести имя проекта. Назовем его led_control.

Откроется пустое окно приложения.

Здесь будем располагать необходимые компоненты. Выберите ListPicker в окне слева и поместите его в проект.

У компонента ListPicker в окне справа найдите свойство Text, и измените «Text for ListPicker1» на «Выберите BT-устройство».

Откройте закладку Layout в окне слева, поместите в приложение компонент HorizontalArrangement, измените его свойство Width на «Fill parent». Добавьте в HorizontalArrangement 2 кнопки Button, у каждой из них установите свойство Width в «Fill parent». Должно получиться так:

Изменим подписи на кнопках: на первой будет написано LED ON, на второй — LED OFF.

Ниже добавим Label и очистим его Text.

Осталось добавить компонент, организующий передачу данных по bluetooth. Откройте закладку Connectivity и поместите в проект BluetoothClient. Этот компонент окажется не на экране телефона, а под ним, т.к. он не является визуальным.

Теперь можно приступать к написанию программы. В верхней правой части программы выберите режим Blocks.

Здесь будет составляться программа из графических блоков. Слева кликните на компонент ListPicker1 и выберите ListPicker1.BeforePicking.

Снова нажмите на ListPicker1 и выберите set ListPicker1.Elements to

Поставьте его как на скриншоте.

Этим мы получили список сопряженных bluetooth-устройств. Теперь подключимся к выбранному устройству. Напишите блок как на скриншоте ниже.

Розовый блок с надписью Connected — это первый блок в закладке Text. Впишите Connected в пустое окошко.

Теперь напишем обработчик кнопок. При нажатии на первую кнопку будет отсылаться текст «led_on», а при нажатии на вторую — «led_off». Так же будет изменяться и надпись в Label1.

Осталось загрузить проект в ваш смартфон. Нажмите Build и выберите способ загрузки.

Для первого варианта вам понадобятся интернет и считыватель QR-кодов. Нажмите и дождитесь окончания сборки проекта и формирования QR-кода, после чего откройте считыватель QR-кодов на смартфоне и считайте код. Останется только загрузить и установить файл.

Во втором варианте проект в формате.apk сохранится на ваш компьютер и вы сможете скинуть его на смартфон любым удобным способом (например по USB).

Теперь займемся программой на Arduino.

Прием-передача данных осуществляется через COM-порт, поэтому будем использовать Serial. Будем посимвольно принимать сигналы, формировать строку и дальше сравнивать сформированную строку с командами led_on и led_off.

Arduino

String val = ""; void setup() { Serial.begin(9600); pinMode(13, OUTPUT); } void loop() { while (Serial.available()) { //пока приходят данные char c = Serial.read(); //считываем их val += c; //и формируем строку delay(3); } if (val != "") { Serial.println(val); } if (val == "led_on") { digitalWrite(13, HIGH); } else if (val == "led_off") { digitalWrite(13, LOW); } val = ""; }

String val = "" ;

void setup () {

Serial . begin (9600 ) ;

pinMode (13 , OUTPUT ) ;

void loop () {

while (Serial . available () ) { //пока приходят данные

char c = Serial . read () ; //считываем их

val += c ; //и формируем строку

delay (3 ) ;

}

Загрузите код в Arduino.

Теперь можно подключить Bluetooth-модуль HC-06. Подключается он очень просто:

Vcc 5v (можно 3,3 v)

ЕСЛИ ПОПЫТАТЬСЯ ЗАГРУЗИТЬ ПРОГРАММУ В ARDUINO С ПОДКЛЮЧЕННЫМ МОДУЛЕМ, ТО ВЫЛЕЗЕТ ОШИБКА, Т.К. И МОДУЛЬ И ЗАГРУЗКА ПРОГРАММЫ ЗАДЕЙСТВУЮТ ПОРТЫ RX И TX!

Подайте питание на Arduino. На bluetooth-модуле должен заморгать светодиод, это означает, что он ожидает подключения. Возьмите смартфон, найдите в настройках bluetooth, включите его и запустите поиск. Найдите устройство с именем hc-06 и подключитесь к нему. С первого раза может не получиться. После однократного успешного сопряжения можно запускать программу на смартфоне.

Сначала нажмите на «Выберите BT-устройство» и выберите модуль среди сопряженных устройств. Далее нажимайте кнопки включения и выключения светодиода. Если все сделано правильно, то все будет работать.

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

В данной статье будет подробно расписано создание небольшого приложения для мобильной операционной системы Android и скетча для Arduino. На Arduino Uno будет стоять Wireless Shield с Bluetooth-модулем. Приложение будет подключаться к Bluetooth-модулю и посылать некую команду. В свою очередь скетч по этой команде будет зажигать или гасить один из подключенных к Arduino светодиодов.

Нам понадобится

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

Заготовка

Разработка для ОС Android ведется в среде разработки ADT, Android Development Tools. Которую можно скачать с портала Google для разработчиков. После скачивания и установке ADT, смело его запускаем. Однако, еще рано приступать к разработке приложения. Надо еще скачать Android SDK нужной версии. Для этого необходимо открыть Android SDK Manager «Window → Android SDK Manager». В списке необходимо выбрать нужный нам SDK, в нашем случае Android 2.3.3 (API 10). Если телефона нет, то выбирайте 2.3.3 или выше; а если есть - версию, совпадающую с версией ОС телефона. Затем нажимаем на кнопку «Install Packages», чтобы запустить процесс установки.

После завершения скачивания и установки мы начинаем создавать приложение. Выбираем «File → New → Android Application Project». Заполним содержимое окна так, как показано на рисунке.

    Application Name - то имя приложения, которое будет показываться в Google Play Store. Но выкладывать приложение мы не собираемся, поэтому имя нам не особо важно.

    Project Name - имя проекта в ADT.

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

В выпадающих списках «Minimum Required SDK», «Target SDK», «Compile With» выбираем ту версию, которую мы скачали ранее. Более новые версии SDK поддерживают графические темы для приложений, а старые нет. Поэтому в поле «Theme» выбираем «None». Нажимаем «Next».

Снимаем галочку с «Create custom launcher icon»: в рамках данной статьи не будем заострять внимание на создании иконки приложения. Нажимаем «Next».

В появившемся окне можно выбрать вид «Activity»: вид того, что будет на экране, когда будет запущено приложение. Выбираем «Blank activity», что означает, что мы хотим начать всё с чистого листа. Нажимаем «Next».

В нашем приложении будет всего одно Activity, поэтому в появившемся окне можно ничего не менять. Поэтому просто жмем на «Finish».

Все, наше приложение создано.

Настройка эмулятора

Отладка приложений для Android производится на реальном устройстве или, если такового нет, то на эмуляторе. Сконфигурируем свой.

Для этого запустим «Window → Android Virtual Device Manager». В появившемся окне нажмем «New». Заполняем поля появившейся формы. От них зависит сколько и каких ресурсов будет предоставлять эмулятор «телефону». Выберите разумные значения и нажимайте «ОК».

В окне Android Virtual Device Manager нажимаем кнопку «Start». Это запустит эмулятор. Запуск занимает несколько минут. Так что наберитесь терпения.

В результате вы увидите окно эмулятора подобное этому:

Заполнение Activity

Activity - это то, что отображается на экране телефона после запуска приложения. На нем у нас будет две кнопки «Зажечь красный светодиод» и «Зажечь синий светодиод». Добавим их. В панели «Package Explorer» открываем res/layout/activity_main.xml . Его вид будет примерно таким же, как на скриншоте.

Перетаскиваем 2 кнопки «ToggleButton» на экранную форму. Переключаемся во вкладку «activity_main.xml» и видим следующий код:

activity_main_aiutogen.xml xmlns:tools = android:layout_width ="match_parent" android:layout_height ="match_parent" android:paddingBottom = android:paddingLeft = android:paddingRight ="@dimen/activity_horizontal_margin" android:paddingTop ="@dimen/activity_vertical_margin" tools:context =".MainActivity" > android:id ="@+id/toggleButton1" android:layout_alignParentLeft ="true" android:layout_alignParentTop ="true" android:text ="ToggleButton" /> android:id ="@+id/toggleButton2" android:layout_width ="wrap_content" android:layout_height ="wrap_content" android:layout_above ="@+id/textView1" android:layout_alignParentRight ="true" android:text ="ToggleButton" /> >

Это ни что иное, как наша Activity, которая отображается не в виде графики, а описанная в формате XML.

Сделаем имена компонентов более понятными. Изменим поля android:id следующим образом.

android:id ="@+id/toggleRedLed" ... android:id ="@+id/toggleGreenLed" ...

А еще добавим им подписи, изменим их цвет и размер текста. Результирующий код разметки будет выглядеть следующим образом.

activity_main.xml "http://schemas.android.com/apk/res/android" xmlns:tools ="http://schemas.android.com/tools" android:layout_width ="fill_parent" android:paddingBottom ="@dimen/activity_vertical_margin" android:paddingLeft ="@dimen/activity_horizontal_margin" android:paddingRight ="@dimen/activity_horizontal_margin" android:paddingTop ="@dimen/activity_vertical_margin" tools:context =".MainActivity" android:weightSum ="2" android:orientation ="horizontal" > android:id ="@+id/toggleRedLed" android:layout_width ="wrap_content" android:layout_height ="fill_parent" android:layout_weight ="1" android:background ="#FF0000" android:textOff ="OFF" android:textOn ="ON" android:textSize ="30dp" /> android:id ="@+id/toggleGreenLed" android:layout_width ="wrap_content" android:layout_height ="fill_parent" android:layout_weight ="1" android:background ="#00FF00" android:textOff ="OFF" android:textSize ="30dp" android:textOn ="ON" /> >

Эти же изменения можно сделать и в графическом режиме, воспользовавшись вкладкой «Outline/Properties».

Пробный запуск

Мы можем запустить только что созданное приложение на эмуляторе. Идем в настройки запуска «Run» → Run Configurations», в левой части нажимаем на «Android Application». Появляется новая конфигурация «New_configuration». В правой части окна выбираем вкладку «Target» и выбираем опцию «Launch on all compatible devices/AVD».

Нажимаем «Apply», а затем «Run». Приложение запустится в эмуляторе.

Можно понажимать кнопки. Но ничего происходить не будет, поскольку обработчики нажатий еще нами не написаны.

Чтобы запустить приложение на реальном устройстве, необходимо включить в его настройках опцию «Отладка USB» и подключить его к компьютеру.

На реальном устройстве приложение выглядит абсолютно аналогично.

Написание кода для Android

Правка манифеста

Каждое Android-приложение должно сообщить системе о том, какие права необходимо ему предоставить. Перечисление прав идет в так называемом файле манифеста AndroidManifest.xml . В нем мы должны указать тот факт, что хотим использовать Bluetooth в своем приложении. Для этого достаточно добавить буквально пару строк:

AndroidManifest.xml "http://schemas.android.com/apk/res/android" package ="ru.amperka.arduinobtled" android:versionCode ="1" android:versionName ="1.0" > android:minSdkVersion ="10" android:targetSdkVersion ="10" /> "android.permission.BLUETOOTH" /> "android.permission.BLUETOOTH_ADMIN" />
android:allowBackup ="true" android:icon ="@drawable/ic_launcher" android:label ="@string/app_name" android:theme ="@style/AppTheme" > android:name ="ru.amperka.arduinobtled.MainActivity" android:label ="@string/app_name" > > "android.intent.category.LAUNCHER" /> > > > >

Добавляем основной код

Пришла пора вдохнуть жизнь в наше приложение. Открываем файл MainActivity.java (src → ru.amperka.arduinobtled). Изначально он содержит следующий код:

MainActivityAutogen.java package ru.amperka.arduinobtled ; import android.os.Bundle ; import android.app.Activity ; import android.view.Menu ; public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super .onCreate (savedInstanceState) ; setContentView(R.layout .activity_main ) ; } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater() .inflate (R.menu .main , menu) ; return true ; } }

Дополним код в соответствии с тем, что нам нужно:

    Будем включать Bluetooth, если он выключен.

    Будем обрабатывать нажатия на кнопки

    Будем посылать информацию о том, какая кнопка была нажата.

Передавать на Arduino мы будем один байт с двузначным числом. Первая цифра числа - номер пина, к которому подключен тот или иной светодиод, вторая - состояние светодиода: 1 - включен, 0 - выключен.

Число-команда, рассчитывается очень просто: Если нажата красная кнопка, то берется число 60 (для красного светодиода мы выбрали 6-й пин Arduino) и к нему прибавляется 1 или 0 в зависимости от того, должен ли сейчас гореть светодиод или нет. Для зеленой кнопки всё аналогично, только вместо 60 берется 70 (поскольку зеленый светодиод подключен к 7 пину). В итоге, в нашем случае, возможны 4 команды: 60, 61, 70, 71.

Напишем код, который реализует всё сказанное.

MainActivity.java package ru.amperka.arduinobtled ; import java.io.IOException ; import java.io.OutputStream ; import java.lang.reflect.InvocationTargetException ; import java.lang.reflect.Method ; import android.app.Activity ; import android.bluetooth.BluetoothAdapter ; import android.bluetooth.BluetoothDevice ; import android.bluetooth.BluetoothSocket ; import android.content.Intent ; import android.os.Bundle ; import android.util.Log ; import android.view.Menu ; import android.view.View ; import android.view.View.OnClickListener ; import android.widget.Toast ; import android.widget.ToggleButton ; public class MainActivity extends Activity implements View .OnClickListener { //Экземпляры классов наших кнопок ToggleButton redButton; ToggleButton greenButton; //Сокет, с помощью которого мы будем отправлять данные на Arduino BluetoothSocket clientSocket; //Эта функция запускается автоматически при запуске приложения @Override protected void onCreate(Bundle savedInstanceState) { super .onCreate (savedInstanceState) ; setContentView(R.layout .activity_main ) ; //"Соединям" вид кнопки в окне приложения с реализацией redButton = (ToggleButton) findViewById(R.id .toggleRedLed ) ; greenButton = (ToggleButton) findViewById(R.id .toggleGreenLed ) ; //Добавлем "слушатель нажатий" к кнопке redButton.setOnClickListener (this ) ; greenButton.setOnClickListener (this ) ; //Включаем bluetooth. Если он уже включен, то ничего не произойдет String enableBT = BluetoothAdapter.ACTION_REQUEST_ENABLE ; startActivityForResult(new Intent(enableBT) , 0 ) ; //Мы хотим использовать тот bluetooth-адаптер, который задается по умолчанию BluetoothAdapter bluetooth = BluetoothAdapter.getDefaultAdapter () ; //Пытаемся проделать эти действия try { //Устройство с данным адресом - наш Bluetooth Bee //Адрес опредеяется следующим образом: установите соединение //между ПК и модулем (пин: 1234), а затем посмотрите в настройках //соединения адрес модуля. Скорее всего он будет аналогичным. BluetoothDevice device = bluetooth.getRemoteDevice ("00:13:02:01:00:09" ) ; //Инициируем соединение с устройством Method m = device.getClass () .getMethod ( "createRfcommSocket" , new Class { int .class } ) ; clientSocket = (BluetoothSocket) m.invoke (device, 1 ) ; clientSocket.connect () ; //В случае появления любых ошибок, выводим в лог сообщение } catch (IOException SecurityException e) { Log.d ("BLUETOOTH" , e.getMessage () ) ; } catch (NoSuchMethodException e) { Log.d ("BLUETOOTH" , e.getMessage () ) ; } catch (IllegalArgumentException e) { Log.d ("BLUETOOTH" , e.getMessage () ) ; } catch (IllegalAccessException e) { Log.d ("BLUETOOTH" , e.getMessage () ) ; } catch (InvocationTargetException e) { Log.d ("BLUETOOTH" , e.getMessage () ) ; } //Выводим сообщение об успешном подключении Toast.makeText (getApplicationContext() , "CONNECTED" , Toast.LENGTH_LONG ) .show () ; } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater() .inflate (R.menu .main , menu) ; return true ; } //Как раз эта функция и будет вызываться @Override public void onClick(View v) { //Пытаемся послать данные try { //Получаем выходной поток для передачи данных OutputStream outStream = clientSocket.getOutputStream () ; int value = 0 ; //В зависимости от того, какая кнопка была нажата, //изменяем данные для посылки if (v == redButton) { value = (redButton.isChecked () ? 1 : 0 ) + 60 ; } else if (v == greenButton) { value = (greenButton.isChecked () ? 1 : 0 ) + 70 ; } //Пишем данные в выходной поток outStream.write (value) ; } catch (IOException e) { //Если есть ошибки, выводим их в лог Log.d ("BLUETOOTH" , e.getMessage (, OUTPUT) ; pinMode(7 , OUTPUT) ; } void loop() { //Если данные пришли if (Serial.available () > 0 ) { //Считываем пришедший байт byte incomingByte = Serial.read () ; //Получаем номер пина путем целочисленного деления значения принятого байта на 10 //и нужное нам действие за счет получения остатка от деления на 2: //(1 - зажечь, 0 - погасить) digitalWrite(incomingByte / 10 , incomingByte % 2 ) ; } }

Особенности заливки скетча

Для связи Bluetooth-Bee с контроллером используются те же пины (0 и 1), что и для прошивки. Поэтому при программировании контроллера переключатель «SERIAL SELECT» на «Wireless Shield» должен быть установлен в положение «USB», а после прошивки его надо вернуть в положение «MICRO».

Результат

Заключение

В данной статье мы научились создавать приложения для операционной системы Android и передавать данные по Bluetooth. Теперь при нажатии на кнопку на экране телефона на базе операционной системы Android, произойдет изменение состояния светодиода на плате.

Вы можете развить мысль и сделать более дружественный интерфейс на Android, управлять с его помощью гораздо более сложными устройствами, публиковать классные приложения в Android Market и ещё много-много всего интересного!

Статьи по теме: