蓝牙服务功能

news2024/9/24 5:24:52

前言

这阵子用到蓝牙比较多,想写一个专栏专门讲解蓝牙协议及其应用,本篇是第二篇文章,讲解蓝牙服务。

参考网上各大神文章,及瑞萨的文章,参考GPT,并且加入了一些本人的理解。

图片部分源自网络,侵删。

有纰漏请指出,转载请说明。

学习交流请发邮件 1280253714@qq.com

蓝牙服务

在蓝牙低功耗(BLE)中,服务(Service)是指一组相关的特征(Characteristics)的集合,用于定义蓝牙设备之间的数据交换和功能。每个BLE设备可以提供一个或多个服务,每个服务可以包含一个或多个特征。

BLE服务通过唯一的服务UUID(Universally Unique Identifier)来标识,UUID是一个128位的标识符,用于唯一标识一个特定的BLE服务。常见的BLE服务包括:

1. Generic Access Service (GAP):GAP服务是BLE设备中必须提供的一个基本服务,用于管理设备的连接和广告。它包含了设备名称、外观、连接参数等信息。

2. Generic Attribute Service (GATT):GATT服务是BLE设备中定义的一种通用属性协议,用于在设备之间传输和管理属性数据。GATT服务包含了一个或多个特征,每个特征包含了一个或多个属性值。

3. Battery Service:电池服务用于获取BLE设备的电池电量信息。它包含了一个电池电量特征,可以通过读取该特征的值来获取设备的电池电量。

4. Heart Rate Service:心率服务用于获取BLE设备的心率数据。它包含了一个心率测量特征,可以通过读取该特征的值来获取设备的心率数据。

5. Environmental Sensing Service:环境传感服务用于获取BLE设备的环境传感数据,如温度、湿度、光照等。它包含了多个环境传感特征,每个特征对应一种环境传感数据。

6. Health Thermometer Service:健康温度计服务用于获取BLE设备的体温数据。它包含了一个体温测量特征,可以通过读取该特征的值来获取设备的体温数据。

这些是一些常见的BLE服务,不同的设备可能会提供不同的服务和特征,以实现各种不同的功能和应用。通过BLE服务,设备可以实现数据的传输、监测和控制等功能。

服务、特性、属性(读、写、通知)

Service、Characteristic、Property

 

UUID

UUID (Universally Unique Identifier)用于标识蓝牙服务以及通讯特征访问属性,不同的蓝牙服务和属性使用不同的访问方法,就像人们语言交流一样,语言相同才能正常交流(找到正确的UUID,才能使用正确的功能)。 简单理解UUID就是编号,对应不同服务的一个唯一的编号,用于区分不同的服务及服务特性的个体。服务和特性都有各自的UUID。他很像网络应用中的端口号,例如80是HTTP协议的端口,他提供的是HTTP服务。

服务与特性都有一个唯一对应的UUID,每个特性有read、write、notification等属性。我们真正使用蓝牙服务的时候,实际是针对不同属性的特性进行操作。使用过程是:通过蓝牙通信完成与设备的连接,查找到对应的服务,定位到该服务下的某个特性,并根据特性的属性完成具体操作。

16位UUID和128位UUID是两种不同的标识符。

/// @name 16bit Service UUIDs in air format.
/// @sa https://developer.bluetooth.org/gatt/services/Pages/ServicesHome.aspx
///@{
/** Alert Notification Service */
#define ADV_UUID_ALERT_NOTIFICATION_SERVICE         "\x11\x18"
/** Battery Service */
#define ADV_UUID_BATTERY_SERVICE                    "\x0F\x18"
/** Blood Pressure */
#define ADV_UUID_BLOOD_PRESSURE_SERVICE             "\x10\x18"
/** Current Time Service */
#define ADV_UUID_CURRENT_TIME_SERVICE               "\x05\x18"
...

蓝牙16位UUID和128位UUID是用于标识蓝牙设备和服务的唯一标识符。它们之间的区别如下:

1. 长度:16位UUID是16个十六进制字符,而128位UUID是128个十六进制字符。

2. 唯一性:128位UUID的唯一性比16位UUID更高。由于16位UUID的长度较短,可能存在冲突的可能性较大,而128位UUID的长度更长,因此冲突的概率更低。

3. 可用性:由于16位UUID的数量有限,因此在蓝牙设备和服务中使用16位UUID的选择较少。而128位UUID的数量非常大,因此可以更灵活地用于标识各种不同的设备和服务。

4. 可读性:由于16位UUID的长度较短,因此它们通常是由蓝牙SIG(蓝牙特别兴趣小组)分配的预定义UUID。这些预定义UUID通常有一个易于记忆和辨识的名称,例如“蓝牙音频设备”或“蓝牙键盘”。而128位UUID通常是由开发者自己创建的,因此可能没有易于记忆和辨识的名称。

