Skip to content

Add BluetoothSerial library #1144

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Mar 5, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions libraries/BluetoothSerial/README.md
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
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);
}
26 changes: 26 additions & 0 deletions libraries/BluetoothSerial/keywords.txt
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)
#######################################
9 changes: 9 additions & 0 deletions libraries/BluetoothSerial/library.properties
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
239 changes: 239 additions & 0 deletions libraries/BluetoothSerial/src/BluetoothSerial.cpp
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
56 changes: 56 additions & 0 deletions libraries/BluetoothSerial/src/BluetoothSerial.h
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 modified tools/sdk/lib/libbt.a
Binary file not shown.