藍牙功能

藍牙功能html

 

做爲藍牙中心,鏈接外設ios

通常性的步驟是先掃描設備,而後根據藍牙設備的名稱等信息找到須要鏈接的設備,進行鏈接git

而後獲取設備的服務,能夠訂閱對應的服務,能夠對設備進行寫入github

 

 

//
//  ViewController.m
//  BlueTooth
//
//  Created by JackXu on 15/6/9.
//  Copyright (c) 2015年 BFMobile. All rights reserved.
//

#import "ViewController.h"
#define MyDeviceName @"HMSoft"
@interface ViewController ()

@property (nonatomic, strong) CBCentralManager *centralMgr;
@property (nonatomic, strong) CBPeripheral *discoveredPeripheral;
@property (nonatomic, strong) CBCharacteristic *writeCharacteristic;

@property (nonatomic,strong) CBCharacteristic *testCharacteristic;
@property (weak, nonatomic) IBOutlet UITextField *editText;
@property (weak, nonatomic) IBOutlet UILabel *resultText;

@property (nonatomic,strong) CBPeripheral *smartWatchPeripheral;
@property (nonatomic,strong) NSMutableArray *discoveredPerpheralArray;



@property (nonatomic,strong) CBService *testService;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.centralMgr = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
}

//檢查App的設備BLE是否可用 (ensure that Bluetooth low energy is supported and available to use on the central device)
- (void)centralManagerDidUpdateState:(CBCentralManager *)central
{
    switch (central.state)
    {
        case CBCentralManagerStatePoweredOn:
            //discover what peripheral devices are available for your app to connect to
            //第一個參數爲CBUUID的數組,須要搜索特色服務的藍牙設備,只要每搜索到一個符合條件的藍牙設備都會調用didDiscoverPeripheral代理方法
            [self.centralMgr scanForPeripheralsWithServices:nil options:nil];
            break;
        default:
            NSLog(@"Central Manager did change state");
            break;
    }
}

- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI
{
    NSLog(@"peripheral == %@ rssi == %@",peripheral,RSSI);
    //找到須要的藍牙設備,中止搜素,保存數據
    if([peripheral.name isEqualToString:MyDeviceName]){
        _discoveredPeripheral = peripheral;
        [_centralMgr connectPeripheral:peripheral options:nil];
    }
    
    for ( CBPeripheral *savedPeripheral in self.discoveredPerpheralArray) {
        if (![[savedPeripheral.identifier UUIDString] isEqualToString:[peripheral.identifier UUIDString]]) {
            
//            self.discoveredPerpheralArray 
            
            
        }
    }
    
    NSString *peripheralName = peripheral.name;
    NSRange wannaFitLocation = [peripheralName rangeOfString:@"WannaFit"];
    if (wannaFitLocation.location != NSNotFound){
        self.smartWatchPeripheral = peripheral;
        [_centralMgr connectPeripheral:peripheral options:nil];
    
    }
    
    
}

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

    NSLog(@"didDisconnectPeripheral %s",__FUNCTION__);
}

//鏈接成功
- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral
{
    
    NSLog(@"didConnectPeripheral %s",__FUNCTION__);
    //Before you begin interacting with the peripheral, you should set the peripheral’s delegate to ensure that it receives the appropriate callbacks(設置代理)
    [_discoveredPeripheral setDelegate:self];
    //discover all of the services that a peripheral offers,搜索服務,回調didDiscoverServices
    [_discoveredPeripheral discoverServices:nil];
    
    [self.smartWatchPeripheral setDelegate:self];
    
    [self.smartWatchPeripheral discoverServices:nil];
}