总的来说,16位UUID适用于一些常见的蓝牙设备和服务,而128位UUID适用于更复杂和特定的蓝牙设备和服务。

DA14531 服务的创建与处理

如下,蓝牙可以有多个服务,每个服务有其UUID,每个服务有多个特征值,每个特征值都有其UUID。

// Service 1 of the custom server 1
static const att_svc_desc128_t custs1_svc1                      = DEF_SVC1_UUID_128;

static const uint8_t SVC1_CTRL_POINT_UUID_128[ATT_UUID_128_LEN]       = DEF_SVC1_CTRL_POINT_UUID_128;
static const uint8_t SVC1_LED_STATE_UUID_128[ATT_UUID_128_LEN]        = DEF_SVC1_LED_STATE_UUID_128;
static const uint8_t SVC1_ADC_VAL_1_UUID_128[ATT_UUID_128_LEN]        = DEF_SVC1_ADC_VAL_1_UUID_128;
static const uint8_t SVC1_ADC_VAL_2_UUID_128[ATT_UUID_128_LEN]        = DEF_SVC1_ADC_VAL_2_UUID_128;
static const uint8_t SVC1_BUTTON_STATE_UUID_128[ATT_UUID_128_LEN]     = DEF_SVC1_BUTTON_STATE_UUID_128;
static const uint8_t SVC1_INDICATEABLE_UUID_128[ATT_UUID_128_LEN]     = DEF_SVC1_INDICATEABLE_UUID_128;
static const uint8_t SVC1_LONG_VALUE_UUID_128[ATT_UUID_128_LEN]       = DEF_SVC1_LONG_VALUE_UUID_128;

// Service 2 of the custom server 1
static const att_svc_desc128_t custs1_svc2                      = DEF_SVC2_UUID_128;

static const uint8_t SVC2_WRITE_VAL_1_UUID_128[ATT_UUID_128_LEN]      = DEF_SVC2_WRITE_VAL_1_UUID_128;
static const uint8_t SVC2_WRITE_VAL_2_UUID_128[ATT_UUID_128_LEN]      = DEF_SVC2_WRITE_VAL_2_UUID_128;

如下,Generic Access、Generic Attribute、Device Information,其实都是16位的UUID,是由蓝牙SIG(蓝牙特别兴趣小组)分配的预定义UUID。这些预定义UUID通常有一个易于记忆和辨识的名称。

 

DA14531 通过消息ID选择进入服务的回调

