esp32自带蓝牙模块可以让我们进行蓝牙连接并进行数据交换
首先来编写代码,经典蓝牙的使用非常简单,首先声明使用了BluetoothSerial这个库,然后使用SerialBT.begin函数设置蓝牙的名字,再然后就是设置配对码,由于这里没有用到配对码,所以我将注释掉。当配对成功我们就使用printf函数打印出蓝牙配对成功。
#include
#include
BluetoothSerial SerialBT;
void setup()
{
Serial.begin(115200);
SerialBT.begin("BAKUMAN"); // 如果没有参数传入则默认是蓝牙名称是: "ESP32"
// SerialBT.setPin("1234"); // 蓝牙连接的配对码
Serial.printf("BT initial ok and ready to pair. \r\n");
}
void loop()
{
if (Serial.available())
{
SerialBT.write(Serial.read());
}
if (SerialBT.available())
{
Serial.write(SerialBT.read());
}
delay(1);
}
再然后就是loop函数中:
Serial.available()是串口中(演示中为电脑端)收到的信息,如果串口中有数据,就使用蓝牙发送出去。
SerialBT.available()是蓝牙中(演示中为手机端)收到的信息,如果蓝牙中有数据,就发送给串口,串口就会打印出来。
接下来就是演示的截图:
串口发送信息:
蓝牙发送数据:
UUID:ble的服务和characteristic是通过UUID来进行识别的。创建uuid可以使用这么一个网站:Online UUID Generator Tool
notify:如果这个主机的一个特征值characteristic发生改变,就可以通过notify来告诉我们
pCharacteristic = pService->createCharacteristic(CHARACTERISTIC_UUID_TX, BLECharacteristic::PROPERTY_NOTIFY);
//创建一个(读)特征值, 它是通知下发类型的特征值
write:我们可以把特征值定为写入类型, 这样客户端可以给我们写入, 触发写入回调函数
BLECharacteristic *pCharacteristic = pService->createCharacteristic(CHARACTERISTIC_UUID_RX, BLECharacteristic::PROPERTY_WRITE);
//创建一个(写)特征, 它是写入类型的特征值
pCharacteristic->setCallbacks(new MyCallbacks());
//为特征添加一个回调
使用这个低功耗蓝牙有这么几个步骤:
\1. 创建一个 BLE Server
\2. 创建一个 BLE Service
\3. 创建一个 BLE Characteristic
\4. 创建一个 BLE Descriptor
\5. 开始服务
\6. 开始广播
并且我们还需要使用BLEDevice,BLEServer,BLEUtils,BLE2902,common这几个库
/*
Video: https://www.youtube.com/watch?v=oCMOYS71NIU
Based on Neil Kolban example for IDF: https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/tests/BLE%20Tests/SampleNotify.cpp
Ported to Arduino ESP32 by Evandro Copercini
Create a BLE server that, once we receive a connection, will send periodic notifications.
创建一个BLE服务器,一旦我们收到连接,将会周期性发送通知
T使用步骤:
1. 创建一个 BLE Server
2. 创建一个 BLE Service
3. 创建一个 BLE Characteristic
4. 创建一个 BLE Descriptor
5. 开始服务
6. 开始广播
*/
#include
#include
#include
#include
#include
#include "common.h"
uint8_t txValue = 0; //后面需要发送的值
BLEServer *pServer = NULL; //BLEServer指针 pServer
BLECharacteristic *pTxCharacteristic = NULL; //BLECharacteristic指针 pTxCharacteristic
bool deviceConnected = false; //本次连接状态
bool oldDeviceConnected = false; //上次连接状态
// See the following for generating UUIDs: https://www.uuidgenerator.net/
#define SERVICE_UUID "12a59900-17cc-11ec-9621-0242ac130002" // UART service UUID
#define CHARACTERISTIC_UUID_RX "12a59e0a-17cc-11ec-9621-0242ac130002"
#define CHARACTERISTIC_UUID_TX "12a5a148-17cc-11ec-9621-0242ac130002"//注意这里面是用
class MyServerCallbacks : public BLEServerCallbacks
{
void onConnect(BLEServer *pServer)
{
deviceConnected = true;
};
void onDisconnect(BLEServer *pServer)
{
deviceConnected = false;
}
};
class MyCallbacks : public BLECharacteristicCallbacks
{
void onWrite(BLECharacteristic *pCharacteristic)
{
std::string rxValue = pCharacteristic->getValue(); //接收信息
if (rxValue.length() > 0)
{ //向串口输出收到的值
Serial.print("RX: ");
for (int i = 0; i < rxValue.length(); i++)
Serial.print(rxValue[i]);
Serial.println();
}
}
};
BLEDevice::init(ble_name);
pServer = BLEDevice::createServer();
pServer->setCallbacks(new MyServerCallbacks()); //设置回调
BLEService *pService = pServer->createService(SERVICE_UUID);
在这里面的回调函数就是上面代码串中的MyServerCallbacks
pTxCharacteristic = pService->createCharacteristic(CHARACTERISTIC_UUID_TX, BLECharacteristic::PROPERTY_NOTIFY);
pTxCharacteristic->addDescriptor(new BLE2902());
BLECharacteristic *pRxCharacteristic = pService->createCharacteristic(CHARACTERISTIC_UUID_RX, BLECharacteristic::PROPERTY_WRITE);
pRxCharacteristic->setCallbacks(new MyCallbacks()); //设置回调
这里创建了一个特征值,类型是通知。
在后面使用createCharacteristic(CHARACTERISTIC_UUID_RX, BLECharacteristic::PROPERTY_WRITE)将rx收集到的信息写入,通过MyCallbacks再打印出来
为了实现"串口",我们在这个服务下添加了两个特征值, 一个是TX. 一个是RX.另外还需注意三个uuid因该是相对应的值。
pService->start(); // 开始服务
pServer->getAdvertising()->start(); // 开始广播
Serial.println(" 等待一个客户端连接,且发送通知... ");
(1)设备已经连接:
if (deviceConnected){
pTxCharacteristic->setValue(&txValue, 1); // 设置要发送的值为1
pTxCharacteristic->notify(); // 广播
txValue++; // 指针数值自加1
delay(2000); // 如果有太多包要发送,蓝牙会堵塞
}
这里面测试的是不停发送数据,每发一次数值加一。
此时
class MyServerCallbacks : public BLEServerCallbacks
{
void onConnect(BLEServer *pServer)
{
deviceConnected = true;
};
void onDisconnect(BLEServer *pServer)
{
deviceConnected = false;
}
};
通过这个回调可以说清楚这个蓝牙到底有没有连接,如果连接了通过
pServer->setCallbacks(new MyServerCallbacks());
这个MyServerCallbacks回调就可以返回连接状态。
调式结果如图:
ble串口:
ble开始广播
最后附上整段代码:
/*
Video: https://www.youtube.com/watch?v=oCMOYS71NIU
Based on Neil Kolban example for IDF: https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/tests/BLE%20Tests/SampleNotify.cpp
Ported to Arduino ESP32 by Evandro Copercini
Create a BLE server that, once we receive a connection, will send periodic notifications.
创建一个BLE服务器,一旦我们收到连接,将会周期性发送通知
T使用步骤:
1. 创建一个 BLE Server
2. 创建一个 BLE Service
3. 创建一个 BLE Characteristic
4. 创建一个 BLE Descriptor
5. 开始服务
6. 开始广播
*/
#include
#include
#include
#include
#include
#include "common.h"
uint8_t txValue = 0; //后面需要发送的值
BLEServer *pServer = NULL; //BLEServer指针 pServer
BLECharacteristic *pTxCharacteristic = NULL; //BLECharacteristic指针 pTxCharacteristic
bool deviceConnected = false; //本次连接状态
bool oldDeviceConnected = false; //上次连接状态d
// See the following for generating UUIDs: https://www.uuidgenerator.net/
#define SERVICE_UUID "12a59900-17cc-11ec-9621-0242ac130002" // UART service UUID
#define CHARACTERISTIC_UUID_RX "12a59e0a-17cc-11ec-9621-0242ac130002"
#define CHARACTERISTIC_UUID_TX "12a5a148-17cc-11ec-9621-0242ac130002"
class MyServerCallbacks : public BLEServerCallbacks
{
void onConnect(BLEServer *pServer)
{
deviceConnected = true;
};
void onDisconnect(BLEServer *pServer)
{
deviceConnected = false;
}
};
class MyCallbacks : public BLECharacteristicCallbacks
{
void onWrite(BLECharacteristic *pCharacteristic)
{
std::string rxValue = pCharacteristic->getValue(); //接收信息
if (rxValue.length() > 0)
{ //向串口输出收到的值
Serial.print("RX: ");
for (int i = 0; i < rxValue.length(); i++)
Serial.print(rxValue[i]);
Serial.println();
}
}
};
void setup()
{
Serial.begin(115200);
// 创建一个 BLE 设备
BLEDevice::init("BAKUMAN");//在这里面是ble的名称
// 创建一个 BLE 服务
pServer = BLEDevice::createServer();
pServer->setCallbacks(new MyServerCallbacks()); //设置回调
BLEService *pService = pServer->createService(SERVICE_UUID);
// 创建一个 BLE 特征
pTxCharacteristic = pService->createCharacteristic(CHARACTERISTIC_UUID_TX, BLECharacteristic::PROPERTY_NOTIFY);
pTxCharacteristic->addDescriptor(new BLE2902());
BLECharacteristic *pRxCharacteristic = pService->createCharacteristic(CHARACTERISTIC_UUID_RX, BLECharacteristic::PROPERTY_WRITE);
pRxCharacteristic->setCallbacks(new MyCallbacks()); //设置回调
pService->start(); // 开始服务
pServer->getAdvertising()->start(); // 开始广播
Serial.println(" 等待一个客户端连接,且发送通知... ");
}
void loop()
{
// deviceConnected 已连接
if (deviceConnected)
{
pTxCharacteristic->setValue(&txValue, 1); // 设置要发送的值为1
pTxCharacteristic->notify(); // 广播
txValue++; // 指针数值自加1
delay(2000); // 如果有太多包要发送,蓝牙会堵塞
}
// disconnecting 断开连接
if (!deviceConnected && oldDeviceConnected)
{
delay(500); // 留时间给蓝牙缓冲
pServer->startAdvertising(); // 重新广播
Serial.println(" 开始广播 ");
oldDeviceConnected = deviceConnected;
}
// connecting 正在连接
if (deviceConnected && !oldDeviceConnected)
{
// do stuff here on connecting
oldDeviceConnected = deviceConnected;
}
}