diff --git a/libraries/BluetoothSerial/README.md b/libraries/BluetoothSerial/README.md new file mode 100644 index 00000000000..9d25dbca0a9 --- /dev/null +++ b/libraries/BluetoothSerial/README.md @@ -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
+For Android: https://play.google.com/store/apps/details?id=de.kai_morich.serial_bluetooth_terminal
+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 diff --git a/libraries/BluetoothSerial/examples/SerialToSerialBT/SerialToSerialBT.ino b/libraries/BluetoothSerial/examples/SerialToSerialBT/SerialToSerialBT.ino new file mode 100644 index 00000000000..9a5fa0877bc --- /dev/null +++ b/libraries/BluetoothSerial/examples/SerialToSerialBT/SerialToSerialBT.ino @@ -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); +} \ No newline at end of file diff --git a/libraries/BluetoothSerial/keywords.txt b/libraries/BluetoothSerial/keywords.txt new file mode 100644 index 00000000000..25c4c7e5a33 --- /dev/null +++ b/libraries/BluetoothSerial/keywords.txt @@ -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) +####################################### diff --git a/libraries/BluetoothSerial/library.properties b/libraries/BluetoothSerial/library.properties new file mode 100644 index 00000000000..20adb66c796 --- /dev/null +++ b/libraries/BluetoothSerial/library.properties @@ -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 diff --git a/libraries/BluetoothSerial/src/BluetoothSerial.cpp b/libraries/BluetoothSerial/src/BluetoothSerial.cpp new file mode 100644 index 00000000000..eff913fee98 --- /dev/null +++ b/libraries/BluetoothSerial/src/BluetoothSerial.cpp @@ -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 diff --git a/libraries/BluetoothSerial/src/BluetoothSerial.h b/libraries/BluetoothSerial/src/BluetoothSerial.h new file mode 100644 index 00000000000..12281ed7123 --- /dev/null +++ b/libraries/BluetoothSerial/src/BluetoothSerial.h @@ -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 +#include +#include +#include +#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 diff --git a/tools/sdk/lib/libbt.a b/tools/sdk/lib/libbt.a index 20c4efca108..47aa93398a9 100644 Binary files a/tools/sdk/lib/libbt.a and b/tools/sdk/lib/libbt.a differ