Serial bluetooth terminal как работает
Перейти к содержимому

Serial bluetooth terminal как работает

  • автор:

ESP32: Bluetooth

В состав платы входит классический Bluetooth. Пример можно найти в разделе Examples/BluetoothSerial/SerialToSerialBT. В примере используется библиотека BluetoothSerial.

Bluetooth Low Energy (BLE) также доступен на плате. Это тема другой статьи

Рассмотрим упрощённый пример без дополнительных проверок. Просто будем посылать строку любому устройству, которое подключится к нашей плате.

 #include "BluetoothSerial.h" BluetoothSerial SerialBT; void setup() < SerialBT.begin("ESP32"); >void loop()

В реальных устройствах всё-таки не помешает дополнительная проверка.

 void setup() < Serial.begin(115200); if (!SerialBT.begin("ESP32")) < Serial.println("An error occurred initializing Bluetooth"); >else < Serial.println("Bluetooth initialized"); >> 

Посылаем данные через последовательный порт

В Windows вы можете обнаружить плату через специальное окно настроек «Bluetooth & other devices» (англ.версия). Затем в диспетчере устройств нужно посмотреть появившегося номер COM-порта. После этого в Arduino IDE нужно выбрать данный порт и открыть «Монитор порта», в котором будут появляться сообщения.

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

 #include "BluetoothSerial.h" BluetoothSerial SerialBT; void setup() < Serial.begin(115200); if (!SerialBT.begin("ESP32")) < Serial.println("An error occurred initializing Bluetooth"); >> void loop() < while (SerialBT.available()) < Serial.write(SerialBT.read()); >delay(50); > 

Данные удобно посылать через приложение Putty. В настройках выбираем тип соединения Serial и выставляем скорость. Главное — не ошибиться с номером порта, попробуйте методом перебора.

Putty General

Затем в блоке Terminal выбираем настройки Force on.

Putty Terminal

После запуска появляется чёрный экран консоли, в котором можно вводить команды.

Putty Console

Посылаемые команды отображаются в мониторе порта.

Serial Monitor

Регистрируем события

Мы посылаем сообщения вслепую, не зная, соединился ли клиент к плате. Чтобы избежать этой проблемы, можем добавить в скетч функцию обратного вызова через register_callback(). Тем самым мы сможем отслеживать момент соединения компьютера (Putty).

 #include "BluetoothSerial.h" BluetoothSerial SerialBT; void callback(esp_spp_cb_event_t event, esp_spp_cb_param_t *param) < if(event == ESP_SPP_SRV_OPEN_EVT)< Serial.println("Client Connected"); >> void setup() < Serial.begin(115200); SerialBT.register_callback(callback); if (!SerialBT.begin("ESP32")) < Serial.println("An error occurred initializing Bluetooth"); >else < Serial.println("Bluetooth initialized"); >> void loop() < while (SerialBT.available()) < Serial.write(SerialBT.read()); >delay(50); > 

Снова запустите скетч и установите соединение через Putty. В успешном случае в мониторе порта появится сообщение Client Connected.

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

 #include "BluetoothSerial.h" BluetoothSerial SerialBT; void callback(esp_spp_cb_event_t event, esp_spp_cb_param_t *param) < if (event == ESP_SPP_SRV_OPEN_EVT) < Serial.println("Client Connected"); Serial.println("Client Connected has address:"); for (int i = 0; i < 6; i++) < Serial.printf("%02X", param->srv_open.rem_bda[i]); if (i < 5) < Serial.print(":"); >> Serial.println("--------------"); > > void setup() < Serial.begin(115200); SerialBT.register_callback(callback); if (!SerialBT.begin("ESP32")) < Serial.println("An error occurred initializing Bluetooth"); >else < Serial.println("Bluetooth initialized"); >> void loop() < while (SerialBT.available()) < Serial.write(SerialBT.read()); >delay(50); > 

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

Client Bluetooth

Включаем светодиод с телефона

Посылать данные можно с Android-телефона. Сначала в настройках нужно присоединиться к плате, а затем через приложение, которое умеет работать как Bluetooth-терминал (например, Bluetooth Terminal), увидеть поступающие сообщения или отправлять собственные команды.