//鏈接失敗,就會獲得回調:
- (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error{
    //此時鏈接發生錯誤
    NSLog(@"connected periphheral failed");
}

//獲取服務後的回調
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error
{
    if (error)
    {
        NSLog(@"didDiscoverServices : %@", [error localizedDescription]);
        return;
    }
    
    for (CBService *s in peripheral.services)
    {
        NSLog(@"Service found with UUID : %@", s.UUID);
        //Discovering all of the characteristics of a service,回調didDiscoverCharacteristicsForService
        [s.peripheral discoverCharacteristics:nil forService:s];
    }
}

//獲取特徵後的回調
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error{
    if (error)
    {
        NSLog(@"didDiscoverCharacteristicsForService error : %@", [error localizedDescription]);
        return;
    }
    
    NSLog(@"service == %@",service);
    
    for (CBCharacteristic *c in service.characteristics)
    {
        NSLog(@"c.properties:%lu",(unsigned long)c.properties) ;
        //Subscribing to a Characteristic’s Value 訂閱
        
        NSLog(@"characteristic == %@",c);
        [peripheral setNotifyValue:YES forCharacteristic:c];
        // read the characteristic’s value,回調didUpdateValueForCharacteristic
        [peripheral readValueForCharacteristic:c];
        _writeCharacteristic = c;
    }
    
    
    
    

}

//訂閱的特徵值有新的數據時回調
- (void)peripheral:(CBPeripheral *)peripheral
didUpdateNotificationStateForCharacteristic:(CBCharacteristic *)characteristic
             error:(NSError *)error {
    if (error) {
        NSLog(@"Error changing notification state: %@",
              [error localizedDescription]);
    }
    
    [peripheral readValueForCharacteristic:characteristic];

}

- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
{
    
    NSLog(@"characteristic value == %@",characteristic.value);
    
    if (error)
    {
        NSLog(@"didUpdateValueForCharacteristic error : %@", error.localizedDescription);
        return;
    }
    
    NSData *data = characteristic.value;
    _resultText.text = [[ NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    NSLog(@"characteristic properties == %lu value == %@ ",(unsigned long)characteristic.properties,characteristic.value);
    
//    NSLog(@"hex string == %@",[self convertDataToHexStr:data]);
//    
//
    
     

    
    
}



- (NSMutableArray *)discoveredPerpheralArray{
    if (!_discoveredPerpheralArray) {
        _discoveredPerpheralArray = [NSMutableArray array];
    }
    return _discoveredPerpheralArray;

}

#pragma mark 寫數據
-(void)writeChar:(NSData *)data
{
    //回調didWriteValueForCharacteristic
    [_discoveredPeripheral writeValue:data forCharacteristic:_writeCharacteristic type:CBCharacteristicWriteWithoutResponse];
    
    
    NSData *data2 = [self test2Data];
    
    NSLog(@"data2 == %@",data2);
    
    for (CBService *service in self.smartWatchPeripheral.services) {
        
        
        for (CBCharacteristic *characteristic in service.characteristics) {
            
            
            [self.smartWatchPeripheral writeValue:data2  forCharacteristic:characteristic type:CBCharacteristicWriteWithoutResponse];
            
            [self.smartWatchPeripheral writeValue:data2 forCharacteristic:characteristic type:CBCharacteristicWriteWithResponse];
            
        }
    }
   
    
}


//搜索到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);
}

#pragma mark 發送按鈕點擊事件
- (IBAction)sendClick:(id)sender {
    // 字符串轉Data
    NSData *data =[_editText.text dataUsingEncoding:NSUTF8StringEncoding];
    [self writeChar:data];
}


- (NSString *)convertDataToHexStr:(NSData *)data {
    if (!data || [data length] == 0) {
        return @"";
    }
    NSMutableString *string = [[NSMutableString alloc] initWithCapacity:[data length]];
    
    [data enumerateByteRangesUsingBlock:^(const void *bytes, NSRange byteRange, BOOL *stop) {
        unsigned char *dataBytes = (unsigned char*)bytes;
        for (NSInteger i = 0; i < byteRange.length; i++) {
            NSString *hexStr = [NSString stringWithFormat:@"%x", (dataBytes[i]) & 0xff];
            if ([hexStr length] == 2) {
                [string appendString:hexStr];
            } else {
                [string appendFormat:@"0%@", hexStr];
            }
        }
    }];
    
    return string;
}

- (NSData *)convertHexStrToData:(NSString *)str {
    if (!str || [str length] == 0) {
        return nil;
    }
    
    NSMutableData *hexData = [[NSMutableData alloc] initWithCapacity:8];
    NSRange range;
    if ([str length] % 2 == 0) {
        range = NSMakeRange(0, 2);
    } else {
        range = NSMakeRange(0, 1);
    }
    for (NSInteger i = range.location; i < [str length]; i += 2) {
        unsigned int anInt;
        NSString *hexCharStr = [str substringWithRange:range];
        NSScanner *scanner = [[NSScanner alloc] initWithString:hexCharStr];
        
        [scanner scanHexInt:&anInt];
        NSData *entity = [[NSData alloc] initWithBytes:&anInt length:1];
        [hexData appendData:entity];
        
        range.location += range.length;
        range.length = 2;
    }
    
    return hexData;
}

- (NSData *)test1Data{

    Byte bytes[20] = {0x89,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9A};
    
    NSData *data2 =  [NSData dataWithBytes:bytes length:20];
    return data2;

}
- (NSData *)test2Data{
    
    Byte bytes[20] = {0xA5,0x11,0x00,0x00,0x02,0x0A,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC2};
    
    NSData *data2 =  [NSData dataWithBytes:bytes length:20];
    return data2;
    
}




- (NSData *)setWatchTime{

    Byte bytes[10] = {0x08,0x14,0x0e,0x0a,0x1f,0x0f,0x38,0x1e,0x01,0x00};
    Byte resultByte = 0x00;
    
    for (int i = 0; i<9; i++) {
        
        resultByte += bytes[i];
    }
    NSLog(@"result bye == %x",resultByte);
    resultByte = resultByte & 0xff;
    NSLog(@"result bye == %x",resultByte);
    bytes[9] = resultByte;
    
    
    
    NSData *data2 =  [NSData dataWithBytes:bytes length:10];
    
    NSLog(@"data2 == %@",data2);
    
    return data2;

}

- (NSData *)getWatchInfo{

    Byte bytes[10] = {0xF6,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00};
    Byte resultByte = 0x00;
    
    for (int i = 0; i<9; i++) {
        
        resultByte += bytes[i];
    }
    NSLog(@"result bye == %x",resultByte);
    resultByte = resultByte & 0xff;
    NSLog(@"result bye == %x",resultByte);
    bytes[9] = resultByte;
    
    
    
    NSData *data2 =  [NSData dataWithBytes:bytes length:10];
    
    NSLog(@"data2 == %@",data2);
    
    return data2;
}

- (NSData *)findTheWatch{
    
    Byte bytes[10] = {0x0B,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00};
    Byte resultByte = 0x00;
    
    for (int i = 0; i<9; i++) {
        
        resultByte += bytes[i];
    }
    
    resultByte = resultByte & 0xff;
    bytes[9] = resultByte;
    
    
    
    NSData *data2 =  [NSData dataWithBytes:bytes length:10];
    
    NSLog(@"data2 == %@",data2);

    return data2;
}
@end

 

 

做爲藍牙設備數組

#import "BePeripheralViewController.h"



static NSString *const ServiceUUID1 =  @"FFF0";
static NSString *const notiyCharacteristicUUID =  @"FFF1";
static NSString *const readwriteCharacteristicUUID =  @"FFF2";
static NSString *const ServiceUUID2 =  @"FFE0";
static NSString *const readCharacteristicUUID =  @"FFE1";
static NSString *const localTimeUUID = @"Local Time Information";
  
static NSString * const LocalNameKey =  @"WannaFit-T10D-5F29";

@implementation BePeripheralViewController{
    CBPeripheralManager *peripheralManager;
    //定時器
    NSTimer *timer;
    //添加成功的service數量
    int serviceNum;
    UILabel *info;
   
}
- (void)viewDidLoad {
    [super viewDidLoad];
    /*
     和CBCentralManager相似,藍牙設備打開須要必定時間,打開成功後會進入委託方法
     - (void)peripheralManagerDidUpdateState:(CBPeripheralManager *)peripheral;
     模擬器永遠也不會得CBPeripheralManagerStatePoweredOn狀態
     */
    peripheralManager = [[CBPeripheralManager alloc]initWithDelegate:self queue:nil];
   
    //頁面樣式
    [self.view setBackgroundColor:[UIColor whiteColor]];
    info = [[UILabel alloc]initWithFrame:self.view.frame];
    [info setText:@"正在打開設備"];
    [info setTextAlignment:NSTextAlignmentCenter];
    [self.view addSubview:info];
    
}

- (void)viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear:animated];
    [peripheralManager stopAdvertising];
}



//配置bluetooch的
-(void)setUp{
    //characteristics字段描述
    CBUUID *CBUUIDCharacteristicUserDescriptionStringUUID = [CBUUID UUIDWithString:CBUUIDCharacteristicUserDescriptionString];
    
    /*
     能夠通知的Characteristic
     properties:CBCharacteristicPropertyNotify 
     permissions CBAttributePermissionsReadable
     */
    CBMutableCharacteristic *notiyCharacteristic = [[CBMutableCharacteristic alloc]initWithType:[CBUUID UUIDWithString:notiyCharacteristicUUID] properties:CBCharacteristicPropertyNotify value:nil permissions:CBAttributePermissionsReadable];

    /*
     可讀寫的characteristics
     properties:CBCharacteristicPropertyWrite | CBCharacteristicPropertyRead
     permissions CBAttributePermissionsReadable | CBAttributePermissionsWriteable
     */
    CBMutableCharacteristic *readwriteCharacteristic = [[CBMutableCharacteristic alloc]initWithType:[CBUUID UUIDWithString:readwriteCharacteristicUUID] properties:CBCharacteristicPropertyWrite | CBCharacteristicPropertyRead value:nil permissions:CBAttributePermissionsReadable | CBAttributePermissionsWriteable];
    //設置description
    CBMutableDescriptor *readwriteCharacteristicDescription1 = [[CBMutableDescriptor alloc]initWithType: CBUUIDCharacteristicUserDescriptionStringUUID value:@"name"];
    [readwriteCharacteristic setDescriptors:@[readwriteCharacteristicDescription1]];
    

    /*
     只讀的Characteristic
     properties:CBCharacteristicPropertyRead
     permissions CBAttributePermissionsReadable
     */
    CBMutableCharacteristic *readCharacteristic = [[CBMutableCharacteristic alloc]initWithType:[CBUUID UUIDWithString:readCharacteristicUUID] properties:CBCharacteristicPropertyRead value:nil permissions:CBAttributePermissionsReadable];

    
    //service1初始化並加入兩個characteristics
    CBMutableService *service1 = [[CBMutableService alloc]initWithType:[CBUUID UUIDWithString:ServiceUUID1] primary:YES];
    NSLog(@"%@",service1.UUID);
    
    [service1 setCharacteristics:@[notiyCharacteristic,readwriteCharacteristic]];
    
    //service2初始化並加入一個characteristics
    CBMutableService *service2 = [[CBMutableService alloc]initWithType:[CBUUID UUIDWithString:ServiceUUID2] primary:YES];
    [service2 setCharacteristics:@[readCharacteristic]];
    
    //添加後就會調用代理的- (void)peripheralManager:(CBPeripheralManager *)peripheral didAddService:(CBService *)service error:(NSError *)error
    [peripheralManager addService:service1];
    [peripheralManager addService:service2];
}




#pragma  mark -- CBPeripheralManagerDelegate

//peripheralManager狀態改變
- (void)peripheralManagerDidUpdateState:(CBPeripheralManager *)peripheral{
    switch (peripheral.state) {
            //在這裏判斷藍牙設別的狀態  當開啓了則可調用  setUp方法(自定義)
        case CBPeripheralManagerStatePoweredOn:
            NSLog(@"powered on");
            [info setText:[NSString stringWithFormat:@"設備名%@已經打開,能夠使用center進行鏈接",LocalNameKey]];
            [self setUp];
            break;
        case CBPeripheralManagerStatePoweredOff:
            NSLog(@"powered off");
            [info setText:@"powered off"];
            break;
            
        default:
            break;
    }
}

//perihpheral添加了service
- (void)peripheralManager:(CBPeripheralManager *)peripheral didAddService:(CBService *)service error:(NSError *)error{
    if (error == nil) {
        serviceNum++;
    }

    //由於咱們添加了2個服務,因此想兩次都添加完成後纔去發送廣播
    if (serviceNum==2) {
        //添加服務後能夠在此向外界發出通告 調用完這個方法後會調用代理的
        //(void)peripheralManagerDidStartAdvertising:(CBPeripheralManager *)peripheral error:(NSError *)error
        [peripheralManager startAdvertising:@{
                                              CBAdvertisementDataServiceUUIDsKey : @[[CBUUID UUIDWithString:ServiceUUID1],[CBUUID UUIDWithString:ServiceUUID2]],
                                              CBAdvertisementDataLocalNameKey : LocalNameKey
                                             }
         ];
        
    }
    
}

//peripheral開始發送advertising
- (void)peripheralManagerDidStartAdvertising:(CBPeripheralManager *)peripheral error:(NSError *)error{
    NSLog(@"in peripheralManagerDidStartAdvertisiong");
}

//訂閱characteristics
-(void)peripheralManager:(CBPeripheralManager *)peripheral central:(CBCentral *)central didSubscribeToCharacteristic:(CBCharacteristic *)characteristic{
    NSLog(@"訂閱了 %@的數據",characteristic.UUID);
    //每秒執行一次給主設備發送一個當前時間的秒數
    timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(sendData:) userInfo:characteristic  repeats:YES];
}

//取消訂閱characteristics
-(void)peripheralManager:(CBPeripheralManager *)peripheral central:(CBCentral *)central didUnsubscribeFromCharacteristic:(CBCharacteristic *)characteristic{
    NSLog(@"取消訂閱 %@的數據",characteristic.UUID);
    //取消迴應
    [timer invalidate];
}

//發送數據,發送當前時間的秒數
-(BOOL)sendData:(NSTimer *)t {
    CBMutableCharacteristic *characteristic = t.userInfo;
    NSDateFormatter *dft = [[NSDateFormatter alloc]init];
    [dft setDateFormat:@"ss"];
    NSLog(@"%@",[dft stringFromDate:[NSDate date]]);
    
    //執行迴應Central通知數據
    return  [peripheralManager updateValue:[[dft stringFromDate:[NSDate date]] dataUsingEncoding:NSUTF8StringEncoding] forCharacteristic:(CBMutableCharacteristic *)characteristic onSubscribedCentrals:nil];
    
}


//讀characteristics請求
- (void)peripheralManager:(CBPeripheralManager *)peripheral didReceiveReadRequest:(CBATTRequest *)request{
    NSLog(@"didReceiveReadRequest");
    NSLog(@"request == %@ request.value == %@",request,request.value);
    //判斷是否有讀數據的權限
    if (request.characteristic.properties & CBCharacteristicPropertyRead) {
        NSData *data = request.characteristic.value;
        [request setValue:data];
        //對請求做出成功響應
        [peripheralManager respondToRequest:request withResult:CBATTErrorSuccess];
    }else{
        [peripheralManager respondToRequest:request withResult:CBATTErrorWriteNotPermitted];
    }
}


//寫characteristics請求
- (void)peripheralManager:(CBPeripheralManager *)peripheral didReceiveWriteRequests:(NSArray *)requests{
    NSLog(@"didReceiveWriteRequests");
    CBATTRequest *request = requests[0];
    
    //判斷是否有寫數據的權限
    if (request.characteristic.properties & CBCharacteristicPropertyWrite) {
        //須要轉換成CBMutableCharacteristic對象才能進行寫值
        CBMutableCharacteristic *c =(CBMutableCharacteristic *)request.characteristic;
        c.value = request.value;
        [peripheralManager respondToRequest:request withResult:CBATTErrorSuccess];
    }else{
        [peripheralManager respondToRequest:request withResult:CBATTErrorWriteNotPermitted];
    }
    
    
}

//
- (void)peripheralManagerIsReadyToUpdateSubscribers:(CBPeripheralManager *)peripheral{
    NSLog(@"peripheralManagerIsReadyToUpdateSubscribers");
    
}


@end

 

更進一步的藍牙功能app

https://my.oschina.net/u/2340880/blog/644432ide

https://github.com/ZYHshao/BlueGameui

 

參考資料atom

iOS簡易藍牙對戰五子棋遊戲設計思路之一——核心藍牙通信類的設計.net

https://my.oschina.net/u/2340880/blog/644432

 

ios藍牙開發(二)ios鏈接外設的代碼實現

http://liuyanwei.jumppo.com/2015/08/14/ios-BLE-2.html

 

iOS-BLE藍牙開發持續更新

http://www.jianshu.com/p/84b5b834b942

 

劉彥瑋的技術博客中文章對應的demo http://liuyanwei.jumppo.com http://liuyanwei.jumppo.com

https://github.com/coolnameismy/demo

相關文章
相關標籤/搜索