CH579 CH573 CH582 CH592 蓝牙主机(Central)实例应用讲解

蓝牙主机(Central),顾名思义,就是一个蓝牙主设备,与从机(Peripheral)建立连接进行通信,可以接收从机通知,也可以给从机发送信息,通常Central和Peripheral结合使用。

一、官方例程Central的工作流程

从官方例程中,我们可以看到,Central的工作流程大致如下:

一、初始化完成开启扫描,

二、获取扫描信息

三、将扫描到的mac地址与目标连接mac地址作比较,扫描到目标mac就发起连接否则继续开启扫描

四、枚举服务进行通信测试

上图标注1:开始扫描
标注2将扫描获取的从机MAC地址加入扫描列表
标注3与目标连接MAC地址比较
标注4没有找到目标,重新开始扫描
标注5找到目标mac,发起连接

从上述描述中我们知道,要想与Peripheral建立连接,必须知道Peripheral的MAC地址,但实际应用中,我们很难知道Peripheral的MAC的地址,就算知道了,也很难输入Central中,毕竟大多数情况下,每个Peripheral的MAC地址是不同的,尤其是我们针对的是现有的产品时。

那么我们如何应对这种问题呢?

二、BLE广播数据中的AD Type详解

 一般来说,同一种产品,广播数据是相同的,甚至同一个厂家的同一种类型的产品,广播数据也会有一些共同的特征,我们可以通过研究产品的广播数据来解决上面提到的问题。所以我们先来了解一下广播数据中的AD Type。

AD Type是广播数据单元(AD Structure)的核心字段,用于定义后续数据(AD Data)的类型和格式。以下是常见AD Type的分类及说明:

一)、基础设备信息类

  1. Flags(类型=0x01)

    • 功能‌:标识设备的发现模式和兼容性,如是否支持BLE/BR/EDR双模。
    • 数据格式‌:1字节,各bit位含义:
      • Bit 0:LE有限发现模式(仅临时可连接)
      • Bit 1:LE普通发现模式(持续可连接)
      • Bit 2:不支持BR/EDR(纯BLE设备)
      • Bit 3-4:控制器/主机支持双模
    • 示例‌:0x06表示支持普通发现模式且不支持BR/EDR。
  2. 完整设备名称(类型=0x09)

    • 功能‌:声明设备完整名称(如Nordic_HRM)。
    • 数据格式‌:UTF-8字符串,长度由Len字段定义。
  3. 缩短设备名称(类型=0x08)

    • 功能‌:设备名称的缩写形式,用于节省广播数据空间。

二)、服务声明类

  1. 完整16位服务UUID列表(类型=0x03)

    • 功能‌:广播设备支持的所有16位标准服务UUID(如心率服务0x180D)。
    • 数据格式‌:多个2字节UUID连续排列。
  2. 非完整服务UUID列表(类型=0x02)

    • 功能‌:仅声明部分服务,需通过扫描响应或连接后获取完整列表。
  3. 32位/128位服务UUID(类型=0x04-0x07)

    • 功能‌:声明长格式服务UUID(如自定义服务)。

三)、设备能力与参数类

  1. 发射功率等级(类型=0x0A)

    • 功能‌:广播设备的发射功率值(单位dBm),用于距离估算。
    • 数据格式‌:1字节有符号整数(如0xF6表示-10 dBm)。
  2. 设备类别(类型=0x0D)

    • 功能‌:标识设备类型(如手机、传感器)。
    • 数据格式‌:3字节,按蓝牙标准分类编码。

四)、厂商自定义数据类

  • 厂商特定数据(类型=0xFF)
    • 功能‌:携带厂商自定义数据(如iBeacon、Eddystone协议)。
    • 数据格式‌:前2字节为厂商ID(如苹果为0x004C),后续为自定义内容。

五)、其他类型

  • 可连接间隔(类型=0x12)‌:声明设备建议的连接参数。
  • 服务请求(类型=0x14)‌:主动请求特定服务(如定位服务)。
  • 还有更多AD Type,这里就不细说,毕竟与我们的主题关系不大,有兴趣的朋友可以很容易从网上搜索到相关的解释。

六)、关键限制与注意事项

  1. 数据长度限制‌:单个广播包载荷(Payload)总长度不超过31字节。
  2. 组合使用‌:一个广播包可包含多个AD Structure,需合理分配类型优先级(如优先Flags和服务声明)。
  3. 动态更新‌:部分AD Type(如设备名称)支持动态修改以适应场景需求。
  4. 以上AD Type并非全部必需,可以根据产品的特性及实际需要来提供。

 三、实例讲解