Немного видоизменённый пример, в котором добавлена проверка на поступление символов 0 и 1 с Android-устройства (код для Android).

 // Подключаем библиотеку #include "BluetoothSerial.h" // Проверка, что Bluetooth доступен на плате #if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED) #error Bluetooth is not enabled! Please run `make menuconfig` to and enable it #endif // Создаём экземпляр класса BluetoothSerial SerialBT; int LED = 2; // встроенный светодиод void setup() < Serial.begin(115200); // включаем передачу данных у последовательного порта SerialBT.begin("ESP32"); // Может придумать своё имя Serial.println("The device started, now you can pair it with bluetooth!"); pinMode(LED, OUTPUT); >void loop() < if (Serial.available()) < SerialBT.write(Serial.read()); >if (SerialBT.available()) < char incomingChar = SerialBT.read(); Serial.write(incomingChar); // При символе "1" включаем светодиод if (incomingChar == '1') < digitalWrite(LED, HIGH); Serial.println("On"); >// При символе "0" выключаем светодиод if ( incomingChar == '0') < digitalWrite(LED, LOW); Serial.println("Off"); >> delay(20); > 

После заливки скетча нужно дождаться появления надписи «The device started, now you can pair it with bluetooth!» в мониторе порта.

Дальше нужно послать команды. Это можно сделать через программу на Android (ссылка на исходник дана выше) или можно использовать готовую программу Bluetooth Terminal.

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

В последнее время наткнулся на новый терминал Serial Bluetooth Terminal с открытыми исходниками для Android-устройств Classic Bluetooth и BLE.

Узнать адрес ESP32-устройства

С помощью низкоуровневых функций можно узнать адрес-устройства.

У каждого Bluetooth-устройства есть адрес, по которому можно определить изготовителя. На сайте можно вбить адрес и получить имя производителя.

 #include "esp_bt_main.h" #include "esp_bt_device.h" bool initBluetooth() < if (!btStart()) < Serial.println("Failed to initialize controller"); return false; >if (esp_bluedroid_init() != ESP_OK) < Serial.println("Failed to initialize bluedroid"); return false; >if (esp_bluedroid_enable() != ESP_OK) < Serial.println("Failed to enable bluedroid"); return false; >> void printDeviceAddress() < const uint8_t* point = esp_bt_dev_get_address(); for (int i = 0; i < 6; i++) < char str[3]; sprintf(str, "%02X", (int)point[i]); Serial.print(str); if (i < 5) < Serial.print(":"); >> > void setup() < Serial.begin(115200); initBluetooth(); printDeviceAddress(); >void loop() <> 

После запуска скетча откройте монитор порта. Там вы должны увидеть адрес вида 24:0A:C4:27:07:66. Скопируйте адрес и определите производителя через сайт (ссылка выше). В моём случае это оказался Espressif Inc.

Присвоить новое имя устройству

Функция esp_bt_dev_set_device_name() позволяет присвоить устройству новое имя.

 #include "esp_bt_main.h" #include "esp_gap_bt_api.h" #include "esp_bt_device.h" bool initBluetooth(const char *deviceName) < if (!btStart()) < Serial.println("Failed to initialize controller"); return false; >if (esp_bluedroid_init() != ESP_OK) < Serial.println("Failed to initialize bluedroid"); return false; >if (esp_bluedroid_enable() != ESP_OK) < Serial.println("Failed to enable bluedroid"); return false; >esp_bt_dev_set_device_name(deviceName); esp_bt_gap_set_scan_mode(ESP_BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE); > void setup() < Serial.begin(115200); if (!initBluetooth("ESP32 BT")) < Serial.println("Bluetooth init failed"); >; > void loop() <> 

Запустите пример и откройте монитор порта. Если никаких сообщений вы не видите, значит инициализация модуля прошла успешно. Теперь можете открыть окно настроек в Windows или на Android-телефоне и посмотреть список доступных Bluetooth-устройств. В списке вы должны увидеть устройство под именем «ESP32 BT».

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

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

