文章目录

  • 前言
  • 一、设置可发现BLE设备名
  • 1. 蓝牙广播包浅析
  • 2. 开始广播 && 发现BLE设备名称
  • 二、模组与手机基本通信
  • 2.1 初始化蓝牙server模式
  • 2.2 连接蓝牙
  • 2.3 服务特征通知
  • 2.4 服务特征指示
  • 三、模组与手机进行ble数据透传
  • 3.1 模组BLE初始化与连接
  • 3.2 设置BLE透传参数
  • 3.4 开启透传
  • 四、使用静态秘钥进行蓝牙加密配对


前言

阅读前请准备: (1) 安信可esp32-s模组/开发板、USB转TTL、BLE调试助手(建议用nRF Connet)、串口调试助手

一、设置可发现BLE设备名

1. 蓝牙广播包浅析

我们先来看一下乐鑫的AT手册关于BLE设备名的资料

esp32 python 蓝牙开发 esp32经典蓝牙例子_esp32 python 蓝牙开发


我们从描述中可以知道,如果我们需要在手机扫描时即可获取BLE设备名称,需要通过AT+BLEADVDATA设置广播包。那么广播包需要如何设置呢,我们先来看一下广播包格式

蓝牙广播数据包格式如下:

Length

AD Type

AD Date

广播数据长度

广播数据类型

广播数据内容

每个字段的含义如下:
Length表示有效数据的长度,最大为0x1E(31);
AD Type表示广播数据的类型,此字段非常重要,决定广播包的含义
AD Date 广播数据内容,最多29字节(Length和AD Type个占一个字节)

蓝牙广播数据类型定义:

AD Type

含义

备注

0x01

广播模式

bit 0: LE 有限发现模式。 bit 1: LE 普通发现模式。 bit 2: 不支持 BR/EDR。 bit 3: 对 Same Device Capable(Controller) 同时支持 BLE 和 BR/EDR。 bit 4: 对 Same Device Capable(Host) 同时支持 BLE 和 BR/EDR。 bit 5…7: 预留。

0x02

非完整的 16 bit UUID 列表

0x03

完整的 16 bit UUID 列表

0x04

非完整的 32 bit UUID 列表

0x05

完整的 32 bit UUID 列表

0x06

非完整的 128 bit UUID 列表

0x07

完整的 128 bit UUID 列表

0x08

缩写的设备名称

0x09

完整的设备名称

0x0A

广播包的信号强度

0x0B

0x0C

0x0D

0x0E

0x0F

0x10

0x11

带外安全管理

0x12

(Slave)连接间隔范围

0x13

0x14

16 bit UUID 列表

0x15

128 bit UUID 列表

0x16

16 bit UUID Service

前 2 字节是 UUID,后面是 Service 的数据

0x17

公开目标地址

0x18

随机目标地址

0x19

Appearance(外观)

0x1A

0x1B

0x1C

0x1D

0x1E

0x1F

0x20

32 bit UUID Service

前 4 字节是 UUID,后面是 Service 的数据

0x21

128 bit UUID Service

前 16 字节是 UUID,后面是 Service 的数据

~~~

0x29

PB-ADV

0x2A

Mesh Message

0x2B

Mesh Beacon

~~~

0xFF

厂商自定义数据

2. 开始广播 && 发现BLE设备名称

AT+BLEINIT=2 //BLE初始化,将模块设为server端。

AT+BLENAME="AiThinker" //设置BLENEME名并用转换器获得它的16进制数。

esp32 python 蓝牙开发 esp32经典蓝牙例子_BLE设备名_02


AT+BLEADVDATA="0201060A0941695468696E6B6572" //广播设备名称

对照上文的蓝牙广播数据类型定义的描述,可知

02 01 06 字段设置广播模式为BLE only

0A 09 41695468696E6B6572 字段表示:

0A: 此字段数据长度为10

09 :完整的设备名称

41695468696E6B6572:设备名称AiThinker的十六进制表示

AT+BLEADVSTART //开始广播

esp32 python 蓝牙开发 esp32经典蓝牙例子_数据_03


我们在BLE调试助手扫描发现了名为AiThinker 的设备,设置成功

二、模组与手机基本通信

2.1 初始化蓝牙server模式
AT+BLEINIT=2     //初始化BLE为server
 AT+BLEGATTSSRVCRE    //GATTS 创建服务
 AT+BLEGATTSSRVSTART   //GATTS 开启服务  
 AT+BLEADVDATA="0201060A0941695468696E6B6572"   //广播设备名称为AiThinker
 AT+BLEADVSTART        //开启BLE广播
2.2 连接蓝牙

选择名为AiThinker的设备连接

esp32 python 蓝牙开发 esp32经典蓝牙例子_数据_03


连接后找到支持NOTIFY和INDICATE的特征,点击侦听

esp32 python 蓝牙开发 esp32经典蓝牙例子_安信可ESP32_05


侦听成功后app显示如下

esp32 python 蓝牙开发 esp32经典蓝牙例子_BLE设备名_06


app侦听NOTIFY和INDICATE模组分别会收到

+WRITE:0,1,6,1,2,


+WRITE:0,1,7,1,2,

可以看见后面的字符乱码了,是因为app下发的消息是十六进制的,我们把收到的消息转化为hex可以得到两个字符串后面乱码的数据分别为0x0001和0x0002(小端模式)

esp32 python 蓝牙开发 esp32经典蓝牙例子_esp32 python 蓝牙开发_07