根据”BLE广播数据中的AD Type详解“一节所述,以及上面三张广播包图,我们很容易知道,广播包包含的内容比较随意,没有强制要求,但AD Type 0x09,也就是设备名称通常会包含,所以蓝牙主机(Central)在扫描时,可以根据AD Type 0x09来判断是否是目标连接。当然我们根据广播包的信息,很容易知道,可以用AD Type 0x07(自定议服务UUID)或用AD TypxFF(厂家自定义的数据类型)来判断是否是目标连接。

接下来,我们以佳能相机蓝牙遥控器为例来讲解如何根据AD Type 0x09及AD Type 0x07来判断是否是目标连接,如果是,则发起连接请求。(因为该项目是商用项目,我们没办法所完整的源码上传,所以只会贴一部分与本主题有关的代码)。

#define PAIR_MODE_TYPE 0x07const uint8_t Serv_uuid[ATT_UUID_SIZE] = {0x21,0xa8,0xff,0x2f,0x49,0xd8,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x05,0x00};const uint8_t cannon_EOSM50[DEVICE_NAME_MAX_LEN] = {0x45,0x4F,0x53,'M',0x35,0x30,0,0,0,0,0,0,0,0,0,0};
const uint8_t cannon_EOS800D[DEVICE_NAME_MAX_LEN] = {0x45,0x4F,0x53,0x38,0x30,0x30,0x44,0,0,0,0,0,0,0,0,0};
const uint8_t cannon_SX70[DEVICE_NAME_MAX_LEN] = {0x53,0x78,0x37,0x30,0,0,0,0,0,0,0,0,0,0,0,0};
const uint8_t * Device_List[DEVICE_COUNT] = {cannon_EOSM50,cannon_EOS800D,cannon_SX70};case GAP_DEVICE_INFO_EVENT:{// Add device to list
//            centralAddDeviceInfo(pEvent->deviceInfo.addr, pEvent->deviceInfo.addrType);if (IsPaired)break;uint8_t cmystata;uint8_t UserNamelen,len;uint8_t EvtData[31];#ifdef DEBUGsprintf(EvtData,"%s",pEvent->deviceInfo.pEvtData);    //将扫描的数据格式化成字符串进行子字符串匹配
#endif//以下为字符串匹配for (uint8_t i = 0; i < pEvent->deviceInfo.dataLen;){if(pEvent->deviceInfo.pEvtData[i]>=2){len = pEvent->deviceInfo.pEvtData[i];if(pEvent->deviceInfo.pEvtData[i+1] == PAIR_MODE_TYPE){
#if 0for (uint8_t idx = 0; idx < DEVICE_COUNT; idx ++){cmystata = tmos_memcmp(&pEvent->deviceInfo.pEvtData[i+2],Device_List[idx],len-1);if (cmystata == TRUE){
//                    Device_Ctrl.Device_Idx = idx;break;}}
#elsecmystata = tmos_memcmp(&pEvent->deviceInfo.pEvtData[i+2],Serv_uuid,len-1);
#endifif(cmystata == TRUE) //  找到了{
//                StrMatchingFlag = TRUE;GAPRole_CentralCancelDiscovery();     //取消设备扫描发现centralAddDeviceInfo(pEvent->deviceInfo.addr, pEvent->deviceInfo.addrType);}PRINT("\r\n");return;}else{i += len+1;}}else{i++;}}}break;case GAP_DEVICE_DISCOVERY_EVENT:{PRINT("Device found...\n");GAPRole_CentralEstablishLink(DEFAULT_LINK_HIGH_DUTY_CYCLE,DEFAULT_LINK_WHITE_LIST,centralDevList[0].addrType,centralDevList[0].addr);//                BLEConnected = BLE_CONNECTING;// Start establish link timeout eventtmos_start_task(centralTaskId, ESTABLISH_LINK_TIMEOUT_EVT, ESTABLISH_LINK_TIMEOUT);PRINT("Connecting...\n");}break;

以上代码,简单阐述一下,本来我们开始是打算根据AD Type 0x09(也就是设备名称)来判断是否是目标连接,但后来客户不断的增加相机类型,甚至还要求支持没有提供的设备,所以转为根据AD Type 0x07(自定议服务UUID)来判断。

#define PAIR_MODE_TYPE 0x07就是指AD Type 0x07,如果要根据AD Type 0x09,这个地方需要修改,程序代码可能也需要略作修改,毕竟我们后面的代码全部是根据AD Type 0x07(自定议服务UUID)来开发的。

代码本身比较简单,与官方例程不同的是, case GAP_DEVICE_INFO_EVENT:官方例程只是把扫描到的信息添加到相应的列表中, case GAP_DEVICE_DISCOVERY_EVENT: 在这里才判断是否是目标连接。而我们的实例则是在case GAP_DEVICE_INFO_EVENT:就判断是否是目标连接,而在case GAP_DEVICE_DISCOVERY_EVENT: 只是简单的发起连接请求。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/80223.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

不同类型的 SAP 项目

目录 1 实施项目 2 SAP S/4 HANA 升级项目 3 数据迁移项目 4 优化项目 5 Rollout 项目 6 运维项目 1 实施项目 企业第一次用 SAP 系统&#xff0c;从硬件搭建到安装 SAP、根据业务流程做配置、开发、培训业务、测试系统直到系统上线。 SAP S/4 HANA ACTIVATE 实施方法论…

【uniapp】errMsg: “navigateTo:fail timeout“

项目场景&#xff1a; 在点击编辑的时候不能跳转的编辑的页面&#xff0c;然后直接报错errMsg: "navigateTo:fail timeout" 解决方案&#xff1a; 看看是否是出现了盒子的冒泡事件导致了两次调用跳转路径 tap.stop

记录学习的第三十五天

今天主攻单源最短路Dijkstra算法。不过&#xff0c;还是没有完全掌握。 首先是书本的例题我理解了一遍。 然后其实在力扣上做了三道题的&#xff0c;但是我看题解的情况就不太会。然后试着用上面的方法敲了一下↓的题&#xff0c;但是不对啊&#xff0c;我也不知道为什么呀。

Spring-博客系统项目

一,实现效果 登录: 注册: 博客列表 个人博客中心 博客详情: 更新博客 编写博客 二,数据库的建立和连接 首先,需要建库,需要两个实体,一个是用户,一个是博客,需要如下属性,需要注意的是需要将密码的变长字符创设置的长一些,因为之后会对用户的密码进行加密,该博客中密码…

依赖注入详解与案例(前端篇)

依赖注入详解与案例&#xff08;前端篇&#xff09; 一、依赖注入核心概念与前端价值 依赖注入&#xff08;Dependency Injection, DI&#xff09; 是一种通过外部容器管理组件/类间依赖关系的设计模式&#xff0c;其核心是控制反转&#xff08;Inversion of Control, IoC&…

diy装机成功录

三天前&#xff0c;我正式开启了这次装机之旅&#xff0c;购入了一颗性能强劲的 i5-12400 CPU&#xff0c;一块绘图能力出色的 3060ti 显卡&#xff0c;还有技嘉主板、高效散热器、16G 内存条、2T 固态硬盘&#xff0c;以及气派的机箱和风扇&#xff0c;满心期待能亲手打造一台…

计算机三大主流操作系统的前世今生 - Linux|macOS|Windows

全文目录 1 引言2 起源之路2.1 Linux 起源2.2 macOS 起源2.3 Windows 起源 3 综合解析3.1 Linux系统综合解析3.1.1 系统定义与核心架构3.1.2 发展历程3.1.3 核心特点3.1.4 主流发行版3.1.5 应用场景 3.2 macOS系统综合解析3.2.1 系统定义与核心架构3.2.2 发展历程3.2.3 核心特点…

【AI智能推荐系统】第七篇:跨领域推荐系统的技术突破与应用场景

第七篇:跨领域推荐系统的技术突破与应用场景 提示语:🔥 “打破数据孤岛,实现1+1>2的推荐效果!深度解析美团、亚马逊如何用跨领域推荐技术实现业务协同,知识迁移核心技术全公开!” 目录 跨领域推荐的商业价值跨领域推荐技术体系 2.1 基于共享表征的学习2.2 迁移学习…

R 语言科研绘图 --- 桑基图-汇总

在发表科研论文的过程中&#xff0c;科研绘图是必不可少的&#xff0c;一张好看的图形会是文章很大的加分项。 为了便于使用&#xff0c;本系列文章介绍的所有绘图都已收录到了 sciRplot 项目中&#xff0c;获取方式&#xff1a; R 语言科研绘图模板 --- sciRplothttps://mp.…

LintCode第485题-生成给定大小的数组,第220题-冰雹猜想,第235题-分解质因数

第485题 描述 给你一个大小size,生成一个元素从1 到 size的数组 样例 1:输入: size 4输出: [1, 2, 3, 4]样例解释: 返回一个顺序填充1到4的数组。样例 2:输入: size 1输出: [1]样例解释: 返回一个顺序填充1到1的数组 代码如下: public class Solution { /** * param s…

Pandas:数据处理与分析

目录 一、Pandas 简介 二、Pandas 的安装与导入 三、Pandas 的核心数据结构 &#xff08;一&#xff09;Series &#xff08;二&#xff09;DataFrame 四、Pandas 数据读取与写入 &#xff08;一&#xff09;读取数据 &#xff08;二&#xff09;写入数据 五、数据清洗…

Linux云计算训练营笔记day05(Rocky Linux中的命令:管道操作 |、wc、find、vim)

管道操作 | 作用: 将前面命令的输出&#xff0c;传递给后面命令&#xff0c;作为后面命令的参数 head -3 /etc/passwd | tail -1 取第三行 head -8 /etc/passwd | tail -3 | cat -n 取6 7 8行 ifconfig | head -2 | tail -1 只查看IP地址 ifconfig | grep 192 过滤192的ip…

动态规划:最长递增子序列

给定一个数组&#xff0c;求最长递增子序列的长度,就是要求我们求出一个序列中最长的上升子序列的长度&#xff0c;最长上升子序列的定义就是从原序列中按照孙旭去除一些数字&#xff0c;这些数字是逐渐增大的。 *定义dp[i]表示以第i个元素结尾的最长上升子序列的长度。 *初始…

湖北理元理律师事务所:债务优化如何实现还款与生活的平衡?

债务压力往往让债务人陷入“还款还是生存”的两难选择。湖北理元理律师事务所通过案例实践发现&#xff0c;科学规划的核心在于平衡法律义务与基本生活保障&#xff0c;而非单纯追求债务缩减。本文结合实务经验&#xff0c;解析债务优化的可行路径。 刚性需求优先&#xff1a;…

重力场模型、球谐函数以及重力异常

地球重力场有两种表达方法&#xff1a; 1、拉普拉斯&#xff08;Laplace&#xff09;方法&#xff0c;将重力场展开为球谐级数。 2、斯托克斯&#xff08;Stokes&#xff09;方法&#xff0c;根据地球的总质量和旋转角速度计算。 本篇主要说第一种方法&#xff0c;该方法将地…

MySQL的视图

一、MySQL视图的介绍和作用 MySQL视图&#xff0c;加油兄弟们&#xff0c;孰能生巧&#xff0c;完整代码在最后&#xff01;&#xff01;&#xff01; 视图是一个虚拟的表&#xff0c;并不是真是存在的&#xff0c;视图其实并没有真实的数据&#xff0c;他只是根据一个sql语句…

Scala与Go的异同教程

当瑞士军刀遇到电锯&#xff1a;Scala vs Go的相爱相杀之旅 各位准备秃头的程序猿们&#xff08;放心&#xff0c;用Go和Scala不会加重你的发际线问题&#xff09;&#xff0c;今天我们来聊聊编程界的"冰与火之歌"——Scala和Go的异同。准备好瓜子饮料&#xff0c;我…

SaaS场快订平台项目说明【持续更新】

一、项目介绍 SaaS场快订平台是一个高效、便捷的体育场馆在线预订平台。本项目采用SaaS方式开发&#xff0c;用户不需要安装软件&#xff0c;直接通过互联网访问在线程序即可使用。本项目主要构建了一个体育馆预订系统&#xff0c;项目的功能主要包括&#xff1a;用户注册与登…

linux中常用的命令(三)

目录 1- ls(查看当前目录下的内容) 2- pwd (查看当前所在的文件夹) 3- cd [目录名]&#xff08;切换文件夹&#xff09; 4- touch [文件名] &#xff08;如果文件不存在&#xff0c;新建文件&#xff09; 5- mkdir[目录名] &#xff08;创建目录&#xff09; 6-rm[文件名]&…

使用Simulink开发Autosar Nvm存储逻辑

文章目录 前言Autosar Nvm接口设计模型及接口生成代码及arxmlRTE接口mappingRTE代码分析总结 前言 之前介绍过Simulink开发Dem故障触发逻辑&#xff0c;本文接着介绍另外一个常用的功能-Nvm存储的实现。 Autosar Nvm接口 Autosar Nvm中一般在上电初始化的时调用Nvm_ReadAll获…