蓝牙连接以及协议数据解析

1.声明属性以及引入相关库

NSMutableArray *pers;//这个必须有,用于记录搜索到的设备,没有导致连接不上

manager = [[CBCentralManager alloc]initWithDelegate:self queue:dispatch_get_main_queue()];


2.代理方法

-(void)centralManagerDidUpdateState:(CBCentralManager *)central{

switch (central.state) {

case CBCentralManagerStateUnknown:

NSLog(@">>>CBCentralManagerStateUnknown");

break;

case CBCentralManagerStateResetting:

NSLog(@">>>CBCentralManagerStateResetting");

break;

case CBCentralManagerStateUnsupported:

NSLog(@">>>CBCentralManagerStateUnsupported");

break;

case CBCentralManagerStateUnauthorized:

NSLog(@">>>CBCentralManagerStateUnauthorized");

break;

case CBCentralManagerStatePoweredOff:

NSLog(@">>>CBCentralManagerStatePoweredOff");

break;

case CBCentralManagerStatePoweredOn:{

NSLog(@">>>CBCentralManagerStatePoweredOn");

//开始扫描周围的外设

/*

第一个参数nil就是扫描周围所有的外设,扫描到外设后会进入

- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI;

*/

//            NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber  numberWithBool:YES], CBCentralManagerScanOptionAllowDuplicatesKey, nil];

[manager scanForPeripheralsWithServices:nil options:nil];

hudView.hidden=NO;

hudView.contentLab.text=@"开始扫描设备";

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

hudView.hidden=YES;

});

[manager scanForPeripheralsWithServices:nil options:nil];

break;

}

default:

break;

}

}

//扫描到设备会进入方法