В предыдущей статье УправляемArduino через USB. Библиотека Serial.Я рассказал как можно управлять Arduino с компьютера. Bluetooth модуль устроит так, что он работает с библиотекой Serial. Поэтому Bluetooth является самым простым инструментом для беспроводного управления. Но у него тоже есть свои минусы и ограничения о которых я расскажу в следующих проектах.

Рассмотрим подключения на примере Bluetooth модуля HC-06 . Модуль подключается к 0 и 1 пинам ардуины.

Bluetooth модуля HC-06

Схема подключения Bluetooth модуля HC-06 к Arduono UNO.

Схема подключения Bluetooth модуля HC-06 к Arduono UNO

Схема подключения Bluetooth модуля HC-06 к Arduono NANO .

Схема подключения Bluetooth модуля HC-06 к Arduono NANO

Будите внимательны. Подключать нужно RX =>TXD, TX =>RXD.
Скетч будим использовать из статьи: Управляем Arduino через USB. Библиотека Serial .

int LED = 13; int val = 0; void setup() < Serial.begin(9600); //Инициирует последовательное //соединение и задает скорость передачи данных в бит/c (бод) pinMode(LED, OUTPUT); digitalWrite(LED, HIGH); >void loop() < if (Serial.available() >0) // пришли данные < val = Serial.read(); if (val=='1') // если 1 то включаем светодиод < digitalWrite(LED,HIGH); Serial.print("Led On - "); // вывод данных Serial.println("Portal-Pk.ru"); // вывод данных с переносом строки >if (val=='0') // если 0 то выключаем светодиод < digitalWrite(LED,LOW); Serial.print("Led Off - "); // вывод данных Serial.println("Portal-Pk.ru"); // вывод данных с переносом строки >> >

Чтобы ни чего самостоятельно не писать для Android. Воспользуемся готовым приложением который умеет подключаться к Bluetooth устройствам и отправлять и получать данные в терминал — Bluetooth Terminal.

Скачать его можно в Плей маркете. В поиск вбиваем Bluetooth Terminal.

В поиск вбиваем Bluetooth Terminal

Устанавливаем приложение

Запускаем его и ищем наше устройство.

Запускаем его и ищем наше устройство.

Почему-то мое устройство видит как HC-05. Но это не страшно работают данные модули одинаково.

Сейчас оправим в терминале 1. Светодиод на плате включается, при этом мы получаем в терминал ответ «Led On - Portal-Pk.ru»

Сейчас оправим в терминале 1. Светодиод на плате включается, при этом мы получаем в терминал ответ «Led On — Portal-Pk.ru»

Led On - Portal-Pk.ru

Если отправим 0, выключается, при этом мы получаем в терминал ответ «Led Off — Portal-Pk.ru»

Если отправим 0, выключается, при этом мы получаем в терминал ответ «Led Off - Portal-Pk.ru»

Это самый простои пример управления с помощью Bluetooth модуля. Планирую сделать несколько проектов по данной теме. Написать приложение для Android.

Описание

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

Дополнительные модули

Предполагается что у Вас уже есть набор МиниБот, и вы собрали его по инструкции в руководстве пользователя. Тогда дополнительно понадобится на выбор один из двух Bluetooth модулей: Bluetooth SE или HC-05. Мы остановимся на версии Bluetooth SE и ниже будет рассмотрен пример с его использованием. Однако, работа с модулем HC-05 аналогична и не вызовет трудностей.

Что нужно Кол-во, шт
Bluetooth модуль SE 1

Библиотеки

Порядок действий

Шаг 1. Установите библиотеки

Установите в Arduino IDE библиотеки, которые представлены по ссылкам выше (в подпункте «Библиотеки»). О том как устанавливаются библиотеки описано в руководстве пользователя, входящем в комплект, либо посетите соответствующий раздел Базы Знаний.

Шаг 2. Загрузите скетч на контроллер

В скетче мы описываем при получении каких команд с модуля наш робот должен двигаться. Например, команда «F» — означает движение вперёд. Общий список команд:

Команда Движение робота
F Движение вперёд
B Движение назад
L Движение влево
R Движение вправо
S Остановка

Загрузите на контроллер следующий скетч, описывающий выполнение команд движения робота:

