ESP之经典蓝牙库BluetoothSerial介绍和实例演示
1.概述
目前ESP32内置了双模蓝牙(蓝牙4.0版本之前都是经典蓝牙,4.0版本成为BLT低功耗蓝牙转为物联网开发。双模指的就是这款芯片两种模式都支持)。
这篇文章介绍ESP32蓝牙的经典模式使用方法,那么就有疑问了,既然有新版本的蓝牙为什么还要介绍旧版本的蓝牙使用那,这就和使用场景有关了,经典蓝牙库简单,BLT库复杂。如果只是实现首发数据那么经典蓝牙更合适。如果对功耗有要求那么可以使用BLT库开发。
2.蓝牙库介绍
经典蓝牙模式开发使用BluetoothSerial
库,这个库在Arduino中已经存在,不需要单独下载,下面就来介绍下这个库常用的函数,以及如何使用这些库开发程序。
2.1.主从机模式介绍
不同的蓝牙设备之间的连接他们都有一个身份,这个身份就是主机还是从机。
下面介绍下两个身份的区别:
主机身份:
主机身份可疑主动搜索从机的蓝牙地址,并且和他们建立连接。一个主机可以同时连接多个从机。
从机身份
从机模式不能搜索其他设备的蓝牙不能主动建立连接,只能被搜索。从设备和主机建立连接后可以和主设备收发数据,从设备可以允许多个主设备配对,但只能允许一台主机连接。
2.2.常用库介绍
1.获取自身蓝牙地址
每个设备的蓝牙都有一个唯一的mac地址,它由6个字节组成。使用esp_bt_dev_get_address()
函数可以获取本机的蓝牙mac地址。
获取本机蓝牙mac地址示例
#include "esp_bt_main.h"
#include "esp_bt_device.h"
#include "esp32-hal.h"
#include "BluetoothSerial.h"void setup() {//设置蓝牙波特率Serial.begin(115200);//开启蓝牙btStart();//初始化蓝牙协议esp_bluedroid_init();//开启蓝牙协议esp_bluedroid_enable();
}void loop() {//获取本机蓝牙地址auto address = esp_bt_dev_get_address();if(address){for(int i=0; i<6; i++){// 格式化输出蓝牙6个字节内容Serial.printf("%02X", address[i]);if(i<5){Serial.print(":");}}Serial.println();delay(1000);}
}
在Arduino上查看查看蓝牙地址信息时候,需要将波特率调整为115200
2.建立连接和收发信息函数
函数名称 | 解释 |
---|---|
BluetoothSerial(void) | 构造函数 |
bool begin(String localName=String(), bool isMaster=false) | 初始化蓝牙,从机初始化完后就可以接受主机的连接了;localName:蓝牙的名称,如果为空的话,默认为ESP32;isMater:是否是主机,默认是从机,从机可以被主机连接 |
bool hasClient(void) | 是否有设备已经连接 |
bool disconnect() | 关闭当前的spp连接 |
bool isclosed() | spp连接是否已经关闭 |
bool isReady(bool checkMaster=false, int timeout=0); voidend(void) | /spp信道是否可用,如果checkMaster为true还会同时检测本机是否是主机,不是的话也会返回false |
voidend(void) | 关闭蓝牙功能 |
bool unpairDevice(uint8 t remoteAddress[]) | 解除指定地址的蓝牙设备的配对 |
3.收发数据函数
函数名称 | 解释 |
---|---|
int available(void) | 有多少数据可以读 |
void setTimeout(int timeoutMS) | 设置读写的超时时间,默认是0,马上返回 |
int peek(void) | 读缓冲区第一字节,如果读取错误,返回—1 |
int read(void) | 读取一个字节,如果读取错误,返回—1 |
size t write(uint8 t c) | 发送一个字节 |
size_t write(const uint8_t *buffer, size t size) | 最多发送size字节,返回成功发送的字节 数 |
size_t print() | |
size_t printf() | |
size_t println() | 三个print系列的函数都是返回实际发送的字节 |
void flush() | 将数据从缓冲区强制送入信道 |
size t readBytes(char *buffer, size_t length) | 字节方式读取数据 |
size t readBytesUntil(char terminator, char *buffer, size t length) | 字节方式读取数据 |
String readstring() | 字符串方式读取数据 |
String readStringUntil(char terminator) | 字符串方式读取数据 |
3.ESP32作为从机示例
3.1.最简单的从机发送和接收数据例子
这个例子将ESP32设置为从机,程序中没有使用SPP协议,他不需要密码验证就可以配对连接。
#include "BluetoothSerial.h"BluetoothSerial SerialBT; //定义一个蓝牙对象void setup() {Serial.begin(115200);SerialBT.begin("ESP32Fish"); //蓝牙的名字叫ESP32Fish, 从机模式Serial.println("The device started, now you can pair it with bluetooth!");
}void loop() {char buf[129];//判断是否接收到数据if(SerialBT.available()){auto sz = SerialBT.readBytes(buf, 128); //从蓝牙接收数据if(sz){buf[sz] = 0;Serial.println(buf);strcat(buf, " - Slave");SerialBT.write((uint8_t*)buf, strlen(buf)); //从蓝牙发送数据}}delay(20);
}
1.将程序复制到ArduinoIDE,然后将程序上传到ESP32.
2.这个时候需要拿出手机,开发蓝牙设置搜索名称为ESP32Fish
蓝牙设备,然后配对。
3.配对成功后,在windows电脑上通过浏览器搜索Bluetooth Serial Tool
蓝牙调试工具并安装。
4.打开Bluetooth Serial Tool
工具:
- 点击
Refresh
刷新 - 然后选择蓝牙名称
- 点击Connect连接
- 输入内容
- 点击发送
查看ArduinoIDE窗口接收到了消息
3.2.SPP开启SSP验证最简单例子
开启SSP验证在配对的时候就需要输入验证码才能连接。
下面是开启SSP的函数
//启用SSP认证,配对的时候会主机会产生一个密码发送给从机,我们从机手动确认,主机侧也得确认
void enableSSP();
//设置配对认证请求回调函数
void onConfirmRequest(ConfirmRequestCb cb);
//设置配对认证结果回调函数
void onAuthComplete(AuthCompleteCb cb);
//是否同意连接,true:同意 false:不同意
void confirmReply(boolean confirm);typedef std: function<void(uint32_t num val)> ConfirmRequestCb;typedef std: function<void(boolean success)> AuthCompleteCb;
关于配对的一些提示:
如果你两台设备配对过了,你的从机改了认证方式,改了蓝牙名,实测两台设备之前还是处于配对状态。
开启SSP验证示例代码
#include "BluetoothSerial.h"BluetoothSerial SerialBT; //定义一个蓝牙对象//认证请求回调
void BTConfirmRequestCallback(uint32_t numVal)
{//numVal是主机发来的识别码Serial.printf("recv pin: %d \r\n", numVal);//这里要对这个识别码进行判断,是否和主机一样或是是否是我们从机内置的密码//然后再判断是否确定连接,我们这里直接确认了SerialBT.confirmReply(true);//SerialBT.confirmReply(false); //如果要拒绝就用这句
}//认证结果回调函数
void BTAuthCompleteCallback(boolean success)
{if (success)Serial.println("Pairing success!!");elseSerial.println("Pairing failed, rejected by user!!");
}void RecvData(const uint8_t *buffer, size_t size)
{if(size > 0){Serial.write(buffer, size); //打印出来SerialBT.write(buffer, size);SerialBT.println(" - Slave");}
}void setup() {SerialBT.enableSSP(); //在begin之前调用SerialBT.onConfirmRequest(BTConfirmRequestCallback);SerialBT.onAuthComplete(BTAuthCompleteCallback);Serial.begin(115200);SerialBT.onData(RecvData); //注册接收回调函数SerialBT.begin("ESP32Fish"); //蓝牙的名字叫ESP32Fish, 从机模式Serial.println("The device started, now you can pair it with bluetooth!");
}void loop() {
}
上传程序后,删除之前的配对信息,然后重新配对,就会提示输入code码。