-(void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI{

NSLog(@"当扫描到设备:%@",peripheral.name);

//    [peripherals addObject:peripheral];

//    [tableview reloadData];

//接下来可以连接设备

// 这个是我的设备名,根据实际情况,修改

if ([peripheral.name hasPrefix:@"ABG"]){

/*

一个主设备最多能连7个外设,每个外设最多只能给一个主设备连接,连接成功,失败,断开会进入各自的委托

- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral;//连接外设成功的委托

- (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error;//外设连接失败的委托

- (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error;//断开外设的委托

*/

//找到的设备必须持有它,否则CBCentralManager中也不会保存peripheral,那么CBPeripheralDelegate中的方法也不会被调用!!

manager.delegate=self;

[pers addObject:peripheral];

self.per=peripheral;

//连接设备

[manager connectPeripheral:peripheral options:nil];

hudView.hidden=NO;

hudView.contentLab.text=[NSString stringWithFormat:@"扫描到设备%@,并开始连接",peripheral.name];

}

}

//连接到Peripherals-成功

- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral

{

NSLog(@">>>连接到名称为(%@)的设备-成功",peripheral.name);

//设置的peripheral委托CBPeripheralDelegate

//@interface ViewController : UIViewController

[peripheral setDelegate:self];

//扫描外设Services,成功后会进入方法:-(void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error{

[peripheral discoverServices:nil];

//    self.nameLab.text=peripheral.name;

//    self.contactStateLab.text=@"链接中";

hudView.hidden=NO;

hudView.contentLab.text=[NSString stringWithFormat:@"链接设备%@成功,",peripheral.name];

}

//连接到Peripherals-失败

-(void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error

{

NSLog(@">>>连接到名称为(%@)的设备-失败,原因:%@",[peripheral name],[error localizedDescription]);

//自定义的mbprogress

hudView.hidden=NO;

hudView.contentLab.text=[NSString stringWithFormat:@"链接设备%@失败,",peripheral.name];

}

//Peripherals断开连接

- (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error{

NSLog(@">>>外设连接断开连接 %@: %@\n", [peripheral name], [error localizedDescription]);

//    self.contactStateLab.text=@"链接断开";

//这句话确保了能保持连接,断了重新连接

[manager connectPeripheral:peripheral options:nil];

hudView.contentLab.text=[NSString stringWithFormat:@"设备%@链接断开",peripheral.name];

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

hudView.hidden=YES;

});

}

//扫描到Services

-(void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error{

//  NSLog(@">>>扫描到服务:%@",peripheral.services);

if (error)

{

NSLog(@">>>Discovered services for %@ with error: %@", peripheral.name, [error localizedDescription]);

return;

}

for (CBService *service in peripheral.services) {

NSLog(@"%@",service.UUID);

//扫描每个service的Characteristics,扫描到后会进入方法: -(void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error

/这个1808是我的设备的入口,需根据实际改变

if ([service.UUID.UUIDString isEqualToString:@"1808"]) {

[peripheral discoverCharacteristics:nil forService:service];

}

//        if ([service.UUID.UUIDString isEqualToString:@"180A"]) {

//            [peripheral discoverCharacteristics:nil forService:service];

//        }

//        if ([service.UUID.UUIDString isEqualToString:@"180F"]) {

//            [peripheral discoverCharacteristics:nil forService:service];

//        }

}

}

//扫描到Characteristics

-(void) peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error{

NSString *name=[NSString stringWithFormat:@"发现特征的服务:%@ (%@)",service.UUID.data ,service.UUID];

NSLog(@"%@",name);

for (CBCharacteristic *c in service.characteristics) {

//        [self updateLog:[NSString stringWithFormat:@"特征 UUID: %@ (%@)",c.UUID.data,c.UUID]];

NSLog(@"%@",c.UUID);

//        if ([c.UUID isEqual:[CBUUID UUIDWithString:@"FF01"]]) {

////            _writeCharacteristic = c;

//        }

//

if ([c.UUID isEqual:[CBUUID UUIDWithString:@"FFF4"]]) {

chara=c;

[peripheral readValueForCharacteristic:c];

[peripheral setNotifyValue:YES forCharacteristic:c];

}

//        if ([c.UUID isEqual:[CBUUID UUIDWithString:@"FF04"]]) {

//            [peripheral readValueForCharacteristic:c];

//        }

//

//        if ([c.UUID isEqual:[CBUUID UUIDWithString:@"FF05"]]) {

//            [peripheral readValueForCharacteristic:c];

//            [peripheral setNotifyValue:YES forCharacteristic:c];

//        }

//

//        if ([c.UUID isEqual:[CBUUID UUIDWithString:@"FFA1"]]) {

//            [peripheral readRSSI];

//        }

//        [_nCharacteristics addObject:c];

}

}

-(void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error{

//打印出characteristic的UUID和值

//!注意,value的类型是NSData,具体开发时,会根据外设协议制定的方式去解析数据

//该蓝牙协议是返回数值是ascii码

//    NSLog(@"characteristic uuid:%@  value:%@",characteristic.UUID,characteristic.value);

//    NSData * data = characteristic.value;

//    //将接收到的十六进制数据 转成 十六进制字符串

//    Byte *byte    = (Byte *)[data bytes];

//    // 取出其中用用的两位

//    Byte b[]      = {byte[1],byte[2]};

//    // 在转化成NSData

//    NSData *adata = [[NSData alloc] initWithBytes:b length:sizeof(b)];

//    NSLog(@"adata = %@", adata);

//    // 转化成字符串

//    NSString *str = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];

//    NSLog(@"%@",str);

NSData * data = characteristic.value;

Byte * resultByte = (Byte *)[data bytes];

//

for(int i=0;i<[data length];i++){

printf("testByteFF02[%d] = %d\n",i,resultByte[i]);

//        NSString *string = [NSString stringWithFormat:@"%c",resultByte[i]];

//        printf("testByteFF02[%d] = %@\n",i,string);

if (resultByte[3]==0x00&&resultByte[4]==0x00&&resultByte[5]==0x00&&resultByte[6]==0x01) {

NSLog(@"停止测试");

hudView.hidden=NO;

hudView.contentLab.text=@"停止测量";

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

hudView.hidden=YES;

});

}

if (resultByte[7]==0xcf) {

NSLog(@"停止测试");

hudView.hidden=NO;

hudView.contentLab.text=@"停止测量";

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

hudView.hidden=YES;

});

}

int asc=resultByte[i];

if (asc==0xfe) {

int num;

if (resultByte[2]==0) {

num=resultByte[1];

}else{

num=resultByte[2];

}

NSString *aString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];

NSLog(@"测量中,当前值:%d",num);

if(num!=254){

hudView.hidden=NO;

hudView.contentLab.text=[NSString stringWithFormat:@"当前测量值%d",num];

}

//            self.textview.text=[NSString stringWithFormat:@"测量中,当前值:%d",num];

}

