Ардуино для андроида

Урок 15. Bluetooth модуль HC-06 подключение к Arduino. Управление устройствами с телефона.

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

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

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

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

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

Схема подключения Bluetooth к Arduino:

Подключать 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 и Android через Bluetooth

Пришла пора вдохнуть жизнь в наше приложение. Открываем файл 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) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } }

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

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

Передавать на 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 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()); } } }

Немного кода

В рассматриваемом примере сообщения, передающиеся по USB, состоят из трех байтов:
1-й байт определяет команду или группу устройств, например светодиоды — 0x2
2-й байт указывает на конкретное устройство, например зеленый светодиод — 0x1
3-й байт содержит значение, передаваемое устройству, например максимальная яркость — 0xff

… /* инициализация */ AndroidAccessory acc(«Google, Inc.», «DemoKit», «DemoKit Arduino Board», «1.0», «http://www.android.com», «0000000012345678»); void setup() { …. acc.powerOn(); } void loop() { byte msg; /* проверка подключения */ if (acc.isConnected()) { /* получение сообщения от Android устройства */ int len = acc.read(msg, sizeof(msg), 1); if (len > 0) { /* сообщение для светодиодов */ if (msg == 0x2) { if (msg == 0x0) analogWrite(LED3_RED, msg); else if (msg == 0x1) analogWrite(LED3_GREEN, msg); else if (msg == 0x2) analogWrite(LED3_BLUE, msg); } } msg = 0x1; b = digitalRead(BUTTON1); if (b != b1) { msg = 0; msg = b ? 1 : 0; /* отправка состояния кнопки */ acc.write(msg, 3); b1 = b; } } }

Android

import com.android.future.usb.UsbAccessory; import com.android.future.usb.UsbManager; … public class DemoKitActivity extends Activity implements Runnable { private UsbManager mUsbManager; UsbAccessory mAccessory; FileInputStream mInputStream; FileOutputStream mOutputStream; … private void openAccessory(UsbAccessory accessory) { mFileDescriptor = mUsbManager.openAccessory(accessory); if (mFileDescriptor != null) { mAccessory = accessory; FileDescriptor fd = mFileDescriptor.getFileDescriptor(); mInputStream = new FileInputStream(fd); mOutputStream = new FileOutputStream(fd); Thread thread = new Thread(null, this, «AccessoryThread»); thread.start(); } } public void run() { int ret = 0; byte buffer = new byte; int i; while (ret >= 0) { // получение входящих сообщений ret = mInputStream.read(buffer); i = 0; while (i < ret) { int len = ret — i; switch (buffer) { case 0x1: // сообщение от кнопки if (len >= 3) { Message m = Message.obtain(mHandler, MESSAGE_SWITCH); m.obj = new SwitchMsg(buffer, buffer); mHandler.sendMessage(m); } i += 3; break; } } } } // пример использования — включить красный светодиод на полную яркость: // mActivity.sendCommand((byte)2, (byte)0, (byte)255) public void sendCommand(byte command, byte target, int value) { byte buffer = new byte; if (value > 255) value = 255; buffer = command; buffer = target; buffer = (byte) value; if (mOutputStream != null && buffer != -1) { try { mOutputStream.write(buffer); } catch (IOException e) { … } } } }

Передача данных по Bluetooth между Android и Arduino

В статье Arduino и Bluetooth был рассмотрен один из способов передачи информации между Android-устройством и ПК по Bluetooth-соединению. Там же, в двух словах было упомянуто и Android-устройство, но для принятия и передачи данных использовался Android Bluetooth терминал. Однако, для реальных устройств необходима полноценная программа (не будем же мы управлять тем же роботом из терминала…), написанная для Android’а. В данной статье хотелось бы затронуть тему программного обеспечения для работы с Bluetooth, с применением языка Java и среды разработки Eclipse. Установка и настройка Eclipse хорошо описана в этой статье: Android и Arduino. Программное обеспечение.

Arduino

Я буду использовать Bluetooth модуль HC-06, однако для других модулей HC-04, HC-05 и т.п. схема подключения такая же (за исключением светодиода). Плата Arduino Nano V3.

Для наглядности, к плате Arduino я подключил красный светодиод, к 12-пину, но можно использовать и встроенный LED (обычно 13 пин).

Скетч для Arduino следующий:

char incomingByte; // входящие данные int LED = 12; // LED подключен к 12 пину void setup() { Serial.begin(9600); // инициализация порта pinMode(LED, OUTPUT); Serial.println(«Press 1 to LED ON or 0 to LED OFF…»); } void loop() { if (Serial.available() > 0) { //если пришли данные incomingByte = Serial.read(); // считываем байт if(incomingByte == ‘0’) { digitalWrite(LED, LOW); // если 1, то выключаем LED Serial.println(«LED OFF. Press 1 to LED ON!»); // и выводим обратно сообщение } if(incomingByte == ‘1’) { digitalWrite(LED, HIGH); // если 0, то включаем LED Serial.println(«LED ON. Press 0 to LED OFF!»); } } }

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

Теперь, что касается Android. Мы рассмотрим два примера, в первом мы будем передавать данные от Android-устройства к arduino, а во втором примере мы рассмотрим двусторонний обмен данными между устройствами. Второй пример сложнее и в части понимания и по сложности кода, т.к. используются потоки (thread).

Мы будем использовать Java код, с явным указанием MAC-адреса устройства, к которому мы будем подключаться. Т.к. если делать интерфейс обнаружения Bluetooth-устройств, их выбора, подключения к ним и т.д., то код будет очень большой и для некоторых читателей труднопонимаем. Но для тех, кому интересно могут посмотреть стандартный пример Bluetooth Chat.

Узнать MAC-адрес можно к примеру в программе для Android’а: Bluetooth Terminal:

Нас интересует устройство BOLUTEK (наш модуль HC-06, подключенный к Arduino), его MAC адрес: 00:15:FF:F2:19:4C. Его и надо будет в дальнейшем прописать в программе.

Android — передаем данные в Arduino

Первая программа очень простая, главное окно активити будет содержать 2 кнопки: включить LED и выключить LED. При нажатии на кнопку включения LED, по Bluetooth будет передаваться «1», при нажатии на выключение LED — «0».

В файле манифеста необходимо прописать 2 строки разрешения работы с Bluetooth:

Сам код главного активити:

package com.example.bluetooth1; import java.io.IOException; import java.io.OutputStream; import java.util.UUID; import com.example.bluetooth1.R; 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.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.Toast; public class MainActivity extends Activity { private static final String TAG = «bluetooth1»; Button btnOn, btnOff; private static final int REQUEST_ENABLE_BT = 1; private BluetoothAdapter btAdapter = null; private BluetoothSocket btSocket = null; private OutputStream outStream = null; // SPP UUID сервиса private static final UUID MY_UUID = UUID.fromString(«00001101-0000-1000-8000-00805F9B34FB»); // MAC-адрес Bluetooth модуля private static String address = «00:15:FF:F2:19:4C»; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); btnOn = (Button) findViewById(R.id.btnOn); btnOff = (Button) findViewById(R.id.btnOff); btAdapter = BluetoothAdapter.getDefaultAdapter(); checkBTState(); btnOn.setOnClickListener(new OnClickListener() { public void onClick(View v) { sendData(«1»); Toast.makeText(getBaseContext(), «Включаем LED», Toast.LENGTH_SHORT).show(); } }); btnOff.setOnClickListener(new OnClickListener() { public void onClick(View v) { sendData(«0»); Toast.makeText(getBaseContext(), «Выключаем LED», Toast.LENGTH_SHORT).show(); } }); } @Override public void onResume() { super.onResume(); Log.d(TAG, «…onResume — попытка соединения…»); // Set up a pointer to the remote node using it’s address. BluetoothDevice device = btAdapter.getRemoteDevice(address); // Two things are needed to make a connection: // A MAC address, which we got above. // A Service ID or UUID. In this case we are using the // UUID for SPP. try { btSocket = device.createRfcommSocketToServiceRecord(MY_UUID); } catch (IOException e) { errorExit(«Fatal Error», «In onResume() and socket create failed: » + e.getMessage() + «.»); } // Discovery is resource intensive. Make sure it isn’t going on // when you attempt to connect and pass your message. btAdapter.cancelDiscovery(); // Establish the connection. This will block until it connects. Log.d(TAG, «…Соединяемся…»); try { btSocket.connect(); Log.d(TAG, «…Соединение установлено и готово к передачи данных…»); } catch (IOException e) { try { btSocket.close(); } catch (IOException e2) { errorExit(«Fatal Error», «In onResume() and unable to close socket during connection failure» + e2.getMessage() + «.»); } } // Create a data stream so we can talk to server. Log.d(TAG, «…Создание Socket…»); try { outStream = btSocket.getOutputStream(); } catch (IOException e) { errorExit(«Fatal Error», «In onResume() and output stream creation failed:» + e.getMessage() + «.»); } } @Override public void onPause() { super.onPause(); Log.d(TAG, «…In onPause()…»); if (outStream != null) { try { outStream.flush(); } catch (IOException e) { errorExit(«Fatal Error», «In onPause() and failed to flush output stream: » + e.getMessage() + «.»); } } try { btSocket.close(); } catch (IOException e2) { errorExit(«Fatal Error», «In onPause() and failed to close socket.» + e2.getMessage() + «.»); } } private void checkBTState() { // Check for Bluetooth support and then check to make sure it is turned on // Emulator doesn’t support Bluetooth and will return null if(btAdapter==null) { errorExit(«Fatal Error», «Bluetooth не поддерживается»); } else { if (btAdapter.isEnabled()) { Log.d(TAG, «…Bluetooth включен…»); } else { //Prompt user to turn on Bluetooth Intent enableBtIntent = new Intent(btAdapter.ACTION_REQUEST_ENABLE); startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT); } } } private void errorExit(String title, String message){ Toast.makeText(getBaseContext(), title + » — » + message, Toast.LENGTH_LONG).show(); finish(); } private void sendData(String message) { byte msgBuffer = message.getBytes(); Log.d(TAG, «…Посылаем данные: » + message + «…»); try { outStream.write(msgBuffer); } catch (IOException e) { String msg = «In onResume() and an exception occurred during write: » + e.getMessage(); if (address.equals(«00:00:00:00:00:00»)) msg = msg + «.\n\nВ переменной address у вас прописан 00:00:00:00:00:00, вам необходимо прописать реальный MAC-адрес Bluetooth модуля»; msg = msg + «.\n\nПроверьте поддержку SPP UUID: » + MY_UUID.toString() + » на Bluetooth модуле, к которому вы подключаетесь.\n\n»; errorExit(«Fatal Error», msg); } } }

Данный код найден на одном из зарубежных блогов и слегка модернизирован. Как видно выше, на кнопки мы вешаем обработчики событий. При нажатии на кнопку передается строка 1 или 0 через sendData() в буфер Bluetooth адаптера. Полный проект с исходными кодами приведен ниже. Для работы программы, необходим Android не ниже версии API15, т.е. 4.0.3 и выше.

Android — прием и передача данных к Arduino

А вот здесь пришлось повозиться. Дело в том, что в Android’е для приема данных от какого-либо устройства необходимо создавать отдельный фоновый поток, чтобы у нас не зависало основное активити. Для этого мы задействуем thread и все данные будут приниматься в отдельном потоке.

На окно главного активити мы добавим новый элемент TextView, который будет служить для отображения принятых данных от Arduino. Сам java-код главного активити я постарался хорошо прокомментировать, чтобы сделать его удобочитаемым:

package com.example.bluetooth2; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.UUID; import com.example.bluetooth2.R; 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.os.Handler; import android.util.Log; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.TextView; import android.widget.Toast; public class MainActivity extends Activity { private static final String TAG = «bluetooth2»; Button btnOn, btnOff; TextView txtArduino; Handler h; private static final int REQUEST_ENABLE_BT = 1; final int RECIEVE_MESSAGE = 1; // Статус для Handler private BluetoothAdapter btAdapter = null; private BluetoothSocket btSocket = null; private StringBuilder sb = new StringBuilder(); private ConnectedThread mConnectedThread; // SPP UUID сервиса private static final UUID MY_UUID = UUID.fromString(«00001101-0000-1000-8000-00805F9B34FB»); // MAC-адрес Bluetooth модуля private static String address = «00:15:FF:F2:19:4C»; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); btnOn = (Button) findViewById(R.id.btnOn); // кнопка включения btnOff = (Button) findViewById(R.id.btnOff); // кнопка выключения txtArduino = (TextView) findViewById(R.id.txtArduino); // для вывода текста, полученного от Arduino h = new Handler() { public void handleMessage(android.os.Message msg) { switch (msg.what) { case RECIEVE_MESSAGE: // если приняли сообщение в Handler byte readBuf = (byte) msg.obj; String strIncom = new String(readBuf, 0, msg.arg1); sb.append(strIncom); // формируем строку int endOfLineIndex = sb.indexOf(«\r\n»); // определяем символы конца строки if (endOfLineIndex > 0) { // если встречаем конец строки, String sbprint = sb.substring(0, endOfLineIndex); // то извлекаем строку sb.delete(0, sb.length()); // и очищаем sb txtArduino.setText(«Ответ от Arduino: » + sbprint); // обновляем TextView btnOff.setEnabled(true); btnOn.setEnabled(true); } //Log.d(TAG, «…Строка:»+ sb.toString() + «Байт:» + msg.arg1 + «…»); break; } }; }; btAdapter = BluetoothAdapter.getDefaultAdapter(); // получаем локальный Bluetooth адаптер checkBTState(); btnOn.setOnClickListener(new OnClickListener() { // определяем обработчик при нажатии на кнопку public void onClick(View v) { btnOn.setEnabled(false); mConnectedThread.write(«1»); // Отправляем через Bluetooth цифру 1 //Toast.makeText(getBaseContext(), «Включаем LED», Toast.LENGTH_SHORT).show(); } }); btnOff.setOnClickListener(new OnClickListener() { public void onClick(View v) { btnOff.setEnabled(false); mConnectedThread.write(«0»); // Отправляем через Bluetooth цифру 0 //Toast.makeText(getBaseContext(), «Выключаем LED», Toast.LENGTH_SHORT).show(); } }); } @Override public void onResume() { super.onResume(); Log.d(TAG, «…onResume — попытка соединения…»); // Set up a pointer to the remote node using it’s address. BluetoothDevice device = btAdapter.getRemoteDevice(address); // Two things are needed to make a connection: // A MAC address, which we got above. // A Service ID or UUID. In this case we are using the // UUID for SPP. try { btSocket = device.createRfcommSocketToServiceRecord(MY_UUID); } catch (IOException e) { errorExit(«Fatal Error», «In onResume() and socket create failed: » + e.getMessage() + «.»); } // Discovery is resource intensive. Make sure it isn’t going on // when you attempt to connect and pass your message. btAdapter.cancelDiscovery(); // Establish the connection. This will block until it connects. Log.d(TAG, «…Соединяемся…»); try { btSocket.connect(); Log.d(TAG, «…Соединение установлено и готово к передачи данных…»); } catch (IOException e) { try { btSocket.close(); } catch (IOException e2) { errorExit(«Fatal Error», «In onResume() and unable to close socket during connection failure» + e2.getMessage() + «.»); } } // Create a data stream so we can talk to server. Log.d(TAG, «…Создание Socket…»); mConnectedThread = new ConnectedThread(btSocket); mConnectedThread.start(); } @Override public void onPause() { super.onPause(); Log.d(TAG, «…In onPause()…»); try { btSocket.close(); } catch (IOException e2) { errorExit(«Fatal Error», «In onPause() and failed to close socket.» + e2.getMessage() + «.»); } } private void checkBTState() { // Check for Bluetooth support and then check to make sure it is turned on // Emulator doesn’t support Bluetooth and will return null if(btAdapter==null) { errorExit(«Fatal Error», «Bluetooth не поддерживается»); } else { if (btAdapter.isEnabled()) { Log.d(TAG, «…Bluetooth включен…»); } else { //Prompt user to turn on Bluetooth Intent enableBtIntent = new Intent(btAdapter.ACTION_REQUEST_ENABLE); startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT); } } } private void errorExit(String title, String message){ Toast.makeText(getBaseContext(), title + » — » + message, Toast.LENGTH_LONG).show(); finish(); } private class ConnectedThread extends Thread { private final BluetoothSocket mmSocket; private final InputStream mmInStream; private final OutputStream mmOutStream; public ConnectedThread(BluetoothSocket socket) { mmSocket = socket; InputStream tmpIn = null; OutputStream tmpOut = null; // Get the input and output streams, using temp objects because // member streams are final try { tmpIn = socket.getInputStream(); tmpOut = socket.getOutputStream(); } catch (IOException e) { } mmInStream = tmpIn; mmOutStream = tmpOut; } public void run() { byte buffer = new byte; // buffer store for the stream int bytes; // bytes returned from read() // Keep listening to the InputStream until an exception occurs while (true) { try { // Read from the InputStream bytes = mmInStream.read(buffer); // Получаем кол-во байт и само собщение в байтовый массив «buffer» h.obtainMessage(RECIEVE_MESSAGE, bytes, -1, buffer).sendToTarget(); // Отправляем в очередь сообщений Handler } catch (IOException e) { break; } } } /* Call this from the main activity to send data to the remote device */ public void write(String message) { Log.d(TAG, «…Данные для отправки: » + message + «…»); byte msgBuffer = message.getBytes(); try { mmOutStream.write(msgBuffer); } catch (IOException e) { Log.d(TAG, «…Ошибка отправки данных: » + e.getMessage() + «…»); } } /* Call this from the main activity to shutdown the connection */ public void cancel() { try { mmSocket.close(); } catch (IOException e) { } } } }

В данном примере для отправки данных мы используем отдельный поток Thread. Тоже самое и для приема данных — метод run(). Также обратите внимание на класс Handler, который служит для организации очереди сообщений и их вывода в главное активити. Дело в том, что в фоновом потоке нельзя напрямую выводить что-либо в главное активити, т.к. это приведет к «крашу» программы.
Класс StringBuilder используется для формирования строки из принятых данных. После, происходит поиск конца строки с символами \r\n, и если они найдены, то строка отображается на активити и обьект sb очищается, чтобы не произошло склейка с последующими принятыми данными.

К статье прилагаются скомпилированные файлы для Android: bluetooth1.apk и bluetooth2.apk, а также исходники проекта для Arduino IDE и Eclipse

Прикрепленные файлы: