type
status
date
slug
summary
tags
category
password
icon

蓝牙

notion image

蓝牙广播

蓝牙信道

低功耗蓝牙一共有 40 个信道
频道范围从 2402MHz 到 2480MHz ,每 2MHz 一个信道
其中 37,38,39 是广播信道
notion image
一个广播数据包最长 37 个字节
其中包含 6 个字节用作蓝牙设备的 MAC 地址,剩余 31 个字节称为广播数据包,其又被分为若干个广播数据结构体(AD Structure)
notion image
当广播数据包内容不够 31 个字节时,系统会自动补 0,凑够 31 个字节
常见的广播类型如下:
notion image
蓝牙设备名称采用 UTF-8 编码,完整的广播类型文档参考链接
😖
特别注意:
当 AD Type 为 0x01 表示的是设备标识,含义如下:
数据位
含义
Bit0
LE有限可发现模式
Bit1
LE普通可发现模式
Bit2
不支持 BR/EDR(经典蓝牙)
Bit3
控制器端同时支持 BR/EDR 和LE(低功耗蓝牙)
Bit4
主机端同时支持 BR/EDR 和 LE
Bit 5 - 7
保留
如果设备只支持 LE (低功耗蓝牙),不支持 BR/EDR (经典蓝牙),一般都将设备设为处于普通发现模式,所以只设置 Bit1 和 Bit2 ,即 0x06(b00000110)

扫描请求和扫描响应

蓝牙设备除了可以通过上述方式,主动的发射广播数据外,还可以接受其他设备的扫描请求,从而响应额外的数据,二者的区别如下:
广播是蓝牙从机设备主动发出的数据。
而扫描响应是,当蓝牙主机收到从机的广播数据后,如果想要进一步了解该从机设备的信息,可以向从机设备发送扫描请求,从机收到扫描请求后,向对应的主机回复扫描响应。
notion image
我们前文中讲到,蓝牙的广播数据最多是 31 个字节,如果广播数据太多,这 31 个字节装不下时,我们就可以将一部分不太重要的数据放到扫描响应数据里面,来分担广播数据的工作。
🗯️
在 Android 蓝牙开发中广播包有两种:
  • 广播包(Advertising Data):大小限制在 37 字节
  • 响应包(Scan Response)
外围设备在开启广播时可以带上广播包(必带)或响应包(可选),中心设备扫描到广播时,二者会一起被接收,并放在同一 buffer 中

状态切换和事件处理

蓝牙状态机
蓝牙链路层的状态机有五种状态,分别是就绪态,广播态,链接态,扫描态,发起连接态,各个状态间的转换路径如下图所示:
notion image
以手机连接某个蓝牙模块为例,手机作为主机设备,蓝牙模块作为从机设备。上电之后二者都将处于就绪态,蓝牙模块设置广播数据并开始广播后将转换到广播态;手机扫描附近范围内的蓝牙设备时,手机将处于扫描态,手机尝试连接某个设备时,手机的蓝牙处于发起连接态,连接成功后,二者将都处于链接态。断开连接之后,二者将都再回到就绪态!

服务(Service)和特性(Characteristic)

UUID

UUID是 University Unique Identifie 的缩写,翻译成中文为 通用唯一标识符。是蓝牙组织联盟定义的用于区分蓝牙服务和特性的的标识符,总长度为 128Bit。例如:
128Bit 的 UUID 占用 16 个字节,在变成个传输的时候都很不方便,所以蓝牙联盟定义了一个 UUID 的基地址,允许在此基础上使用 16Bit 的 UUID。
UUID 基地址:0x0000xxxx-0000-1000-8000-00805F9B34FB
比如 16Bit 的 UUID : 0x2A37 转换成 128Bit 的 UUID 为:
低功耗蓝牙设备之间通信,都是基于服务和特性。一个蓝牙设备中可以包含若干个服务,一个服务中可以包含若干个特性,每一个服务或者特性都要有一个 UUID 。
notion image
蓝牙的数据交互都是基于一个个特性进行的,数据交互的方式有五种,分别是 ReadWriteWrite WithOutResponsNotifyIndication
🗯️
上述没说到,每个特性还可以包含若干个 Descriptor 描述,如果想要外围设备的某个特征具有 Notify,那么就需要为这个特征添加一个代表能够主动通知的描述(UUID=”0x2902”)

服务和特性的创建

蓝牙设备要在进入广播态之前创建服务和特性,在 MicroPython 中大概分为四步:
  1. 创建要使用的 UUID;
  1. 使用 UUID 创建特性并设置特性的读写权限;
  1. 将创建好的特性添加到服务集合中;
  1. 将服务集合注册到协议栈中

数据交互

低功耗蓝牙之间的数据交互都是基于特性,以手机连接蓝牙模块为例,手机读取蓝牙模块的数据,使用的是 Read 方法,手机发送数据给蓝牙模块使用的是 Write 方法,蓝牙模块发送数据到手机,一般使用的是 Notify 方法,而且手机端还要打开 Notify 监听。 低功耗蓝牙设备之间通信常用的方式是 Read,Write 和 Notify ,必须在创建特性时赋予对应的权限,才能在通信中使用。如果某个特性在创建的时候,没有开启 Write 权限,则手机将无法通过该特性发送数据到设备;
已定义的 16Bit UUID 对于一些常用的功能,蓝牙组织联盟已经为其定义好了 UUID,我们在开发产品的时候直接使用即可。
16Bit UUID 定义文档下载地址

数据收发

包格式:
一帧低功耗蓝牙的数据包一般情况下最多有261个字节,包含如下内容:
  • 预补码:1个字节,用于时钟同步和信道估计
  • 访问地址: 4个字节
  • 数据位: 2~253字节
  • CRC校验位: 3字节
 

经典蓝牙和低功耗蓝牙的区别

notion image
 

📎 参考文章

 
Mac-常用功能GraphQL API 查询语言
Loading...
shuouyang
shuouyang
android开发 ReactNative开发 小程序开发
最新发布
AOSP 环境搭建
2025-3-29
View 绘制流程-源码解析
2025-3-12
HTTP
2025-3-4
JVM 虚拟机
2025-2-28
蓝牙-BLE-基础
2025-2-28
从 OkHttp 的原理来看 HTTP
2025-2-19
公告
🎉热点信息🎉
--- 1 ---
Jet Brains 推出新的跨平台支持 Kotlin MultiPlatform
--- 2 ---
新的小巧便捷的依赖注入框架 Koin
--- 3 ---
新一代 API 查询语言 GraphQL