====== Связываем 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 и ещё много-много всего интересного!