====== Связываем Arduino и Android через Bluetooth ======
В данной статье будет подробно расписано создание небольшого приложения для мобильной операционной системы Android и скетча для Arduino. На Arduino Uno будет стоять Wireless Shield с Bluetooth-модулем. Приложение будет подключаться к Bluetooth-модулю и посылать некую команду. В свою очередь скетч по этой команде будет зажигать или гасить один из подключенных к Arduino светодиодов.
===== Нам понадобится =====
{{ :беспроводная-связь:components-bt.jpg? |}}
-[[amp>product/arduino-uno|Arduino Uno]]
-[[amp>product/arduino-wireless-shield|Arduino Wireless Shield]]
-[[amp>product/bluetooth-bee|Bluetooth Bee]]
-[[amp>product/led-5mm|Красные и зеленые светодиоды]]
-[[amp>product/resistor|Резисторы]]
-[[amp>product/wire-mm|Провода «папа-папа»]]
-[[amp>product/breadboard-half|Breadboard Half]]
-Телефон на базе ОС Android
===== Создание приложения для Android =====
==== Заготовка ====
Разработка для ОС Android ведется в среде разработки ADT, Android Development Tools. Которую можно скачать с [[http://developer.android.com/sdk/index.html|портала Google]] для разработчиков.
После скачивания и установке ADT, смело его запускаем. Однако, еще рано приступать к разработке приложения. Надо еще скачать Android SDK нужной версии. Для этого необходимо открыть Android SDK Manager «Window -> Android SDK Manager». В списке необходимо выбрать нужный нам SDK, в нашем случае Android 2.3.3 (API 10). Если телефона нет, то выбирайте 2.3.3 или выше; а если есть — версию, совпадающую с версией ОС телефона. Затем нажимаем на кнопку «Install Packages», чтобы запустить процесс установки.
{{ :беспроводная-связь:02-bt.png? |}}
После завершения скачивания и установки мы начинаем создавать приложение. Выбираем «File -> New -> Android Application Project». Заполним содержимое окна так, как показано на рисунке.
{{ :беспроводная-связь:03-bt.png? |}}
* 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». Заполняем поля появившейся формы. От них зависит сколько и каких ресурсов будет предоставлять эмулятор «телефону». Выберите разумные значения и нажимайте «ОК».
{{ :беспроводная-связь:05.png? |}}
В окне Android Virtual Device Manager нажимаем кнопку «Start». Это запустит эмулятор. Запуск занимает несколько минут. Так что наберитесь терпения.
В результате вы увидите окно эмулятора подобное этому:
{{ :беспроводная-связь:6.png?600 |}}
==== Заполнение Activity ====
Activity — это то, что отображается на экране телефона после запуска приложения.
На нем у нас будет две кнопки «Зажечь красный светодиод» и «Зажечь синий светодиод». Добавим их. В панели «Package Explorer» открываем ''res/layout/activity_main.xml''. Его вид будет примерно таким же, как на скриншоте.
{{ :беспроводная-связь:04-bt.png?700 |}}
Перетаскиваем 2 кнопки «ToggleButton» на экранную форму. Переключаемся во вкладку «activity_main.xml» и видим следующий код:
Это ни что иное, как наша Activity, которая отображается не в виде графики, а описанная в формате XML.
Сделаем имена компонентов более понятными. Изменим поля ''android:id'' следующим образом.
А еще добавим им подписи, изменим их цвет и размер текста. Результирующий код разметки будет выглядеть следующим образом.
Эти же изменения можно сделать и в графическом режиме, воспользовавшись вкладкой «Outline/Properties».
{{ :беспроводная-связь:properties-bt.png? |}}
==== Пробный запуск ====
Мы можем запустить только что созданное приложение на эмуляторе. Идем в настройки запуска «Run» -> Run Configurations», в левой части нажимаем на «Android Application». Появляется новая конфигурация «New_configuration». В правой части окна выбираем вкладку «Target» и выбираем опцию «Launch on all compatible devices/AVD».
{{ :беспроводная-связь:07-bt.png?700 |}}
Нажимаем «Apply», а затем «Run». Приложение запустится в эмуляторе.
{{ :беспроводная-связь:10-2-bt.png?700 |}}
Можно понажимать кнопки. Но ничего происходить не будет, поскольку обработчики нажатий еще нами не написаны.
Чтобы запустить приложение на реальном устройстве, необходимо включить в его настройках опцию «Отладка USB» и подключить его к компьютеру.
На реальном устройстве приложение выглядит абсолютно аналогично.
{{ :беспроводная-связь:10-1-bt.png? |}}
==== Написание кода для Android ====
=== Правка манифеста ===
Каждое Android-приложение должно сообщить системе о том, какие права необходимо ему предоставить. Перечисление прав идет в так называемом файле манифеста ''AndroidManifest.xml''. В нем мы должны указать тот факт, что хотим использовать Bluetooth в своем приложении.
Для этого достаточно добавить буквально пару строк:
=== Добавляем основной код ===
Пришла пора вдохнуть жизнь в наше приложение. Открываем файл ''MainActivity.java'' (src -> ru.amperka.arduinobtled). Изначально он содержит следующий код:
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) {
// Inflate the menu; this adds items to the action bar if it is present.
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.
Напишем код, который реализует всё сказанное.
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 e) {
Log.d("BLUETOOTH", e.getMessage());
} catch (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());
}
}
}
===== Написание скетча =====
Данные, которые принимает Bluetooth-модуль, приходят через UART (он же Serial-соединение) на скорости 9600 бит/с. Настраивать Bluetooth-модуль нет никакой необходимости: он сразу готов к работе. Поэтому скетч должен уметь следующее:
-Принять данные по UART
-Зажечь нужный светодиод в зависимости от принятого кода
void setup() {
//Устанавливаем скорость UART
Serial.begin(9600);
//Настраиваем нужные пины на выход
pinMode(6, 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».
===== Результат =====
{{ :беспроводная-связь:result-bt.jpg? |}}
{{youtube>ibWk8WDkE2s?large}}
===== Заключение =====
В данной статье мы научились создавать приложения для операционной системы Android и передавать данные по Bluetooth. Теперь при нажатии на кнопку на экране телефона на базе операционной системы Android, произойдет изменение состояния светодиода на плате.
Вы можете развить мысль и сделать более дружественный интерфейс на Android, управлять с его помощью гораздо более сложными устройствами, публиковать классные приложения в Android Market и ещё много-много всего интересного!