if (asc==0xfd) {

//            Byte  byte1=resultByte[2];

//            int num1=[self hBytesToInt:];

[manager cancelPeripheralConnection:peripheral];

UInt16 asc1=resultByte[3];

UInt16 asc2=resultByte[4];

NSString *str= [NSString stringWithFormat:@"%c%c",asc2,asc1];

NSString *num= [NSString stringWithFormat:@"%ld",strtoul([str UTF8String],0,16)];

//            NSLog(@"测量结束,收缩压%@",str);

NSLog(@"测量结束,收缩压%@",num);

UInt16 asc3=resultByte[5];

UInt16 asc4=resultByte[6];

NSString *str2= [NSString stringWithFormat:@"%c%c",asc4,asc3];

NSString *num2= [NSString stringWithFormat:@"%ld",strtoul([str2 UTF8String],0,16)];

//            NSLog(@"测量结束,收缩压%@",str);

NSLog(@"测量结束,舒张压%@",num2);

UInt16 asc5=resultByte[7];

UInt16 asc6=resultByte[8];

NSString *str3= [NSString stringWithFormat:@"%c%c",asc6,asc5];

NSString *num3= [NSString stringWithFormat:@"%ld",strtoul([str3 UTF8String],0,16)];

//            NSLog(@"测量结束,收缩压%@",str);

if ([num isEqualToString:@"0"]||[num2 isEqualToString:@"0"]||[num3 isEqualToString:@"0"]) {

hudView.hidden=NO;

hudView.contentLab.text=@"测量异常";

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

hudView.hidden=YES;

});

return;

}

if ([num isEqualToString:hasGaoya]&&[num2 isEqualToString:hasDiya]&&[num3 isEqualToString:hasXinglu]) {

return;

}else{

hasGaoya=num;

hasDiya=num2;

hasXinglu=num3;

hudView.hidden=NO;

hudView.contentLab.text=[NSString stringWithFormat:@"测量结束,高压:%@;低压:%@,心率:%@",num,num2,num3];

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

hudView.hidden=YES;

});

NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];

HomeBloodSCell *bloodScell=[mytab cellForRowAtIndexPath:indexPath];

bloodScell.gaoyaLab.text=num;

bloodScell.diyaLab.text=num2;

bloodScell.xingluLab.text=num3;

NSLog(@"测量结束,心率%@",num3);

SelfDataModel *selfdata=[SelfDataModel returnModelBySelectFMDB];

NSDate *date=[NSDate date];

NSDateFormatter *form=[[NSDateFormatter alloc]init];

[form setDateFormat:@"YYYY-MM-dd HH:mm:ss"];

NSString *datestr=[form stringFromDate:date ];

NSString *url=[[HJInterfaceManager sharedInstance]uploadXueya];

NSMutableDictionary *mdic=[[NSMutableDictionary alloc]init];

mdic[@"userId"]=selfdata.idNum;

mdic[@"dbp"]=num2;

mdic[@"sbp"]=num;

mdic[@"pulse"]=num3;

mdic[@"measureTime"]=datestr;

[HJHttpManager PostRequestWithUrl:url param:mdic finish:^(NSData *data) {

NSDictionary *dic=(NSDictionary *)data;

if([dic[@"status"] isEqualToString:@"S"]){

[MBProgressHUD showSuccess:@"数据上传成功"];

HomeBloodSCell *cell=[mytab cellForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];

NSString *str=dic[@"value"][@"measurements"];

cell.statusLab.text=str;

if ([str isEqualToString:@"偏低"]) {

cell.statusLab.textColor=[UIColor colorWithHexString:@"2aa764"];

//        self.pointImage.transform=CGAffineTransformMakeRotation(M_PI/6);

}

if ([str isEqualToString:@"理想"]) {

cell.statusLab.textColor=[UIColor colorWithHexString:@"62c342"];

cell.statusImage.transform=CGAffineTransformMakeRotation(M_PI/2-M_PI/6);

}

if ([str isEqualToString:@"正常"]) {

cell.statusLab.textColor=[UIColor colorWithHexString:@"c9e93c"];

cell.statusImage.transform=CGAffineTransformMakeRotation(M_PI/6*5-M_PI/6);

}

if ([str isEqualToString:@"轻度"]) {

cell.statusLab.textColor=[UIColor colorWithHexString:@"ffc102"];

cell.statusImage.transform=CGAffineTransformMakeRotation(M_PI/6*7-M_PI/6);

}

if ([str isEqualToString:@"中度"]) {

cell.statusLab.textColor=[UIColor colorWithHexString:@"f78758"];

cell.statusImage.transform=CGAffineTransformMakeRotation(M_PI/2*3-M_PI/6);

}

if ([str isEqualToString:@"偏高"]) {

cell.statusLab.textColor=[UIColor colorWithHexString:@"e74c3c"];

cell.statusImage.transform=CGAffineTransformMakeRotation(M_PI/6*11-M_PI/6);

}

}else{

[MBProgressHUD showError:dic[@"message"]];

}

CDLog(@"请求成功");

} failed:^(NSError *error) {

[MBProgressHUD showError:@"请求失败"];

}];

}

//            self.textview.text=[NSString stringWithFormat:@"测量结束,收缩压%@\n\n测量结束,舒张压%@\n\n测量结束,心率%@",num,num2,num3];

}

}

//    NSString *productNumber = [reciveString substringWithRange:NSMakeRange(7, 17)];

//    [productDefault setObject:productNumber forKey:@"productNumber"];

//    [productDefault synchronize];

}

//中心读取外设实时数据

- (void)peripheral:(CBPeripheral *)peripheral didUpdateNotificationStateForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error {

if (error) {

NSLog(@"Error changing notification state: %@", error.localizedDescription);

}

// Notification has started

if (characteristic.isNotifying) {

NSString *reciveString = [NSString stringWithFormat:@"%@", [self hexadecimalString:characteristic.value]];

NSUserDefaults *productDefault = [NSUserDefaults standardUserDefaults];

//    NSString *productNumber = [reciveString substringWithRange:NSMakeRange(7, 17)];

[peripheral readValueForCharacteristic:characteristic];

} else { // Notification has stopped

// so disconnect from the peripheral

NSLog(@"Notification stopped on %@.  Disconnecting", characteristic);

//        [self updateLog:[NSString stringWithFormat:@"Notification stopped on %@.  Disconnecting", characteristic]];

[manager cancelPeripheralConnection:peripheral];

}

}

//搜索到Characteristic的Descriptors

-(void)peripheral:(CBPeripheral *)peripheral didDiscoverDescriptorsForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error{

//打印出Characteristic和他的Descriptors

NSLog(@"characteristic uuid:%@",characteristic.UUID);

for (CBDescriptor *d in characteristic.descriptors) {

NSLog(@"Descriptor uuid:%@",d.UUID);

}

}

//获取到Descriptors的值

-(void)peripheral:(CBPeripheral *)peripheral didUpdateValueForDescriptor:(CBDescriptor *)descriptor error:(NSError *)error{

//打印出DescriptorsUUID 和value

//这个descriptor都是对于characteristic的描述,一般都是字符串,所以这里我们转换成字符串去解析

NSLog(@"characteristic uuid:%@  value:%@",[NSString stringWithFormat:@"%@",descriptor.UUID],descriptor.value);

}

#pragma mark 写数据后回调

- (void)peripheral:(CBPeripheral *)peripheral

didWriteValueForCharacteristic:(CBCharacteristic *)characteristic

error:(NSError *)error {

if (error) {

NSLog(@"Error writing characteristic value: %@",

[error localizedDescription]);

return;

}

NSLog(@"写入%@成功",characteristic);

[peripheral readValueForCharacteristic:characteristic];

}

//向设备写入数据让其停止

-(IBAction)stopBtnDown:(id)sender{

//    char byte[] = {0xFD,0xFD,0xFB,0xFB,0x05,0x0C,0x0D,0x0A};

Byte byte[] = {0XFD,0XFD,0XFB,0XFB,0X05,0X0C,0X0D,0X0A};

NSData * data = [NSData dataWithBytes:byte length:8];

[self.per writeValue:data forCharacteristic:chara type:CBCharacteristicWriteWithResponse];

//    NSString *str=@"[0xFD,0xFD,0xFB,0xFB,0x05,0x0C,0x0D,0x0A]";

//    NSData *data=[str dataUsingEncoding:NSUTF8StringEncoding];

//    [self.per writeValue:data forCharacteristic:chara type:CBCharacteristicWriteWithResponse];

}

-(IBAction)showList:(id)sender{

Byte byte[] = {0xFD,0xFD,0x07,0x07,0x07,0x07,0x0D,0x0A};

NSData * data = [NSData dataWithBytes:byte length:8];

[self.per writeValue:data forCharacteristic:chara type:CBCharacteristicWriteWithResponse];

}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,163评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,301评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,089评论 0 352
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,093评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,110评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,079评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,005评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,840评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,278评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,497评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,667评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,394评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,980评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,628评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,796评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,649评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,548评论 2 352

推荐阅读更多精彩内容