- ESP32: Bluetooth
- Посылаем данные через последовательный порт
- Регистрируем события
- Включаем светодиод с телефона
- Узнать адрес ESP32-устройства
- Присвоить новое имя устройству
- Arduino.ru
- Почему блютуз модуль не работает как Serial на Ардуино mega
- Checking if the bluetooth module on my Arduino board works
- I am trying to send data via bluetooth but Serial.available() always return 0
ESP32: Bluetooth
В состав платы входит классический Bluetooth. Пример можно найти в разделе Examples/BluetoothSerial/SerialToSerialBT. В примере используется библиотека BluetoothSerial.
Рассмотрим упрощённый пример без дополнительных проверок. Просто будем посылать строку любому устройству, которое подключится к нашей плате.
#include "BluetoothSerial.h" BluetoothSerial SerialBT; void setup() < SerialBT.begin("ESP32"); >void loop()
В реальных устройствах всё-таки не помешает дополнительная проверка.
Посылаем данные через последовательный порт
В 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 и выставляем скорость. Главное — не ошибиться с номером порта, попробуйте методом перебора.
Затем в блоке Terminal выбираем настройки Force on.
После запуска появляется чёрный экран консоли, в котором можно вводить команды.
Посылаемые команды отображаются в мониторе порта.
Регистрируем события
Мы посылаем сообщения вслепую, не зная, соединился ли клиент к плате. Чтобы избежать этой проблемы, можем добавить в скетч функцию обратного вызова через 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); >
Снова пытаемся соединиться с платой с компьютера или телефона и получаем адреса подключаемых устройств. На скриншоте показано, как я дважды подключался к плате с разных устройств.
Включаем светодиод с телефона
Посылать данные можно с 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».
Arduino.ru
Почему блютуз модуль не работает как Serial на Ардуино mega
Друзья, подскажите плиз всю голову сломал:
Подключаю его к плате Arduino — Mega как положено:
RXD модуля — к TX(1), TXD модуля — к RX(0), VCC- к 5 V, GND- к GND
Хочу: Из программы-терминал посылать символы ‘1’ и ‘0’ для включения/выключения светодиода, а при нажатии кнопки, подключенной к ардуино, — выводить в терминал строку «I am Dima».
БТ-модуль с БТ-адаптером благополучно соединяется и в терминале коннектится как COM-порт № Х. Светодиодик на БТ-модуле горит. При нажатии кнопки строка Serial.println(«I am Dima») в терминале появляется! А вот наоборот — ни фига! При отправке любого символа из терминала на ардуину (Терминал- COM-порт Х — БТ-адаптер — БТ-модуль — Serial — Ардуина) в Serial у ардуины ничего не появляется ,т.е.
Неужели ни у кого не возникало такой проблемы кроме меня.
выложите код полностью. только сначала прочитайте в правилах, как это делается.
Да там код простейший, дело не в коде. Сейчас выложу.
void setup() < Serial.begin(9600); // подключаем последовательный порт pinMode(13, OUTPUT); // объявляем пин 13 как выход // UNO //MsTimer2::set(INTERRUPT_PERIOD, timerInterupt); // задаем период прерывания по таймеру в мс //MsTimer2::start(); // разрешаем прерывание по таймеру // MEGA FlexiTimer2::set(2,1/1000, timerInterupt); // задаем период прерывания по таймеру 2 мс FlexiTimer2::start(); >void loop() < if (Serial.available()) // проверяем, поступают ли какие-то команды < Serial.println("Serial available !"); val = Serial.read(); // переменная val равна полученной команде if (val == '1')
Задействовать другой порт, так как этот serial заведен на второй МК для связи по USB !
if (Serial.available()) // проверяем, поступают ли какие-то команды < Serial.println("Serial available !");
Событие Serial.available() почему то не наступает никогда! Вопрос - почему?
Можно чуть подробнее? Что значит " на второй МК для связи по USB" ? От USB я арудину естественно отключил. И потом - как же это работает на UNO .
На UNO нет второго МК на плате ! То что вы отключили USB, никак не отключило второй МК от главное МК. У вас сейчас Tx от платы BT посажен на Tx от второго МК .
if (Serial.available()) // проверяем, поступают ли какие-то команды < Serial.println("Serial available !");
Событие Serial.available() почему то не наступает никогда! Вопрос - почему?
Схему меги посмотрите - там видно что PE0 и PE1 соединены со вторым МК, который выступает как USB-serial и он ВСЕГДА занимает сериал, если только не перерезать дорожки или перепрограммировать второй МК - оба способа убьют заливку скетчей по USB !
Вы хотите сказать, что Serial1 yа меге нельзя использовать не для чего другого как только для загрузки программы? А для обмена по UART его использовать никак нельзя? Я просто все свои проекты делал на UNO и с мегой как-то совсем плохо знаком.
А как задействовать другой порт? просто соединить с пинами 14 и 15 ? В программе что-то нужно менять?
Перерезать дорожки. это я вряд ли рискну
Плата Arduino Mega имеет три дополнительных последовательных порта: Serial1 на портах 19 (RX) и 18 (TX), Serial2 на портах на портах 17 (RX) и 16 (TX), Serial3 на портах на портах 15 (RX) и 14 (TX). Чтобы использовать эти порты для связи с компьютером понадобится дополнительные адаптеры USB-to-serial, т.к. они не подключены к встроенному адаптеру платы Mega. Для связи с внешним устройством через последовательный интерфейс соедините TX порт вашего устройства с RX портом внешнего устройства и RX порт вашего устройства с портом TX внешнего и соедините "землю" на устройствах. (Важно! Не подключайте эти порты напрямую к RS232 порту, это может повредить плату).
Через этот serial удобно обмениваться с компом через USB.
У меги несколько serial. Надо выбрать Serial1 Serial2 Serial3 и соответствующие ножки.
Checking if the bluetooth module on my Arduino board works
I'm trying to have my Arduino UNO board to work with a BlueSmirf Gold (http://www.sparkfun.com/products/10268). I wired it as explained on various tutorial (for example here: http://www.instructables.com/id/how-to-Control-arduino-by-bluetooth-from-PC-pock/) I've set the baud rate to 9600 as explained here: http://forum.sparkfun.com/viewtopic.php?p=94557 I manage to connect to it using the default Arduino serial terminal, ZTerm and my phone (using Amarino). In every cases, the green light on the bluetooth modem turns on, so until there it looks good. The main problem is that my modem does not seem to be able to send/receive anything (the only time I've had any response was when I've set the baud rate to 9600). For example, I have this code (simplified here, but the main idea is there):
int out_pin = 2; String readLine() < char command[100]; int i = 0; if(Serial.available())< delay(100); while( Serial.available() >0 && i < 99) < command[i++] = Serial.read(); >command[i++]='\0'; Serial.flush(); > Serial.print("command: "); Serial.println(command); return (String) command; > void menu() < if (Serial.available() String command = readLine(); // Do thing based on the command > void setup() < pinMode(out_pin, OUTPUT); Serial.begin(9600); >void loop()
Logically, when I send something via the terminal, I should get it back (which is what happens when using the usb serial). When I connect to the board via Bluetooth, it just stays silent. I also tried this piece of code:
- Arduino - Phone connected via Bluetooth
- The Amarino monitoring was on
- Arduino - Computer connected via the USB serial
When uploading the new code to my board, some parts of it were displayed on the monitoring tool on the phone. It happened one or twice and I can't reproduce it now.
I'm pretty sure I've done something wrong somewhere (it seems at least it's the most logical explanation) but I'm also wondering if it could not be a problem with the Bluetooth model (I mean, even the sample tutorials do not work).
- is there something I missed/forgot to do that could help me solve the problem ?
- if not: is there a simple way to check that my Bluetooth modem works fine ?
I am trying to send data via bluetooth but Serial.available() always return 0
I have created an android app that (theoretically) sends data to the arduino via bluetooth. I know that I have managed to get connectivity(the led on the bluetooth module stopped blinking) but the Serial.available() isn't changing when I write some values. I have tried using different apps (from the play store) - no luck. The arduino code which suppose to read the data:
void setup() < Serial.begin(9600); Serial.println("Simple Motor Shield sketch"); >void loop() < if(Serial.available()>0) < Serial.println("in"); for(int i=0;i<=2;i++)< joystick[i] = Serial.read(); >for(int i=0;i <=2;i++)< Serial.println(joystick[i]); >delay(1); > >
bluetoothIn = new Handler() < public void handleMessage(android.os.Message msg) < if (msg.what == handlerState) < //if message is what we want String readMessage = (String) msg.obj; // msg.arg1 = bytes from connect thread recDataString.append(readMessage); //keep appending to string until ~ int endOfLineIndex = recDataString.indexOf("~"); // determine the end-of-line if (endOfLineIndex >0) < // make sure there data before ~ String dataInPrint = recDataString.substring(0, endOfLineIndex); // extract string int dataLength = dataInPrint.length(); //get length of data received recDataString.delete(0, recDataString.length()); //clear all string data >> > >; btAdapter = BluetoothAdapter.getDefaultAdapter(); // get Bluetooth adapter checkBTState(); // Set up onClick listeners for buttons to send 1 or 0 to turn on/off LED btnLeft.setOnClickListener(new View.OnClickListener() < public void onClick(View v) < mConnectedThread.write("0"); // Send "0" via Bluetooth Toast.makeText(getBaseContext(), "Turn off LED", Toast.LENGTH_SHORT).show(); >>); btnRight.setOnClickListener(new View.OnClickListener() < public void onClick(View v) < mConnectedThread.write("1"); // Send "1" via Bluetooth Toast.makeText(getBaseContext(), "Turn on LED", Toast.LENGTH_SHORT).show(); >>); layout_joystick.setOnTouchListener(new View.OnTouchListener() < public boolean onTouch(View arg0, MotionEvent arg1) < js.drawStick(arg1); if (arg1.getAction() == MotionEvent.ACTION_DOWN || arg1.getAction() == MotionEvent.ACTION_MOVE) < //int x = js.getX(); //int y = js.getY(); int angle = (int)js.getAngle(); int distance = (int)js.getDistance(); int maxDist = js.getOffset()+js.getLayoutHeight(); distance =(int)(distance/(maxDist/9)); angle=(int)(angle/40); distance=Math.max(distance,-9); distance=Math.min(distance,9); angle=Math.max(angle,-9); angle=Math.min(angle,9); //mConnectedThread.write(String.valueOf(x)); //mConnectedThread.write(String.valueOf(y)); mConnectedThread.write(String.valueOf(angle)); mConnectedThread.write(String.valueOf(distance)); Log.i("Bluetooth","Distance: " + distance); Log.i("Bluetooth","Angle: " + angle); >return true; > >); > private BluetoothSocket createBluetoothSocket(BluetoothDevice device) throws IOException < return device.createRfcommSocketToServiceRecord(BTMODULEUUID); //creates secure outgoing connecetion with BT device using UUID >@Override public void onResume() < super.onResume(); //Get MAC address from DeviceListActivity via intent Intent intent = getIntent(); //Get the MAC address from the DeviceListActivty via EXTRA address = intent.getStringExtra(DeviceListActivity.EXTRA_DEVICE_ADDRESS); //create device and set the MAC address BluetoothDevice device = btAdapter.getRemoteDevice(address); try < btSocket = createBluetoothSocket(device); >catch (IOException e) < Toast.makeText(getBaseContext(), "Socket creation failed", Toast.LENGTH_LONG).show(); >// Establish the Bluetooth socket connection. try < btSocket.connect(); >catch (IOException e) < try < btSocket.close(); >catch (IOException e2) < //insert code to deal with this >> mConnectedThread = new ConnectedThread(btSocket); mConnectedThread.start(); //I send a character when resuming.beginning transmission to check device is connected //If it is not an exception will be thrown in the write method and finish() will be called mConnectedThread.write("0"); > @Override public void onPause() < super.onPause(); try < //Don't leave Bluetooth sockets open when leaving activity btSocket.close(); >catch (IOException e2) < //insert code to deal with this >> //Checks that the Android device Bluetooth is available and prompts to be turned on if off private void checkBTState() < if(btAdapter==null) < Toast.makeText(getBaseContext(), "Device does not support bluetooth", Toast.LENGTH_LONG).show(); >else < if (btAdapter.isEnabled()) < >else < Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); startActivityForResult(enableBtIntent, 1); >> > //create new class for connect thread private class ConnectedThread extends Thread < private final InputStream mmInStream; private final OutputStream mmOutStream; //creation of the connect thread public ConnectedThread(BluetoothSocket socket) < InputStream tmpIn = null; OutputStream tmpOut = null; try < //Create I/O streams for connection tmpIn = socket.getInputStream(); tmpOut = socket.getOutputStream(); >catch (IOException e) < >mmInStream = tmpIn; mmOutStream = tmpOut; > public void run() < byte[] buffer = new byte[256]; int bytes; // Keep looping to listen for received messages while (true) < try < bytes = mmInStream.read(buffer); //read bytes from input buffer String readMessage = new String(buffer, 0, bytes); // Send the obtained bytes to the UI Activity via handler bluetoothIn.obtainMessage(handlerState, bytes, -1, readMessage).sendToTarget(); >catch (IOException e) < break; >> > //write method public void write(String input) < byte[] msgBuffer = input.getBytes(); //converts entered String into bytes try < mmOutStream.write(msgBuffer); //write bytes over BT connection via outstream >catch (IOException e) < //if you cannot write, close the application Toast.makeText(getBaseContext(), "Connection Failure", Toast.LENGTH_LONG).show(); finish(); >> >