首页 > 代码库 > 蓝牙4.0

蓝牙4.0

1.3 实现过程

作为一个中心要实现完整的通讯,一般要经过这样几个步骤:

建立中心角色—扫描外设(discover)—连接外设(connect)—扫描外设中的服务和特征(discover)—与外设做数据交互(explore and interact)—断开连接(disconnect)。

1.3.1 建立中心角色

 

centralManager = [[CBCentralManageralloc]initWithDelegate:selfqueue:nil];

1.3.2 扫描外设

 

[self.centralManagerscanForPeripheralsWithServices:niloptions:nil];

1.3.3  连接外设 

 

//发现蓝牙设备 回调函数

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

1.3.4  扫描外设中的服务和特征(discover)

 

当连接成功后,系统会通过回调函数告诉我们,然后我们就在这个回调里去扫描设备下所有的服务和特征,代码如下:

//连接成功

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

 

// 寻找到服务

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

 

//寻找到特征

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

1.3.5  与外设做数据交互(explore and interact)

 

//写数据

-(void)writeChar:(NSData *)data{}

 

 

数据的读分为两种,一种是直接读(reading directly),另外一种是订阅(subscribe)。

实际使用中具体用一种要看具体的应用场景以及特征本身的属性。前一个好理解,特征本身的属性是指什么呢?特征有个properties字段(characteristic.properties),它是一个整型值,有如下几个定义:

enum {

     CBCharacteristicPropertyBroadcast = 0x01,

     CBCharacteristicPropertyRead = 0x02,

     CBCharacteristicPropertyWriteWithoutResponse =0x04,

     CBCharacteristicPropertyWrite = 0x08,

     CBCharacteristicPropertyNotify = 0x10,

     CBCharacteristicPropertyIndicate = 0x20,

     CBCharacteristicPropertyAuthenticatedSignedWrites =0x40,

     CBCharacteristicPropertyExtendedProperties =0x80,

     };

比如说,你要交互的特征,它的properties的值是0x10,表示你只能用订阅的方式来接收数据。我这里是用订阅的方式,启动订阅的代码如下:

//监听设备

-(void)startSubscribe

{

    [_testPeripheral setNotifyValue:YES forCharacteristic:_readCharacteristic];

}

当设备有数据返回时,同样是通过一个系统回调通知我,如下所示:

 

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

{

    if(error) 

    {

        NSLog(@"Error updating value for characteristic %@ error: %@", characteristic.UUID, [error localizedDescription]);

         

        if([_mainMenuDelegate respondsToSelector:@selector(DidNotifyReadError:)])

            [_mainMenuDelegate DidNotifyReadError:error];

        return;

    }

    [_recvData appendData:characteristic.value];

     

    if([_recvData length] >=5)//已收到长度

    {

        unsigned char*buffer = (unsignedchar*)[_recvData bytes];

        intnLen = buffer[3]*256+ buffer[4];

        if([_recvData length] == (nLen+3+2+2))

        {

            //接收完毕,通知代理做事

            if([_mainMenuDelegate respondsToSelector:@selector(DidNotifyReadData)])

                [_mainMenuDelegate DidNotifyReadData];

        }

    }

}

1.3.6  断开连接(disconnect)

 

//主动断开设备

-(void)disConnect

 

二.  过程:

1.判断状态为powerOn,然后执行扫描 

2.停止扫描,连接外设 

3.连接成功,寻找服务 

4.在服务里寻找特征 

5.为特征添加通知 

5.通知添加成功,那么就可以实时的读取value[也就是说只要外设发送数据[一般外设的频率为10Hz],代理就会调用此方法]。 

6.处理接收到的value,[hex值,得转换] 

蓝牙4.0