void user_catch_rest_hndl(ke_msg_id_t const msgid,
                          void const *param,
                          ke_task_id_t const dest_id,
                          ke_task_id_t const src_id)
{
    switch(msgid)
    {
        case CUSTS1_VAL_WRITE_IND:
        {
            struct custs1_val_write_ind const *msg_param = (struct custs1_val_write_ind const *)(param);

            switch (msg_param->handle)
            {
                case SVC1_IDX_CONTROL_POINT_VAL:
                    user_svc1_ctrl_wr_ind_handler(msgid, msg_param, dest_id, src_id);
                    break;

                case SVC1_IDX_LED_STATE_VAL:
                    user_svc1_led_wr_ind_handler(msgid, msg_param, dest_id, src_id);
                    break;

DA14531 通过param参数来对回调函数进行处理 

void user_svc1_led_wr_ind_handler(ke_msg_id_t const msgid,
                                     struct custs1_val_write_ind const *param,
                                     ke_task_id_t const dest_id,
                                     ke_task_id_t const src_id)
{
    uint8_t val = 0;
    memcpy(&val, &param->value[0], param->length);

    if (val == CUSTS1_LED_ON)
    {
        GPIO_SetActive(GPIO_LED_PORT, GPIO_LED_PIN);
    }
    else if (val == CUSTS1_LED_OFF)
    {
        GPIO_SetInactive(GPIO_LED_PORT, GPIO_LED_PIN);
    }
}

蓝牙测距

最后介绍一种BLE的特殊功能,这是一种蓝牙特殊的功能

蓝牙测距离可以通过以下几种方式实现:

1. RSSI(接收信号强度指示)测距法:蓝牙设备在通信过程中,可以通过测量接收到的信号强度来估计距离。根据信号强度和距离之间的经验关系,可以通过RSSI值来估计设备之间的距离。

2. TOF(飞行时间)测距法:蓝牙设备可以通过测量信号的传播时间来计算设备之间的距离。这种方法需要设备支持TOF功能,并且需要在设备之间进行时间同步。

3. 视角测距法:蓝牙设备可以通过测量设备之间的视角来估计距离。这种方法利用了三角测量原理,通过测量设备之间的角度和已知的基线长度来计算距离。

需要注意的是,以上方法都是基于估计和计算的,实际测距的精确度会受到多种因素的影响,如信号干扰、障碍物等。因此,在实际应用中,需要根据具体情况选择合适的方法,并进行实时的校准和误差修正。

苹果的Air Tag就用到了这个功能

AirTag是一种由苹果公司推出的追踪设备,可以帮助用户找到丢失的物品。它的工作原理基于以下几个方面:

1. 蓝牙技术:AirTag内置蓝牙芯片,可以与用户的iPhone或其他苹果设备进行通信。当用户将AirTag附在物品上时,可以通过蓝牙与手机进行配对。

2. 寻找功能:当用户无法找到附有AirTag的物品时,可以通过iPhone上的"寻找"应用程序,发出寻找信号。AirTag会发出声音,帮助用户找到物品的位置。

3. 精确定位:苹果的寻找网络是一个由数亿个苹果设备组成的网络,可以帮助用户定位丢失的物品。当AirTag与其他苹果设备接触到时,它会匿名地发送位置信息给用户,以帮助用户找到物品。

4. 安全性:AirTag具有隐私保护功能,以防止被他人滥用。如果AirTag与用户的设备分离超过一定时间,它会发出警报,以提醒用户可能有人追踪他们的位置。此外,AirTag还支持"丢失模式",可以让用户设置联系信息,以便其他人可以联系到他们。

总的来说,AirTag通过蓝牙技术与用户的设备进行通信,并利用苹果的寻找网络帮助用户找到丢失的物品。它提供了精确的定位功能,并具有隐私保护功能,以确保用户的安全。

参考文章

全面且简单明了的蓝牙服务及UUID介绍_蓝牙主服务通道_tanqth的博客-CSDN博客

DA145XX Tutorial Create a Custom GATT Profile — DA145XX Tutorial Create a Custom GATT Profile

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

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

相关文章

树形控件加自定义图标样式及指引线

记录一下留用&#xff0c;有错误请指正。 效果图如下&#xff1a; 自定义图标及指引线 代码&#xff1a; <div class"head-container" style"margin-left: -15px;"><el-tree icon-class"none"style"height:100%; overflow-y: h…

ffmpeg-android studio创建jni项目

一、创建native项目 1.1、选择Native C 1.2、命名项目名称 1.3、选择C标准 1.4、项目结构 1.5、app的build.gradle plugins {id com.android.application }android {compileSdk 32defaultConfig {applicationId "com.anniljing.ffmpegnative"minSdk 25targetSdk 32…

浏览器进程,性能指标,性能优化

目录 浏览器进程&#xff1a;多进程 主进程&#xff1a;显示、交互&#xff0c;增删进程 UI进程&#xff1a;控制地址栏、书签、前进后退 存储进程&#xff1a;cookie&#xff0c;webstorage&#xff0c;indexDB 渲染进程&#xff1a;每个标签页或窗口都有一个独立的渲染进…

Android11编译第四弹:证书和资源内置

问题&#xff1a;我们智能货柜&#xff0c;终端与云端采用的是MQTT通信&#xff0c;为了更加安全&#xff0c;需要采用HTTPS进行通信。这样&#xff0c;中断需要内置证书。这就需要实现ROM中内置资源&#xff0c;将资源打包到系统中。 一、什么是内置资源 内置资源&#xff0…

LeetCode刷题笔记【29】:动态规划专题-1(斐波那契数、爬楼梯、使用最小花费爬楼梯)

文章目录 前置知识解题思路解题步骤动态规划的debug 509. 斐波那契数题目描述解题思路代码使用dp数组优化空间复杂度: 不用数组, 只用两个变量记录即可 70. 爬楼梯题目描述解题思路代码使用dp数组优化空间复杂度: 不用数组, 只用两个变量记录即可 746. 使用最小花费爬楼梯题目描…

Mybatis传递实体对象只能直接获取,不能使用对象.属性方式获取

mybatis的自动识别参数功能很强大&#xff0c;pojo实体类可以直接写进mapper接口里面&#xff0c;不需要在mapper.xml文件中添加paramType,但是加了可以提高mybatis的效率 不加Param注解&#xff0c;取值的时候直接写属性 //这里是单参数&#xff0c;可以不加param&#xff01…

YOLO的基本原理详解

YOLO介绍 YOLO是一种新的目标检测方法。以前的目标检测方法通过重新利用分类器来执行检测。与先前的方案不同&#xff0c;将目标检测看作回归问题从空间上定位边界框&#xff08;bounding box&#xff09;并预测该框的类别概率。使用单个神经网络&#xff0c;在一次评估中直接…

ARM的异常处理

概念 处理器在正常执行程序的过程中可能会遇到一些不正常的事件发生 这时处理器就要将当前的程序暂停下来转而去处理这个异常的事件 异常事件处理完成之后再返回到被异常打断的点继续执行程序 异常处理机制 不同的处理器对异常的处理的流程大体相似&#xff0c;但是不同的处理器…

VsCode备忘

上次简单学习了一下vscode的使用&#xff0c;结果好长时间没用&#xff0c;今天打开又全忘了。。。再记录一下吧 快捷键 CtrlShiftP 命令面板&#xff0c;查找命令&#xff0c;设置等等 Ctrl 打开集成终端&#xff0c;监视生成输出 Ctrl, 打开设置 CtrlP 转到文件,使用转到符…

提高使用VS Code工作效率的技巧

提高使用VS Code工作效率的技巧 时间轴视图&#xff1a;本地源代码控制 时间轴视图为我们提供了内置的源代码控制。 我们中的许多人都知道 Git 和其他源代码控制工具有多么有用&#xff0c;它们可以帮助我们轻松跟踪文件更改并在需要时恢复到之前的状态。 因此&#xff0c;…

网络威胁防御+资产测绘系统-Golang开发

NIPS-Plus 网络威胁防御资产测绘系统-Golang开发 项目地址&#xff1a;https://github.com/jumppppp/NIPS-Plus NIPS-Plus 是一款使用golang语言开发的网络威胁防御系统&#xff08;内置资产测绘系统&#xff09; 网络威胁流量视图网络威胁详细信息浏览列表网络威胁反制探测攻…

编程中的信号处理和系统 - 初学者指南

信号处理是工程和编程的一个重要领域。 基本上,它允许工程师和程序员改进数据,以便人们可以更有效地使用它。 例如,由于信号处理,电话中的大部分背景噪音都被消除了。这样,通话的另一端就只能听到您的声音。 其他例子有: 音频和音乐软件图像视频处理软件医学影像软件语…

【2023高教社杯】D题 圈养湖羊的空间利用率 问题分析、数学模型及MATLAB代码

【2023高教社杯】D题 圈养湖羊的空间利用率 问题分析、数学模型及MATLAB代码 1 题目 题目 D 题 圈养湖羊的空间利用率 规模化的圈养养殖场通常根据牲畜的性别和生长阶段分群饲养&#xff0c;适应不同种类、不同阶段的牲畜对空间的不同要求&#xff0c;以保障牲畜安全和健康&a…

微信小程序navigateTo进入页面后返回原来的页面需要携带数据回来

需求 如图&#xff1a;点击评论后会通过wx.navigateTo进入到评论页面&#xff0c;评论完返回count给原页面&#xff0c;重新赋值实现数量动态变化&#xff0c;不然要刷新这个页面才会更新最新的评论数量。 实现方式&#xff1a; 在评论页面通过wx.setStorageSync(‘data’…

上传ipa到appstore工具

登录app store connect上架的时候&#xff0c;苹果推荐了三个上传构建版本的工具&#xff0c;一个是xcodde&#xff0c;一个是transporter&#xff0c;一个是命令行工具。但是这几个工具在windows都没有对应的软件可以安装。 因此&#xff0c;假如使用windows电脑&#xff0c;…

1600*C. Maximum Set

解析&#xff1a; 尽可能的增大集合内的数&#xff0c;所以倍数要尽可能的小&#xff0c;所以让最小的数不断乘 2&#xff0c;即可找到最大的数量。 所以&#xff0c;每次计算 k log2&#xff08; y / x &#xff09;,这样可得出最小的 x&#xff0c;乘多少个 2&#xff0c;能…

数据分享|WEKA信贷违约预测报告:用决策树、随机森林、支持向量机SVM、朴素贝叶斯、逻辑回归...

完整报告链接&#xff1a;http://tecdat.cn/?p28579 作者&#xff1a;Nuo Liu 数据变得越来越重要&#xff0c;其核心应用“预测”也成为互联网行业以及产业变革的重要力量。近年来网络 P2P借贷发展形势迅猛&#xff0c;一方面普通用户可以更加灵活、便快捷地获得中小额度的贷…

【css面试题】 实现一个盒子的水平竖直居中对齐效果

面试题里有时还会强调 子盒子宽高是否已知&#xff0c;要注意一下 尝试一&#xff1a;给父盒子设置padding 或者子盒子设置margin <style>.father{width: 300px;height: 200px;overflow: hidden; /* 放坑爹现象&#xff0c;不信你删了试试 */background-color: #db7b7b…

SpringBoot隐藏文件

1.设置 2.输入file Types 3.点击忽略文件或者文件夹 4.成功

软件评测师 - 软件测试过程与管理

1.1 软件测试过程 软件的测试过程一般分成测试计划、测试设计与开发、测试实施、测试评审与测试结论等阶段。 软件测试过程是一种抽象的、遵循 GB/T18905&#xff08;ISO14598.5&#xff09;《评价者用的过程&#xff08;Process for Evaluator&#xff09;》 中定义软件评价过…