前言
这阵子用到蓝牙比较多,想写一个专栏专门讲解蓝牙协议及其应用,本篇是第二篇文章,讲解蓝牙服务。
参考网上各大神文章,及瑞萨的文章,参考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, ¶m->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