#include //подключение библиотеки для работы с платформой. robotSE robot; //создание объекта робота void setup() { //инициализация Serial-соединения для получения команд от WiFi модуля Serial.begin(9600); } void loop() { String command = Serial.readStringUntil('\n'); //чтение строки из Serial-порта command.trim(); //обрезать строку (убрать незначащие символы) if (command == "F") { //если это команда F robot.move_forward(); //двигаться вперед Serial.println("FORWARD"); //поясняющая надпись в модуль } if (command == "L") { //если это команда L robot.move_left(); //двигаться влево Serial.println("LEFT"); //поясняющая надпись в модуль } if (command == "S") { //если это команда S robot.move_stop(); //остановиться Serial.println("STOP"); //поясняющая надпись в модуль } if (command == "R") { //если это команда R robot.move_right(); //двигаться вправо Serial.println("RIGHT"); //поясняющая надпись в модуль } if (command == "B") { //если это команда B robot.move_back(); //двигаться назад Serial.println("BACK"); //поясняющая надпись в модуль } }

Шаг 3. Подключите Bluetooth — модуль

Обратите внимание, что мы подключаем модуль к контроллеру уже после того как на контроллер загружен скетч. После подключения Bluetooth модуля к выводам UART, контроллер уже не сможет ими пользоваться для связи с компьютером. И Serial порт будет занят Bluettoth модулем.

Вывод Bluetooth модуль SE Вывод Motor Shield
+ +
TX RXD
RX TXD
SYS1
SYS2

Шаг 4. Установка и настройка приложения

После того, как модуль подключен к контроллеру, нам нужно установить приложение для работы с блютус на смартфоне. На примере ОС Android рассмотрим процесс установки приложения.

В магазине приложений найдите приложение serial bluetooth terminal и установите его.

В настройках телефона активируйте Bluetooth соединения.

Откройте приложение Serial Bluetooth Terminal, войдите в основное меню.

Выберите раздел Devices, перейдите на вкладку Bluetooth LE и нажмите Scan.

После сканирования устройств, выберите нужное устройство. (Если Вы до этого не меняли его имени, то имя должно содержать фразу «BT_SE»).

При выборе устройства, приложение снова откроет начальную страницу (терминал) и отобразит состояние подключения.

Далее, в поле ввода, наберите с клавиатуры любую команду из описанных выше, и нажмите кнопку отправить. После отправки, сообщение отобразится в терминале. В терминал выведется информация о направлении движения робота. Робот начнёт двигаться в указанную сторону.

Шаг 5. Быстрые команды

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

Сейчас мы выполним настройку приложения, чтобы команды отправлялись быстро. В нижней части приложения, можно заметить семь кнопок для быстрого ввода (М1, М2, М3, М4, М5, М6, М7). На эти кнопки можно установить команду, которая будет отправляться по нажатию на кнопку, а так же изменить название кнопки. Для этого выполните долгое нажатие по кнопке М1:

И в открывшемся окне редактирования быстрой команды, измените значение полей Name (имя) на F, и в поле Value (значение) также укажите команду F. И нажмите «галочку» для подтверждения.

Аналогично отредактируйте остальные кнопки:

Кнопка Значение Name Значение Value
M1 F F
M2 L L
M3 S S
M4 R R
M5 B B

После введённых значений, нажимая на кнопку команда отправляется сразу же на модуль и робот моментально выполняет указанные движения.

Шаг 6. Запуск

Управляйте роботом с помощью отправляемых команд на Bluetooth-модуль через смартфон.

© 2014-2023 УмныеЭлементы — DIY-электроника Arduino, компоненты для робототехники и электронных устройств. «УмныеЭлементы» (SmartElements) является зарегистрированным товарным знаком. Любое воспроизведение товарного знака допускается только с согласия правообладателя.

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

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

Arduino

Подключение Bluetooth модуля HC-06 к 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!"); >> >

MAC-адрес

Программа работает очень просто. После запуска или сброса устройства, в последовательный порт выводится сообщение с предложением нажать 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[256]; // 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

  • arduino64.rar (1371 Кб)
  • Bluetooth1.apk (161 Кб)
  • Bluetooth2.apk (161 Кб)

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *