OC 血压计 蓝牙BLE4.0 链接踩坑开发

iOS开发(OC)——蓝牙(BLE) iOS开发交流群:301058503 导入头文件 #import <CoreBluetooth/CoreBluetooth.h> 定义代理 CBCentralManagerDelegate,CBPeripheralDelegate 定义全局变量 @property (nonatomic,strong)CBCentralManager *central... 阅读详情

前言

公司项目要连接第三方公司的血压计,由于从来没有做过和蓝牙有关的项目,好奇的心驱使下下也想顺便了解一下这方面的知识,于是主动向领导请求开发这个功能,经过4天的折腾,终于弄好了,(为什么要4天呢?TMD第三天才搞明白原来不是我代码不行,是他们给错文档了,MDZZ,强忍住骂娘的冲动。。。

蓝牙基础知识:

名词解释:

BLE:(Bluetooth low energy)蓝牙4.0设备因为低耗电,也叫BLE
peripheral,central:外设和中心设备,发起链接的是central(一般是指手机),被链接的设备是peripheral(运动手环)
service and characteristic:(服务和特征)每个设备会提供服务和特征,类似于服务端的API,但是结构不同.每个设备会有很多服务,每个服务中包含很多字段,这些字段的权限一般分为读(read),写(write),通知(notify)几种,就是我们连接设备后具体需要操作的内容
Description:每个characteristic可以对应一个或者多个Description用于描述characteristic的信息或属性(eg.范围,计量单位)

蓝牙开发的2种模式:

中心模式:就是以你的app作为中心,连接其他的外设的场景(本次项目使用,个人认为大部分的情况下都是这种模式)
外设模式:使用手机作为外设连接其他中心设备操作的场景

服务和特征(service and characteristic)

每个设备都会有1个or多个服务
每个服务里都会有1个or多个特征
特征就是具体键值对,提供数据的地方
每个特征属性分为:读,写,通知等等

外设、服务(service)、特征(characteristic)的关系:

建议需要蓝牙开发的小伙伴,先去App Store下载LightBlue这个软件,他的主要作用就是连接上蓝牙外设,并且告诉你,这个蓝牙设备都支持什么服务,每个服务下面有哪些特征,甚至还可以持续监听蓝牙设备发出的数据,你也可以向蓝牙设备写数据(经个人验证,本次开发血压计,写数据、监听数据都没有用,不知道是设备的问题,还是LightBlue的问题,但都无所谓了,毕竟有了服务和特征的UUID,它的任务就完成了……)

开发:

主要流程思路:

建立一个Central Manager实例进行蓝牙管理
搜索外围设备
连接外围设备
获得外围设备的服务
获得服务的特征
从外围设备读数据
给外围设备发送数据

上代码:

注:本来想好好写写集成过程的代码,但是回头一想,集成代码出现在踩坑的文章中,好不专业,而且集成代码在网上
搜索能搜索出一大堆,非常完整、全面,瞬间没有了写下去的动力,回头想想那就不重复造轮子了吧,附上一篇文章,
过程大概就是这样:
https://www.jianshu.com/p/87c30628ddaa
作者辛苦!

坑:

下面主要说一下过程中遇到的坑:

1、搞准CBService的UUID

连接好设备后,搜索CBService时候的UUID,开始做之前最好知道哪个服务的UUID是你需要的,这个第三方设备合作方或者蓝牙设备文档上面会告诉你。如果不知道服务的UUID,需要自己一个个试的话,那就要注意啦,因为设备上面有很多服务,可能有多个服务都具备读写属性甚至都支持通知,在这一步找到正确的UUID是十分关键的,如果这一步错了,后面肯定错。。。

2、查看特征支持

找到服务之后要查看该服务下面的特征都支持什么属性,有了特征支持,就可以针对每个特征进行相应的操作。
提供一个打印特征支持的方法:

-(void)logCharacteristicProperties:(CBCharacteristicProperties)properties {//查看特征支持

if (properties &CBCharacteristicPropertyBroadcast) {//广播

NSLog(@"CBCharacteristicPropertyBroadcast");

}

if (properties &CBCharacteristicPropertyRead) {//读

NSLog(@"CBCharacteristicPropertyRead");

}

if (properties &CBCharacteristicPropertyWriteWithoutResponse) {//写-没有响应

NSLog(@"CBCharacteristicPropertyWriteWithoutResponse");

}

if (properties &CBCharacteristicPropertyWrite) {//写

NSLog(@"CBCharacteristicPropertyWrite");

}

if (properties &CBCharacteristicPropertyNotify) {//通知

NSLog(@"CBCharacteristicPropertyNotify");

}

if (properties &CBCharacteristicPropertyIndicate) {//声明

NSLog(@"CBCharacteristicPropertyIndicate");

}

if (properties &CBCharacteristicPropertyAuthenticatedSignedWrites) {//通过验证的

NSLog(@"CBCharacteristicPropertyAuthenticatedSignedWrites");

}

if (properties &CBCharacteristicPropertyExtendedProperties) {//拓展

NSLog(@"CBCharacteristicPropertyExtendedProperties");

}

if (properties &CBCharacteristicPropertyNotifyEncryptionRequired) {//需要加密的通知

NSLog(@"CBCharacteristicPropertyNotifyEncryptionRequired");

}

if (properties &CBCharacteristicPropertyIndicateEncryptionRequired) {//需要加密的申明

NSLog(@"CBCharacteristicPropertyIndicateEncryptionRequired");

}

}

3、发送数据,无响应

有些设备发送指令的时候会发现没有响应,甚至didWriteValueForCharacteristic
回调的值都是空,这种情况的一个原因是:有些设备需要先建立连接,才能执行后续操作,这个链接不是之前的已经链接好的蓝牙,是需要向外设发送一个连接指令,就比如我这次做的血压计开发,直接发送开始测量指令是不好使的,必须得先发送链接指令,等血压计响应之后,再发开始测量指令。。。

一般情况下,我们发送的指令都是从字符串开始的,想发送给蓝牙,必须是NSData型,但好像转化的时候不是常见的转换方法,

附上发送的指令转换方法:

//NSString类型转换成NSData

-(NSData*)stringToByte:(NSString*)string{

NSString *hexString=[[stringuppercaseString] stringByReplacingOccurrencesOfString:@" "withString:@""];

if ([hexString length]%2!=0) {

return nil;

}

Byte tempbyt[1]={0};

NSMutableData* bytes=[NSMutableDatadata];

for(int i=0;i<[hexStringlength];i++)

{

unichar hex_char1 = [hexStringcharacterAtIndex:i]; ////两位16进制数中的第一位(高位*16)

int int_ch1;

if(hex_char1 >= '0' && hex_char1 <='9')

int_ch1 = (hex_char1-48)*16;  //// 0 的Ascll - 48

else if(hex_char1 >= 'A' && hex_char1 <='F')

int_ch1 = (hex_char1-55)*16;//// A 的Ascll - 65

else

return nil;

i++;

unichar hex_char2 = [hexStringcharacterAtIndex:i]; ///两位16进制数中的第二位(低位)

int int_ch2;

if(hex_char2 >= '0' && hex_char2 <='9')

int_ch2 = (hex_char2-48);//// 0 的Ascll - 48

else if(hex_char2 >= 'A' && hex_char2 <='F')

int_ch2 = hex_char2-55;//// A 的Ascll - 65

else

return nil;

tempbyt[0] = int_ch1+int_ch2; ///将转化后的数放入Byte数组里

[bytes appendBytes:tempbytlength:1];

}

return bytes;

}

//NSData类型转换成NSString

- (NSString*)hexadecimalString:(NSData *)data{

NSString* result;

const unsignedchar* dataBuffer = (const unsigned char*)[data bytes];

if(!dataBuffer){

return nil;

}

NSUInteger dataLength = [datalength];

NSMutableString* hexString = [NSMutableStringstringWithCapacity:(dataLength * 2)];

for(int i =0; i < dataLength; i++){

[hexString appendString:[NSStringstringWithFormat:@"%02lx", (unsignedlong)dataBuffer[i]]];

}

result = [NSString stringWithString:hexString];

return result;

}

4、处理蓝牙接收的信息

一般收到的信息都是十六进制的数值,具体代表什么意思,蓝牙开发文档已经都写好了,如果没有文档的话,我也不知道怎么办了
十六进制转为十进制的方法:

/**

十六进制转化为十进制



@param aHexString 需要转化的str

@return 十进制数

*/

- (NSNumber *) numberHexString:(NSString *)aHexString{

// 为空,直接返回.

if (nil == aHexString){

return nil;

}

NSScanner * scanner = [NSScannerscannerWithString:aHexString];

unsigned long long longlongValue;

[scanner scanHexLongLong:&longlongValue];

//将整数转换为NSNumber,存储到数组中,并返回.

NSNumber * hexNumber = [NSNumbernumberWithLongLong:longlongValue];

return hexNumber;

}
IOS Objective-c 蓝牙开发教程一蓝牙的连接 一开始使用swift连接蓝牙,接收数据,但是因为需求又改成用oc写了,写了swift再写oc非常快的!      开发蓝牙,首先要理解几个概念什么是中心(centrol)什么是周边(peripheral),这些比较基础百度一下就行。有了这些基本概念以后再上手会快些;      首先从targets------>Build Phases------>导入corebluetooth.framewo 阅读详情

相关推荐

开发低功耗蓝牙4.0血压计连接与收发数据

最近在开发鱼跃YE680A蓝牙血压计,获取测量到的血压和心率数据,之前也做有一个爱奥乐蓝牙血压计的,连接流程是一样的,在收发数据时有一些区别,下面做一些笔记:一、整体的可定义三个类,一个Bluetooth服务的,用于连接,一个包含各类UUID的,用于收发数据,最后一个封装工具类,给调用者调用。 1. 先说连接吧,判断是不是支持蓝牙功能,是否打开蓝牙和请求打开蓝牙涉及到的,代码详细可能没贴出来了,

wushengjun1991的博客 6407

Uni-App使用低功耗蓝牙连接血压仪测量(先转载了,很详细)

1、Uni-APP蓝牙使用流程 在阅读这篇内容之前,建议您详细浏览一遍uni-app官方关于蓝牙和低功耗蓝牙(BLE)使用教程文档 uni-app官方低功耗蓝牙接口,如果您有微信小程序方面的开发经验,那您看这篇文章会很快上手,uni-app官方的蓝牙模块接口均是按照微信小程序的蓝牙模块接口编写。 思路流程 手机上打开蓝牙,设备打开蓝牙 APP初始化蓝牙模块 APP调用蓝牙搜寻设备 APP存储搜寻到的指定设备deviceId APP根据指定deviceId连接蓝牙设备 APP连接设备之后获取设备的服务列表s

code 1872

低功耗蓝牙模块在智能血压计中的应用

​   低功耗蓝牙模块在智能血压计中的应用为用户带来了诸多便利,如实时数据传输、远程监控、语音助手等功能。这些功能的实现离不开低功耗蓝牙模块的强大支持。随着物联网技术的不断发展,我们有理由相信,未来智能血压计将会更加智能化、人性化,为人们的健康保驾护航。

2301_81199294的博客 803

2.OC蓝牙功能

一. 最早的蓝牙框架是GameKit,iOS7之前用的比较多,它有只能支持iOS设备间的传输,但是使用步骤简单,我们只需要搞清楚两个类就可以了。 GKPeerPickerController:熟称浏览器,调用此控制器的show方法来显示当前的蓝牙热点,一旦发现有另一页在查找蓝牙的用户,之间就能实链接。 GKSession:连接会话,主要用于发送和接受传输数据。档两个程序进行连接时,GKPee...

weixin_33755554的博客 327

蓝牙HDP协议源码解析

1,概述 1.1 HDP协议 HDP协议: Health Device Profile健康设备协议 使用场景:支持各种蓝牙健康设备和手机进行通信 市场产品:广泛应用于各种智能穿戴设备,比如蓝牙健康手环,蓝牙血压计,蓝牙温度计,蓝牙电子称等各种健康设备。   1.2 代码路径 客户端: frameworks\base\core\java\android\bluetooth   Blu

Jack的博客 5186

Android蓝牙健康设备开发:Health Device Profile(HDP)

android经典蓝牙健康设备开发

github_39281554的博客 2642

iOS开发之蓝牙通讯

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_33709590的博客 257

Android BLE4.0通信之计步、体重、血压

新手刚接触蓝牙4.0,好不容易实现了读取蓝牙上的步数,体重上的数据和血压计的数据。网上资料真的很难找。 扫描蓝牙设备的Activity public class DeviceScanActivity extends ListActivity { private final static int REQUEST_ENABLE_BT = 1; private boolea

zjy323520的博客 3624

CBCharacteristic-CBMutableCharacteristic学习笔记

如有不对的地方欢迎留言指正。谢谢 CBCharacteristic学习笔记 /*!  *  @class CBCharacteristic  *  @discussion  *      代表一个服务的特征  */ @interface CBCharacteristic : NSObject //表明这个属于哪个service @

fang8380的专栏 2317

iOS蓝牙开发:蓝牙的连接和数据的读写

蓝牙开发说简单也简单,说不简单也有点难,开发人员在首次开发蓝牙前首先需要搞清楚蓝牙开发的概念,还要了解掌握蓝牙开发的一整套流程,这样才能快速上手开发蓝牙。

全沾软贱开发攻城狮 1万+

蓝牙BLE血压计Profile

Blood Pressure Profile 21 Jan 2019 蓝牙BLE血压计Profile

第二个参数(那个 properties)确定你将如何使用这个特性值

CBCharacteristicPropertyBroadcast: 允许一个广播特性值,用于描述特性配置,不允许本地特性 CBCharacteristicPropertyRead: 允许读一个特性值 CBCharacteristicPropertyWriteWithoutResponse: 允许写一个特性值,没有反馈 CBCharacteristicPropertyWrite: 允许写一个...

weixin_30823227的博客 440

欧姆龙蓝牙血压计开发文档

欧姆龙蓝牙血压计开发文档,附部分andriod操作代码

iOS:CoreBluetooth 使用

CoreBluetooth 是基于蓝牙 ble 技术实现的,现在的智能手环手表都使用了低功耗蓝牙技术。 CoreBluetooth 场景中蓝牙对象分为两种: 中心设备(CBCentralManager * cbcManager): 中心设备负责扫描接收广播,连接外设设备,向外设设备进行读写操作。 外设设备(CBPeripheral * peripheral): 向外发送广播,...

GSNICE 2634

蓝牙血压计源码

简单蓝牙血压计开发,基于蓝牙4.0,内有GATT基本连接及一些简单设计,本人已经测试通过可运行供大家学习使用,有些信息没怎么整理下载可能需要大家根据实际情况做下整理,因工作原因没那怎么处理,此版仅限蓝牙功能完好

setoolkit克隆网站获取用户信息

一、环境 kali、DVWA 二、步骤 首先打开kali,输入setoolkit 依次选择选项1-选项2-选项3-选项2 输入钓鱼网站的网址(默认为本地网址) 输入要克隆的网址URL 这里我的网址如图,将网址复制 然后模拟攻击场景,攻击者向受害者发送了一条钓鱼链接,此链接与DVWA的登陆页面完全一样,受害者点击之后并进行登陆信息 点击login之后,用户信息就被setool...

BeatRex的博客 2997

iOS之蓝牙开发—CoreBluetooth详解二

这里主要向大家简单地讲解一下的通过中心设备对外设硬件进行数据的写入和反馈消息的获取。 在进行讲解之前,我们需要明白以下几点: 1.查看特征的属性: typedef NS_OPTIONS(NSUInteger, CBCharacteristicProperties) { CBCharacteristicPropertyBroadcast

吴泽松的博客 2000

ICG setup timing violation介绍?

门控时钟(clock gating)在RTL级电路设计过程中进行低功耗优化常用方法,能够有效降低动态功耗(翻转功耗)。Clock gating cell 可以由与门,与非门,或门或者或非门构成,但很容易产生Glitch。在实际使用中,一般用ICG(集成门控时钟单元)来完成clock gating。 下图展示了glitch的产生原因 在CTS时钟树综合的时候,ICG不会被看作sink,通常放置在source点附近,因此就会出现如上图这种结果。上图可以看出,在分析DFF到ICG的setup timing

m0_61003348的博客 9810

iOS 右滑返回失效问题终极解决方案

iOS 的右滑返回是必不可少的一项功能,否则用户体验会大打折扣,但是会经常会碰到某些页面右滑返回失效的情况,下面记录一下解决各种情况下右滑返回失效的方法: 1. 自定义返回按钮 如果页面上是自定义的返回按钮,那在viewDidLoad中加上下面这句话就可以: - (void)viewDidLoad { [super viewDidLoad]; self.navigationCont...

小歲月丶太着急 9668

桑基图实战指南:Excel/Python/R三工具高效绘制方法

桑基图是一种以线条宽度编码流量大小、以节点位置表达流程阶段、以连接关系呈现数据流向的专项可视化技术,其核心原理在于‘宽即量、位即序、连即逻辑’。它并非装饰性图表,而是面向业务诊断的分析前置工具,尤其适用于预算分配、能源损耗、用户转化等存在明确单向流动与显著数值差异的场景。相比传统柱状图或漏斗图,桑基图能天然暴露系统瓶颈与隐性损耗,大幅提升决策效率。本文聚焦工程落地,覆盖Excel插件快速交付、Python Plotly交互开发、R networkD3生态集成三大主流路径,兼顾数据准备铁律、索引映射规范与中文

cuml0912的博客 488

06-esp32-idf开发调试方法(内置JTAG,OpenOCD调试)

使用VS Code和ESP-IDF进行ESP32开发和调试 在我们搭建 **IDF** 框架后,**OpenOCD** 已经自动下载好了, 我们通过 **JTAG** 接口连接使用 **OpenOCD** 进行调试。而**ESP32**芯片中内置 了**JTAG** 电路,无需额外芯片即可调试,更加方便,所以这里我们讲解使用模块自带的usb-jtag接口进行调试。

宁子希的博客 1万+
上一篇: iOS 右滑返回失效问题终极解决方案
下一篇: 微信小程序中使用npm过程中提示:npm WARN saveError ENOENT: no such file or directory
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值