BLE低功耗蓝牙开发相关概念问题记录
时间:2022-04-24
本文章向大家介绍BLE低功耗蓝牙开发相关概念问题记录,主要内容包括Ble概念相关、问题总结、基本概念、基础应用、原理机制和需要注意的事项等,并结合实例形式分析了其使用技巧,希望通过本文能帮助到大家理解应用这部分内容。
蓝牙ble的传输速率是指主从机每秒所传输的字节数。既然是传输速率那就涉及到时间和每次所传递包大小的问题。
关于ble通信的demo可以参考蓝牙API介绍及基本功能实现
Ble概念相关
ble对于数据的传输有一个字节上的限制,默认情况下是20个字节,但并不是不可修改的。默认情况下mtu是23个字节(除去3个字节的标志位剩余为20个字节),主机完全可以通过调用BluetoothGatt#requestMtu(int mtu)来修改每个包所传输的字节数。 同样,ble在属于传输时对于每个包之间的时间间隔也有一定的限制,大多数从机的连接时间间隔为7.5ms–4s(以1.25ms为一个单位,也就是6-0x0C80个单位)。对于连接间隔主机同样可以修改:调用BluetoothGatt# requestConnectionPriority(int connectionPriority)方法。其中connectionPriority有三个取值:
- BluetoothGatt#CONNECTION_PRIORITY_LOW_POWER:低功耗, 对应的连接时间间隔取值范围为:100ms–125ms(80–100个单位)。 对应的从机延时取值为:2.5ms(2个单位) 对应的监控超时取值为:20s(以10ms为一个单位);
- BluetoothGatt#CONNECTION_PRIORITY_BALANCED:处于中等水平 对应的连接时间间隔取值范围为:30ms–50ms(24–40个单位)。 对应的从机延时取值为:0ms(0个单位) 对应的监控超时取值为:20s();
- BluetoothGatt#CONNECTION_PRIORITY_HIGH:高功耗 对应的连接时间间隔取值范围为:11.25ms–15ms(9–12个单位)。 对应的从机延时取值为:0ms(0个单位) 对应的监控超时取值为:20s();
接下来看一下各个概念是什么意思??
- 主机和从机:发起连接的设备是主机,接受连接请求的设备是从机
- 客户端和服务器:展示“属性”的设备是服务器,与之配对的是客户端。换言之,获取信息的客户端提供信息的是服务器
- 主机可以是客户端也可以是服务器端,同样从机可以做客户端也可以做服务器端
- BLE协议和协议栈:协议指的是一种通信标准。比如规定第一个字节代表什么意思第二个字节又代表什么意思。而协议栈是具体的一些实现函数,开发人员调用协议栈函数进行通信(相当于各种API)
- 连接事件:在两个ble设备的连接中使用调频机制,两个设备使用特定的信道收发数据,过段时间再使用新的信道(链路层处理信道切换),两个设备在信道切换后首发数据称为连接事件。即使没有数据收发两设备仍旧会交换链路层数据来维持连接。在一次连接事件中会不停的切换信道,所发送的数据包不止一个。
- 连接间隔(Connection Interval):就是两个连接事件之间的间隔。主机开始发送数据到从机至下一次主机开始发送数据到从机之间的时间间隔。主从机之间的每次通信都是一个连接事件(但不同于第一次从机处于广播状态下主机连接从机)。以1.25ms为一个单位,一般取值是7.5ms–4s(6–3200)。
- 从机延时(Slave latency):允许从机跳过一些连接事件。简单说就是我规定一个时间,在这次连接事件开始后到一定时间内,在这一段时间内从机不响应主机的任何消息。
- 监控超时(Supervision Timeout):两个成功连接事件间的最大允许间隔。如果超过了这个时间而没有任何连接事件即没有任何数据交换则断开连接。以10ms为一个单位,一般取值范围是100ms–32s(10–3200)。
主机在发起连接之后会获取一个BluetoothGatt对象。
- 主机主动读数据调用readCharacteristic方法,读之后会触发 onCharacteristicRead方法
- 主机主动写数据调用writeCharacteristic方法,写之后会触发 onCharacteristicWrite方法(可以进行下一次的写数据)
- 主机被动获取到数据(从机通过notify方法发送数据),当监听到有数据过来时会触发 onCharacteristicChanged方法(但是要想该方法回调,必须在主机端程序中为要监听的characteristic设置notify: setCharacteristicNotification)
- 主机修改mtu(一个包的字节)会触发onMtuChanged方法。
主机从机连接通信过程描述:
- 主机开启蓝牙enable()
- 主机扫描蓝牙startLeScan()( startLeScan(final UUID[] serviceUuids, final LeScanCallback callback) 可以扫描特定uuid的设备)
- 主机connect连接蓝牙
- 主机discoveryServices发现服务( 会回调onServicesDiscovered方法)
- 进行通信
问题总结
问题一:在扫描蓝牙时如何进行过滤??
这个系统已经提供了接口了:
@Deprecated
@RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
public boolean startLeScan(final UUID[] serviceUuids, final LeScanCallback callback) {
把你想要扫描的设备的服务的uuid添加到serviceUuids中进行扫描即可。千万不要以name作为过滤。 如果在扫描到设备之后再通过BluetoothDevice.getUuids()方法进行过滤是不起作用的,看看对方法的定义就知道了:
/**
* Returns the supported features (UUIDs) of the remote device.
*
* <p>This method does not start a service discovery procedure to retrieve the UUIDs
* from the remote device. Instead, the local cached copy of the service
* UUIDs are returned.
* <p>Use {@link #fetchUuidsWithSdp} if fresh UUIDs are desired.
* <p>Requires {@link android.Manifest.permission#BLUETOOTH}.
*
* @return the supported features (UUIDs) of the remote device,
* or null on error
*/
@RequiresPermission(Manifest.permission.BLUETOOTH)
public ParcelUuid[] getUuids() {
这里返回的uuid是缓存的uuid。如果你没有缓存的uuid获取到的肯定是null。
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 用上Latex实现编辑伪代码
- TensorFlow交叉熵函数(cross_entropy)·理解
- 第05期:Prometheus 数据查询(一)
- 技术分享 | MySQL 复制那点事 - Seconds_behind_Master 参数调查笔记
- 线程有多少种状态?Runnable 一定在执行任务吗?
- swift 中类(class)和结构体(struct)区别
- C语言三剑客之《C专家编程》一书精华提炼
- 前端必备技能:json-server全攻略
- 温故知新——Spring AOP(二)
- R语言中的偏最小二乘PLS回归算法
- R如何与Tableau集成分步指南
- 漏洞复现 | CVE‐2020‐5902踩坑记
- PCA图显示分组无差异,怎么办?
- 我接手了一个“垃圾”系统,全栈优化后将性能提升了350倍
- 用 eggnog-mapper 进行功能注释