-
Notifications
You must be signed in to change notification settings - Fork 7.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Add BluetoothSerial library A simple UART to Classical Bluetooth bridge for ESP32 * Create README.md * Fix typos * Replace deprecated header and small fixes * Add coexistence with BLE * Add missing semicolon
- Loading branch information
Showing
7 changed files
with
378 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
### Bluetooth Serial Library | ||
|
||
A simple Serial compatible library using ESP32 classical bluetooth (SPP) | ||
|
||
|
||
|
||
#### How to use it? | ||
|
||
- Download one bluetooth terminal app in your smartphone<br> | ||
For Android: https://play.google.com/store/apps/details?id=de.kai_morich.serial_bluetooth_terminal <br> | ||
For iOS: https://itunes.apple.com/us/app/hm10-bluetooth-serial-lite/id1030454675 | ||
|
||
- Flash an example sketch to your ESP32 | ||
|
||
- Scan and pair the device in your smartphone | ||
|
||
- Open the bluetooth terminal app | ||
|
||
- Enjoy |
29 changes: 29 additions & 0 deletions
29
libraries/BluetoothSerial/examples/SerialToSerialBT/SerialToSerialBT.ino
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
//This example code is in the Public Domain (or CC0 licensed, at your option.) | ||
//By Evandro Copercini - 2018 | ||
// | ||
//This example creates a bridge between Serial and Classical Bluetooth (SPP) | ||
//and also demonstrate that SerialBT have the same functionalities of a normal Serial | ||
|
||
#include "BluetoothSerial.h" | ||
|
||
#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; | ||
|
||
void setup() { | ||
Serial.begin(115200); | ||
SerialBT.begin("ESP32test"); //Bluetooth device name | ||
Serial.println("The device started, now you can pair it with bluetooth!"); | ||
} | ||
|
||
void loop() { | ||
if (Serial.available()) { | ||
SerialBT.write(Serial.read()); | ||
} | ||
if (SerialBT.available()) { | ||
Serial.write(SerialBT.read()); | ||
} | ||
delay(20); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
####################################### | ||
# Syntax Coloring Map For BluetoothSerial | ||
####################################### | ||
|
||
####################################### | ||
# Library (KEYWORD3) | ||
####################################### | ||
|
||
BluetoothSerial KEYWORD3 | ||
|
||
####################################### | ||
# Datatypes (KEYWORD1) | ||
####################################### | ||
|
||
BluetoothSerial KEYWORD1 | ||
|
||
####################################### | ||
# Methods and Functions (KEYWORD2) | ||
####################################### | ||
|
||
SerialBT KEYWORD2 | ||
|
||
|
||
####################################### | ||
# Constants (LITERAL1) | ||
####################################### |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
name=BluetoothSerial | ||
version=1.0 | ||
author=Evandro Copercini | ||
maintainer=Evandro Copercini | ||
sentence=Simple UART to Classical Bluetooth bridge for ESP32 | ||
paragraph= | ||
category=Communication | ||
url= | ||
architectures=esp32 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,239 @@ | ||
// Copyright 2018 Evandro Luis Copercini | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
#include "sdkconfig.h" | ||
|
||
#if defined(CONFIG_BT_ENABLED) && defined(CONFIG_BLUEDROID_ENABLED) | ||
|
||
#ifdef ARDUINO_ARCH_ESP32 | ||
#include "esp32-hal-log.h" | ||
#endif | ||
|
||
#include "BluetoothSerial.h" | ||
|
||
#include "esp_bt.h" | ||
#include "esp_bt_main.h" | ||
#include "esp_gap_bt_api.h" | ||
#include "esp_bt_device.h" | ||
#include "esp_spp_api.h" | ||
|
||
#define SPP_SERVER_NAME "ESP32_SPP_SERVER" | ||
|
||
#define QUEUE_SIZE 256 | ||
uint32_t client; | ||
xQueueHandle SerialQueueBT; | ||
|
||
static const esp_spp_mode_t esp_spp_mode = ESP_SPP_MODE_CB; | ||
static const esp_spp_sec_t sec_mask = ESP_SPP_SEC_NONE; | ||
static const esp_spp_role_t role_slave = ESP_SPP_ROLE_SLAVE; | ||
|
||
static void esp_spp_cb(esp_spp_cb_event_t event, esp_spp_cb_param_t *param) | ||
{ | ||
switch (event) | ||
{ | ||
case ESP_SPP_INIT_EVT: | ||
ESP_LOGI(SPP_TAG, "ESP_SPP_INIT_EVT"); | ||
esp_bt_gap_set_scan_mode(ESP_BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE); | ||
esp_spp_start_srv(sec_mask, role_slave, 0, SPP_SERVER_NAME); | ||
break; | ||
case ESP_SPP_DISCOVERY_COMP_EVT: | ||
ESP_LOGI(SPP_TAG, "ESP_SPP_DISCOVERY_COMP_EVT"); | ||
break; | ||
case ESP_SPP_OPEN_EVT: | ||
ESP_LOGI(SPP_TAG, "ESP_SPP_OPEN_EVT"); | ||
break; | ||
case ESP_SPP_CLOSE_EVT: | ||
client = 0; | ||
ESP_LOGI(SPP_TAG, "ESP_SPP_CLOSE_EVT"); | ||
break; | ||
case ESP_SPP_START_EVT: | ||
ESP_LOGI(SPP_TAG, "ESP_SPP_START_EVT"); | ||
break; | ||
case ESP_SPP_CL_INIT_EVT: | ||
ESP_LOGI(SPP_TAG, "ESP_SPP_CL_INIT_EVT"); | ||
break; | ||
case ESP_SPP_DATA_IND_EVT: | ||
ESP_LOGV(SPP_TAG, "ESP_SPP_DATA_IND_EVT len=%d handle=%d", param->data_ind.len, param->data_ind.handle); | ||
//esp_log_buffer_hex("",param->data_ind.data,param->data_ind.len); //for low level debug | ||
|
||
if (SerialQueueBT != 0){ | ||
for (int i = 0; i < param->data_ind.len; i++) | ||
xQueueSend(SerialQueueBT, param->data_ind.data + i, (TickType_t)0); | ||
} | ||
else { | ||
ESP_LOGE(SPP_TAG, "SerialQueueBT ERROR"); | ||
} | ||
break; | ||
case ESP_SPP_CONG_EVT: | ||
ESP_LOGI(SPP_TAG, "ESP_SPP_CONG_EVT"); | ||
break; | ||
case ESP_SPP_WRITE_EVT: | ||
ESP_LOGV(SPP_TAG, "ESP_SPP_WRITE_EVT"); | ||
break; | ||
case ESP_SPP_SRV_OPEN_EVT: | ||
client = param->open.handle; | ||
ESP_LOGI(SPP_TAG, "ESP_SPP_SRV_OPEN_EVT"); | ||
break; | ||
default: | ||
break; | ||
} | ||
} | ||
|
||
static bool _init_bt(const char *deviceName) | ||
{ | ||
if (!btStarted() && !btStart()){ | ||
ESP_LOGE(SPP_TAG, "%s initialize controller failed\n", __func__); | ||
return false; | ||
} | ||
|
||
esp_bluedroid_status_t bt_state = esp_bluedroid_get_status(); | ||
if (bt_state == ESP_BLUEDROID_STATUS_UNINITIALIZED){ | ||
if (esp_bluedroid_init()) { | ||
ESP_LOGE(SPP_TAG, "%s initialize bluedroid failed\n", __func__); | ||
return false; | ||
} | ||
} | ||
|
||
if (bt_state != ESP_BLUEDROID_STATUS_ENABLED){ | ||
if (esp_bluedroid_enable()) { | ||
ESP_LOGE(SPP_TAG, "%s enable bluedroid failed\n", __func__); | ||
return false; | ||
} | ||
} | ||
|
||
if (esp_spp_register_callback(esp_spp_cb) != ESP_OK){ | ||
ESP_LOGE(SPP_TAG, "%s spp register failed\n", __func__); | ||
return false; | ||
} | ||
|
||
if (esp_spp_init(esp_spp_mode) != ESP_OK){ | ||
ESP_LOGE(SPP_TAG, "%s spp init failed\n", __func__); | ||
return false; | ||
} | ||
|
||
SerialQueueBT = xQueueCreate(QUEUE_SIZE, sizeof(uint8_t)); //initialize the queue | ||
if (SerialQueueBT == NULL){ | ||
ESP_LOGE(SPP_TAG, "%s Queue creation error\n", __func__); | ||
return false; | ||
} | ||
esp_bt_dev_set_device_name(deviceName); | ||
|
||
return true; | ||
} | ||
|
||
static bool _stop_bt() | ||
{ | ||
if (btStarted()){ | ||
esp_bluedroid_disable(); | ||
esp_bluedroid_deinit(); | ||
btStop(); | ||
} | ||
return true; | ||
} | ||
|
||
/* | ||
* Serial Bluetooth Arduino | ||
* | ||
* */ | ||
|
||
BluetoothSerial::BluetoothSerial() | ||
{ | ||
local_name = "ESP32"; //default bluetooth name | ||
} | ||
|
||
BluetoothSerial::~BluetoothSerial(void) | ||
{ | ||
_stop_bt(); | ||
} | ||
|
||
bool BluetoothSerial::begin(String localName) | ||
{ | ||
if (localName.length()){ | ||
local_name = localName; | ||
} | ||
return _init_bt(local_name.c_str()); | ||
} | ||
|
||
int BluetoothSerial::available(void) | ||
{ | ||
if (!client || SerialQueueBT == NULL){ | ||
return 0; | ||
} | ||
return uxQueueMessagesWaiting(SerialQueueBT); | ||
} | ||
|
||
int BluetoothSerial::peek(void) | ||
{ | ||
if (available()){ | ||
if (!client || SerialQueueBT == NULL){ | ||
return 0; | ||
} | ||
|
||
uint8_t c; | ||
if (xQueuePeek(SerialQueueBT, &c, 0)){ | ||
return c; | ||
} | ||
} | ||
return -1; | ||
} | ||
|
||
int BluetoothSerial::read(void) | ||
{ | ||
if (available()){ | ||
if (!client || SerialQueueBT == NULL){ | ||
return 0; | ||
} | ||
|
||
uint8_t c; | ||
if (xQueueReceive(SerialQueueBT, &c, 0)){ | ||
return c; | ||
} | ||
return 0; | ||
} | ||
} | ||
|
||
size_t BluetoothSerial::write(uint8_t c) | ||
{ | ||
if (client){ | ||
uint8_t buffer[1]; | ||
buffer[0] = c; | ||
esp_spp_write(client, 1, buffer); | ||
return 1; | ||
} | ||
return -1; | ||
} | ||
|
||
size_t BluetoothSerial::write(const uint8_t *buffer, size_t size) | ||
{ | ||
if (client){ | ||
esp_spp_write(client, size, (uint8_t *)buffer); | ||
} | ||
return size; | ||
} | ||
|
||
void BluetoothSerial::flush() | ||
{ | ||
if (client){ | ||
int qsize = available(); | ||
uint8_t buffer[qsize]; | ||
esp_spp_write(client, qsize, buffer); | ||
} | ||
} | ||
|
||
void BluetoothSerial::end() | ||
{ | ||
_stop_bt(); | ||
} | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
// Copyright 2018 Evandro Luis Copercini | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
|
||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
#ifndef _BLUETOOTH_SERIAL_H_ | ||
#define _BLUETOOTH_SERIAL_H_ | ||
|
||
#include "sdkconfig.h" | ||
|
||
#if defined(CONFIG_BT_ENABLED) && defined(CONFIG_BLUEDROID_ENABLED) | ||
|
||
#include <cstdint> | ||
#include <cstdio> | ||
#include <cstdlib> | ||
#include <cstring> | ||
#include "freertos/FreeRTOS.h" | ||
#include "freertos/task.h" | ||
#include "esp_bt.h" | ||
|
||
#include "Arduino.h" | ||
#include "Stream.h" | ||
|
||
class BluetoothSerial: public Stream | ||
{ | ||
public: | ||
|
||
BluetoothSerial(void); | ||
~BluetoothSerial(void); | ||
|
||
bool begin(String localName=String()); | ||
int available(void); | ||
int peek(void); | ||
int read(void); | ||
size_t write(uint8_t c); | ||
size_t write(const uint8_t *buffer, size_t size); | ||
void flush(); | ||
void end(void); | ||
|
||
private: | ||
String local_name; | ||
|
||
}; | ||
|
||
#endif | ||
|
||
#endif |
Binary file not shown.