Android + Bluetooth + Arduino
![Android + Bluetooth + Arduino Android + Bluetooth + Arduino](http://istarik.ru/uploads/images/00/00/01/2016/02/14/de2359.png)
Android-приложение для обмена данными с ардуино при помощи bluetooth-модуля HC-05.
Приложение будет отправлять ардуине команды включения-отключения D10...D13, а та, в свою очередь, сообщать о выполненных действиях.
![](http://istarik.ru/uploads/images/00/00/01/2016/02/13/5c38dd.png)
Прежде чем приступать к написанию приложения, необходимо проверить настройки bluetooth-модуля и подключить его к ардуине.
Настройка модуля подробно описана здесь, проделайте всё, что написано в разделе Bluetooth до фразы "Модуль настроен".
После настройки заливаем в ардуину код…
char incomingbyte; // переменная для приема данных
void setup()
{
Serial.begin(9600);
pinMode(10, OUTPUT);
pinMode(11, OUTPUT);
pinMode(12, OUTPUT);
pinMode(13, OUTPUT);
}
void loop()
{
if(Serial.available() > 0) // есть ли что-то в буфере
{
incomingbyte = Serial.read(); // чтение символа
switch (incomingbyte)
{
case 'A':
digitalWrite(10,HIGH);
Serial.println("D10 ON");
break;
case 'a':
digitalWrite(10,LOW);
Serial.println("D10 OFF");
break;
case 'B':
digitalWrite(11,HIGH);
Serial.println("D11 ON");
break;
case 'b':
digitalWrite(11,LOW);
Serial.println("D11 OFF");
break;
case 'C':
digitalWrite(12,HIGH);
Serial.println("D12 ON");
break;
case 'c':
digitalWrite(12,LOW);
Serial.println("D12 OFF");
break;
case 'D':
digitalWrite(13,HIGH);
Serial.println("D13 ON");
break;
case 'd':
digitalWrite(13,LOW);
Serial.println("D13 OFF");
break;
default:
break;
}
}
}
… и соединяем её с модулем по этой схеме:
![](http://istarik.ru/uploads/images/00/00/01/2016/02/05/f30eda.png)
Выполните сопряжение телефона с модулем.
Android
Кто не хочет обременять себя написанием приложения, может скачать готовый apk-файл, а если есть желание попрограммировать тогда...
Скачиваем, устанавливаем и запускаем Android Studio.
![](http://istarik.ru/uploads/images/00/00/01/2016/02/13/187e16.png)
В процессе работы нужно будет установить sdk.
Создаём новый проект под названием BlueArdu
![](http://istarik.ru/uploads/images/00/00/01/2016/02/13/9ba1df.png)
Next...
Оставляем как есть…
![](http://istarik.ru/uploads/images/00/00/01/2016/02/13/66f11f.png)
Next...
Выбираем Empty Activity
![](http://istarik.ru/uploads/images/00/00/01/2016/02/13/c2de37.png)
Next...
Оставляем как есть…
![](http://istarik.ru/uploads/images/00/00/01/2016/02/13/cf584b.png)
Finish
Открываем файл AndroidManifest.xml
![](http://istarik.ru/uploads/images/00/00/01/2016/02/13/9e3ba2.png)
После строчки package=«com.example.dima.blueardu» > добавляем разрешение на использование bluetooth:
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
Строку <activity android:name=".MainActivity" > делаем так:
<activity android:name=".MainActivity" android:screenOrientation="portrait">
Портретная ориентация.
В результате будет так:
![](http://istarik.ru/uploads/images/00/00/01/2016/02/13/eca47e.png)
Кликаем по вкладке activity_main.xml и внизу выбираем вкладку Text
![](http://istarik.ru/uploads/images/00/00/01/2016/02/13/d9522b.png)
Удаляем всё, что там написано и вставляем вот это:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
tools:context=".MainActivity"
android:id="@+id/osnova"
android:background="#e7e8ea"
android:contextClickable="true">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/textInfo"
android:textSize="22dp"
android:layout_marginLeft="20dp"
android:layout_marginTop="20dp"
android:visibility="visible" />
<ListView
android:layout_width="250dp"
android:layout_height="wrap_content"
android:id="@+id/pairedlist"
android:layout_below="@+id/textInfo"
android:layout_alignParentStart="true"
android:layout_marginTop="30dp"
android:layout_marginLeft="20dp"
android:visibility="visible" />
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#e7e7e5"
android:id="@+id/ButPanel"
android:visibility="gone">
<!--D10-->
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/imageButton"
android:layout_gravity="left|top"
android:src="@drawable/offlamp"
android:layout_marginTop="20dp"
android:layout_marginLeft="30dp"
android:onClick="onClickBut1" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="D10"
android:id="@+id/d10"
android:layout_gravity="center_horizontal|top"
android:textSize="30dp"
android:layout_marginTop="30dp" />
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/imageButton2"
android:layout_gravity="right|top"
android:layout_marginTop="20dp"
android:layout_marginRight="30dp"
android:src="@drawable/onlamp"
android:onClick="onClickBut2" />
<!--D11-->
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/imageButton3"
android:layout_gravity="left|top"
android:src="@drawable/offlamp"
android:layout_marginTop="100dp"
android:layout_marginLeft="30dp"
android:onClick="onClickBut3" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="D11"
android:id="@+id/d11"
android:layout_gravity="center_horizontal|top"
android:textSize="30dp"
android:layout_marginTop="110dp" />
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/imageButton4"
android:layout_gravity="right|top"
android:layout_marginTop="100dp"
android:layout_marginRight="30dp"
android:src="@drawable/onlamp"
android:onClick="onClickBut4" />
<!--D12-->
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/imageButton5"
android:layout_gravity="left|top"
android:src="@drawable/offlamp"
android:layout_marginTop="180dp"
android:layout_marginLeft="30dp"
android:onClick="onClickBut5" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="D12"
android:id="@+id/d12"
android:layout_gravity="center_horizontal|top"
android:textSize="30dp"
android:layout_marginTop="190dp" />
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/imageButton6"
android:layout_gravity="right|top"
android:layout_marginTop="180dp"
android:layout_marginRight="30dp"
android:src="@drawable/onlamp"
android:onClick="onClickBut6" />
<!--D13-->
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/imageButton7"
android:layout_gravity="left|top"
android:src="@drawable/offlamp"
android:layout_marginTop="260dp"
android:layout_marginLeft="30dp"
android:onClick="onClickBut7" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="D13"
android:id="@+id/d13"
android:layout_gravity="center_horizontal|top"
android:textSize="30dp"
android:layout_marginTop="270dp" />
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/imageButton8"
android:layout_gravity="right|top"
android:layout_marginTop="260dp"
android:layout_marginRight="30dp"
android:src="@drawable/onlamp"
android:onClick="onClickBut8" />
</FrameLayout>
</RelativeLayout>
Красным цветом подсвечиваются ошибки. В данном случае среда сообщает об отсутствии картинок offlamp
![](http://istarik.ru/uploads/images/00/00/01/2016/02/14/87523a.png)
![](http://istarik.ru/uploads/images/00/00/01/2016/02/14/6c9bda.png)
![](http://istarik.ru/uploads/images/00/00/01/2016/02/14/ee5e12.png)
Сохраните картинки себе на компьютер. После этого скопируйте offlamp.png в буфер (правой кнопкой «копировать»), выберите (правой кнопкой) в левой колонке папку drawable и нажмите вставить.
![](http://istarik.ru/uploads/images/00/00/01/2016/02/14/4e3eb1.png)
OK...
То же самое проделайте со второй картинкой. После этого надписи станут зелёными.
Далее откройте вкладку MainActivity.java, удалите всё кроме первой строчки и вставьте этот код:
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.FrameLayout;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Set;
import java.util.UUID;
import static android.R.layout.*;
public class MainActivity extends AppCompatActivity {
private static final int REQUEST_ENABLE_BT = 1;
BluetoothAdapter bluetoothAdapter;
ArrayList<String> pairedDeviceArrayList;
ListView listViewPairedDevice;
FrameLayout ButPanel;
ArrayAdapter<String> pairedDeviceAdapter;
private UUID myUUID;
ThreadConnectBTdevice myThreadConnectBTdevice;
ThreadConnected myThreadConnected;
private StringBuilder sb = new StringBuilder();
public TextView textInfo, d10, d11, d12, d13;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final String UUID_STRING_WELL_KNOWN_SPP = "00001101-0000-1000-8000-00805F9B34FB";
textInfo = (TextView)findViewById(R.id.textInfo);
d10 = (TextView)findViewById(R.id.d10);
d11 = (TextView)findViewById(R.id.d11);
d12 = (TextView)findViewById(R.id.d12);
d13 = (TextView)findViewById(R.id.d13);
listViewPairedDevice = (ListView)findViewById(R.id.pairedlist);
ButPanel = (FrameLayout) findViewById(R.id.ButPanel);
if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH)){
Toast.makeText(this, "BLUETOOTH NOT support", Toast.LENGTH_LONG).show();
finish();
return;
}
myUUID = UUID.fromString(UUID_STRING_WELL_KNOWN_SPP);
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (bluetoothAdapter == null) {
Toast.makeText(this, "Bluetooth is not supported on this hardware platform", Toast.LENGTH_LONG).show();
finish();
return;
}
String stInfo = bluetoothAdapter.getName() + " " + bluetoothAdapter.getAddress();
textInfo.setText(String.format("Это устройство: %s", stInfo));
} // END onCreate
@Override
protected void onStart() { // Запрос на включение Bluetooth
super.onStart();
if (!bluetoothAdapter.isEnabled()) {
Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableIntent, REQUEST_ENABLE_BT);
}
setup();
}
private void setup() { // Создание списка сопряжённых Bluetooth-устройств
Set<BluetoothDevice> pairedDevices = bluetoothAdapter.getBondedDevices();
if (pairedDevices.size() > 0) { // Если есть сопряжённые устройства
pairedDeviceArrayList = new ArrayList<>();
for (BluetoothDevice device : pairedDevices) { // Добавляем сопряжённые устройства - Имя + MAC-адресс
pairedDeviceArrayList.add(device.getName() + "\n" + device.getAddress());
}
pairedDeviceAdapter = new ArrayAdapter<>(this, simple_list_item_1, pairedDeviceArrayList);
listViewPairedDevice.setAdapter(pairedDeviceAdapter);
listViewPairedDevice.setOnItemClickListener(new AdapterView.OnItemClickListener() { // Клик по нужному устройству
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
listViewPairedDevice.setVisibility(View.GONE); // После клика скрываем список
String itemValue = (String) listViewPairedDevice.getItemAtPosition(position);
String MAC = itemValue.substring(itemValue.length() - 17); // Вычленяем MAC-адрес
BluetoothDevice device2 = bluetoothAdapter.getRemoteDevice(MAC);
myThreadConnectBTdevice = new ThreadConnectBTdevice(device2);
myThreadConnectBTdevice.start(); // Запускаем поток для подключения Bluetooth
}
});
}
}
@Override
protected void onDestroy() { // Закрытие приложения
super.onDestroy();
if(myThreadConnectBTdevice!=null) myThreadConnectBTdevice.cancel();
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if(requestCode == REQUEST_ENABLE_BT){ // Если разрешили включить Bluetooth, тогда void setup()
if(resultCode == Activity.RESULT_OK) {
setup();
}
else { // Если не разрешили, тогда закрываем приложение
Toast.makeText(this, "BlueTooth не включён", Toast.LENGTH_SHORT).show();
finish();
}
}
}
private class ThreadConnectBTdevice extends Thread { // Поток для коннекта с Bluetooth
private BluetoothSocket bluetoothSocket = null;
private ThreadConnectBTdevice(BluetoothDevice device) {
try {
bluetoothSocket = device.createRfcommSocketToServiceRecord(myUUID);
}
catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void run() { // Коннект
boolean success = false;
try {
bluetoothSocket.connect();
success = true;
}
catch (IOException e) {
e.printStackTrace();
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(MainActivity.this, "Нет коннекта, проверьте Bluetooth-устройство с которым хотите соединица!", Toast.LENGTH_LONG).show();
listViewPairedDevice.setVisibility(View.VISIBLE);
}
});
try {
bluetoothSocket.close();
}
catch (IOException e1) {
e1.printStackTrace();
}
}
if(success) { // Если законнектились, тогда открываем панель с кнопками и запускаем поток приёма и отправки данных
runOnUiThread(new Runnable() {
@Override
public void run() {
ButPanel.setVisibility(View.VISIBLE); // открываем панель с кнопками
}
});
myThreadConnected = new ThreadConnected(bluetoothSocket);
myThreadConnected.start(); // запуск потока приёма и отправки данных
}
}
public void cancel() {
Toast.makeText(getApplicationContext(), "Close - BluetoothSocket", Toast.LENGTH_LONG).show();
try {
bluetoothSocket.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
} // END ThreadConnectBTdevice:
private class ThreadConnected extends Thread { // Поток - приём и отправка данных
private final InputStream connectedInputStream;
private final OutputStream connectedOutputStream;
private String sbprint;
public ThreadConnected(BluetoothSocket socket) {
InputStream in = null;
OutputStream out = null;
try {
in = socket.getInputStream();
out = socket.getOutputStream();
}
catch (IOException e) {
e.printStackTrace();
}
connectedInputStream = in;
connectedOutputStream = out;
}
@Override
public void run() { // Приём данных
while (true) {
try {
byte[] buffer = new byte[1];
int bytes = connectedInputStream.read(buffer);
String strIncom = new String(buffer, 0, bytes);
sb.append(strIncom); // собираем символы в строку
int endOfLineIndex = sb.indexOf("\r\n"); // определяем конец строки
if (endOfLineIndex > 0) {
sbprint = sb.substring(0, endOfLineIndex);
sb.delete(0, sb.length());
runOnUiThread(new Runnable() { // Вывод данных
@Override
public void run() {
switch (sbprint) {
case "D10 ON":
d10.setText(sbprint);
break;
case "D10 OFF":
d10.setText(sbprint);
break;
case "D11 ON":
d11.setText(sbprint);
break;
case "D11 OFF":
d11.setText(sbprint);
break;
case "D12 ON":
d12.setText(sbprint);
break;
case "D12 OFF":
d12.setText(sbprint);
break;
case "D13 ON":
d13.setText(sbprint);
break;
case "D13 OFF":
d13.setText(sbprint);
break;
default:
break;
}
}
});
}
} catch (IOException e) {
break;
}
}
}
public void write(byte[] buffer) {
try {
connectedOutputStream.write(buffer);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
/////////////////// Нажатие кнопок /////////////////////
/////////////////////////D10////////////////////////////
public void onClickBut1(View v) {
if(myThreadConnected!=null) {
byte[] bytesToSend = "a".getBytes();
myThreadConnected.write(bytesToSend );
}
}
public void onClickBut2(View v) {
if(myThreadConnected!=null) {
byte[] bytesToSend = "A".getBytes();
myThreadConnected.write(bytesToSend );
}
}
////////////////////////D11////////////////////////////
public void onClickBut3(View v) {
if(myThreadConnected!=null) {
byte[] bytesToSend = "b".getBytes();
myThreadConnected.write(bytesToSend );
}
}
public void onClickBut4(View v) {
if(myThreadConnected!=null) {
byte[] bytesToSend = "B".getBytes();
myThreadConnected.write(bytesToSend );
}
}
//////////////////////D12//////////////////////////
public void onClickBut5(View v) {
if(myThreadConnected!=null) {
byte[] bytesToSend = "c".getBytes();
myThreadConnected.write(bytesToSend );
}
}
public void onClickBut6(View v) {
if(myThreadConnected!=null) {
byte[] bytesToSend = "C".getBytes();
myThreadConnected.write(bytesToSend );
}
}
//////////////////////D13//////////////////////////
public void onClickBut7(View v) {
if(myThreadConnected!=null) {
byte[] bytesToSend = "d".getBytes();
myThreadConnected.write(bytesToSend );
}
}
public void onClickBut8(View v) {
if(myThreadConnected!=null) {
byte[] bytesToSend = "D".getBytes();
myThreadConnected.write(bytesToSend );
}
}
} // END
Если всё сделано правильно, то никаких ошибок не должно быть.
Разрешите на телефоне отладку по USB:
![](http://istarik.ru/uploads/images/00/00/01/2016/02/14/01af47.png)
Подключите телефон к компьютеру и запустите компиляцию нажав зелёную стрелку:
![](http://istarik.ru/uploads/images/00/00/01/2016/02/14/f8fd3b.png)
Через некоторое время появится окно с выбором устройства на котором будет запущено приложение:
![](http://istarik.ru/uploads/images/00/00/01/2016/02/14/2116e3.png)
Отсутствие в списке телефона, означает какие-то проблемы с драйверами.
Нажмите ОК, приложение установится и откроется окно со списком сопряжённых устройств:
![](http://istarik.ru/uploads/images/00/00/01/2016/02/14/089729.png)
Выберите ваш модуль и после соединения откроется главное окно программы:
![](http://istarik.ru/uploads/images/00/00/01/2016/02/14/e9fd5a.png)
На этом всё, далее можно приступать к изучению программирования под Android и добавлять свой функционал.
Скачать исходники.
Здесь можно почитать о том, как сделать метеостанцию.
![](http://istarik.ru/uploads/images/thnd.png)
- +487
- stD
58739
Поддержать автора
Комментарии (4)