2.3 服务特征通知

发送服务特征通知前需要确保app已侦听,侦听方法2.2章节已提供(即侦听NOTIFY)

AT+BLEGATTSNTFY=0,1,6,8		//使用 1号服务的 6 号特征 notify 长度为8字节的数据
2.4 服务特征指示

发送服务特征通知前需要确保app已侦听,侦听方法2.2章节已提供(即侦听INDICATE)

AT+BLEGATTSIND=0,1,7,10	 	//使用 1 号服务的 7 号特征 indicate 长度为 10 字节的数据

整体演示如下

esp32 python 蓝牙开发 esp32经典蓝牙例子_esp32 python 蓝牙开发_08

三、模组与手机进行ble数据透传

3.1 模组BLE初始化与连接

ble初始化与ble方法见2.1和2.2章节

3.2 设置BLE透传参数

设置指令:AT+BLESPPCFG=<cfg_enable>,<tx_srv_index>,<tx_char_index>,<rx_srv_index>,<rx_srv_index>

功能:配置 BLE 透传模式。分别选择两个 characteristic,⼀个⽤于发送数据,⼀个⽤于接收数据,作为数据通信的收发通道。

这条指令一共要设置5个参数:

<cfg_enable>:

• 0:清除 BLE SPP 设置参数;之后的四个参数⽆需填写。

• 1:设置 BLE SPP 参数;之后的四个参数必须填写。

我们一般设置为1

<tx_srv_index>:发送数据的 characteristic 所在的 service 的序号

<tx_char_index>:发送数据的 characteristic 的序号。 作为 BLE server,要求此 characteristic 服务特征的属性⽀持 notify 或者 indicate

<rx_srv_index>:接收数据的 characteristic 所在的 service 的序号。

<rx_char_index>:接收数据的 characteristic 的序号;

以上参数皆可通过指令AT+BLEGATTSCHAR?查询所得

esp32 python 蓝牙开发 esp32经典蓝牙例子_BLE设备名_09


AT+BLEGATTSCHAR?参数说明:

<srv_index> :服务序号,从 1 起始递增

<char_index> :服务特征的序号,从 1 起始递增

<char_uuid> :服务特征的 UUID

<char_prop> :服务特征的属性

<desc_index> :特征描述符序号

<desc_uuid> :特征描述符的 UUID我们拎出一个来解读一下

+BLEGATTSCHAR:“char”,1,6,0xC305,0x10

表示:

characteristic 所在的 service 的序号为1;

characteristic 的序号为6;

服务特征的 UUID为0xC305;

服务特征的属性为0x10 。

但是这个0x10是什么意思呢,我们找到esp-idf源码的定义可以看到相关定义:0x10表示notify;0x20表示indicate;0x08表示write等。下图为完整定义:

esp32 python 蓝牙开发 esp32经典蓝牙例子_BLE设备名_10

ESP32透传写通道应选服务特征的属性为notify或者indicate的characteristic,读通道应选服务特征的属性为write的characteristic (service 端的读写通道是与client端的读写通道相反的)

从查询得知,我们可以选择第1号service的第6号characteristic发送数据,可以选择第1号service的第5号characteristic接收数据,配置透传模式为:
AT+BLESPPCFG=1,1,6,1,5

BLE透传助手app上对应为

esp32 python 蓝牙开发 esp32经典蓝牙例子_BLE设备名_11

3.4 开启透传

开启透传前app必须先开启侦听,侦听方法见2.2章节
AT+BLESPP //开启透传模式:

响应:
OK

> //等待输入数据

此时可以透传收发数据了

模组发送数据到手机:

在串口调试助手输入"Hello AiThinker"

我们可以在BLE调试助手的第1号service的第6号characteristic看到接收到的数据如下

esp32 python 蓝牙开发 esp32经典蓝牙例子_数据_12

手机发送数据到模组:
在BLE调试助手的第1号service的第5号characteristic输入数据,点击发送即可

esp32 python 蓝牙开发 esp32经典蓝牙例子_安信可ESP32_13

esp32 python 蓝牙开发 esp32经典蓝牙例子_BLE设备名_14


退出透传发送

+++ (不带\r\n)

即可

四、使用静态秘钥进行蓝牙加密配对

AT+RESTORE                          // 恢复出厂设置
AT+BLEINIT=2                        // 将模组初始化为 server
AT+BLEGATTSSRVCRE                   // GATTS 创建服务
AT+BLEGATTSSRVSTART                 // GATTS 开启服务
AT+BLENAME="AiThinker"              //设置BLE 设备名称       
AT+BLEADVDATA="0201060A0941695468696E6B6572"        //广播设备名称 
AT+BLESECPARAM=1,0,16,3,3           // 设置 BLE 加密参数
AT+BLESETKEY=123456                 // 设置 BLE 配对静态秘钥 为123456。如果不设置此条指令,配对密钥为动态密钥    
AT+BLEADVSTART                      // 开始 BLE 广播,使用 APP 与ESP32 建立连接
AT+BLEENC=0,3                       // 连接后,发送此条命令即可产生加密配对请求,输入秘钥

esp32 python 蓝牙开发 esp32经典蓝牙例子_数据_15

esp32 python 蓝牙开发 esp32经典蓝牙例子_BLE设备名_16


使用密钥配对成功后,同一台手机与模组再次使用蓝牙连接不需要再输入密钥。恢复出厂设置AT+RESTORE后连接则需要再次输入密钥。