偶得一TI Sensor Tag的開發(fā)板,浪費(fèi)了時(shí)間把玩了一把
iOS是client(Central Mode)SensorTag是server(Peripheral Mode)。一直不是特別為毛設(shè)備會(huì)是server,后來看到下面這句才搞清楚:
server is the side where there is data to serve
把玩目的
- 發(fā)現(xiàn)并連接設(shè)備
- 用Notify方式和直接讀取的方式來獲取傳感器的數(shù)據(jù)
- 寫入某個(gè)Characteristic
- OTA更新設(shè)備固件
準(zhǔn)備工作
蘋果官方給出的和藍(lán)牙相關(guān)的開發(fā)文檔
在工程里引入CoreBluetooth.framework
ViewController的類實(shí)現(xiàn)這兩個(gè)Delegate<CBCentralManagerDelegate, CBPeripheralDelegate>
創(chuàng)建 CoreBluetooth Central Manager
_centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
在創(chuàng)建成功后,CBCentralManager會(huì)觸發(fā)回調(diào)函數(shù),在回調(diào)函數(shù)中應(yīng)用程序可以有機(jī)會(huì)處理藍(lán)牙的不同狀態(tài)。
- (void)centralManagerDidUpdateState:(CBCentralManager *)central {
/*
CBCentralManagerStateUnknown = 0,
CBCentralManagerStateResetting,
CBCentralManagerStateUnsupported,
CBCentralManagerStateUnauthorized,
CBCentralManagerStatePoweredOff,
CBCentralManagerStatePoweredOn
*/
if (central.state != CBCentralManagerStatePoweredOn) {
return;
}
[self scan];
}
連接步驟:
- 掃描藍(lán)牙設(shè)備
NSArray *services = @[[CBUUID UUIDWithString:TI_SENSOR_UUID]];
[self.centralManager scanForPeripheralsWithServices:services options:nil];
碰到一個(gè)奇怪的情況,當(dāng)指定一個(gè)Service UUID時(shí),無法發(fā)現(xiàn)包含這個(gè)UUID的外設(shè)。原因是在Sensor Tag的廣播包里沒有包括任何服務(wù)的UUID信息,所以iOS無法找到對(duì)應(yīng)的外設(shè)。
- 連接外設(shè) - 發(fā)現(xiàn)設(shè)備成功后或失敗后,對(duì)應(yīng)的回調(diào)函數(shù)會(huì)被調(diào)用。
- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI{
// 可以在這里根據(jù)廣播包的內(nèi)容來判斷是否是我們想要連接的設(shè)備
if (![localName isEqualToString:@"SensorTag"]) {
return;
}
// RSS值可以用來判斷藍(lán)牙信號(hào)的強(qiáng)弱,對(duì)于有些應(yīng)用場(chǎng)景,可能需要藍(lán)牙信號(hào)足夠強(qiáng)才允許用戶使用
if (RSSI.integerValue < -35) {
return;
}
// 最后可以試圖連接外設(shè)設(shè)備
[self.centralManager connectPeripheral:peripheral options:nil];
}
- 發(fā)現(xiàn)服務(wù) Services - 設(shè)備連接成功或失敗后,對(duì)應(yīng)的回調(diào)函數(shù)也會(huì)被觸發(fā),在回調(diào)函數(shù)中可以進(jìn)一步查詢?cè)谕庠O(shè)設(shè)備上的服務(wù)。
- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral{
// 連接了外設(shè)后,就可以停止掃面設(shè)備了
[self.centralManager stopScan];
// 用來在下一步發(fā)現(xiàn)設(shè)備時(shí)獲得回調(diào)函數(shù)的調(diào)用
peripheral.delegate = self;
// 在此外設(shè)上尋找UUID為TI_SENSOR_TAG_DEVICE_INFO的服務(wù)
NSArray *services = @[[CBUUID UUIDWithString:TI_SENSOR_TAG_DEVICE_INFO]];
[peripheral discoverServices:services];
}
- 發(fā)現(xiàn)特征 Characteristics - 同樣在發(fā)現(xiàn)完設(shè)備上的服務(wù)后,對(duì)應(yīng)的回調(diào)函數(shù)也會(huì)被調(diào)用。
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error
{
if (error) {
NSLog(@"Error discovering services: %@", [error localizedDescription]);
[self cleanup];
return;
}
// 遍歷外設(shè)上所有的服務(wù)
for (CBService *service in peripheral.services) {
NSLog(@"Service UUID:%@ - %@", service.UUID.UUIDString, service.description);
// 可以按照UUID在指定的Service上發(fā)現(xiàn)對(duì)應(yīng)的特征
[peripheral discoverCharacteristics:nil forService:service];
}
}
- 更新特征值 / 通過Notify方式來獲得特征值的變化
// 發(fā)現(xiàn)特征值后被觸發(fā)的回調(diào)函數(shù)
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error {
if (error) {
NSLog(@"Error discovering characteristics: %@", [error localizedDescription]);
[self cleanup];
return;
}
// 遍歷該服務(wù)上的所有特征值
for (CBCharacteristic *characteristic in service.characteristics) {
NSLog(@"Character.UUID: %@ of Service %@-%@", characteristic.UUID, service.description, service.UUID);
// 根據(jù)特征值是否可Notify方式偵聽來對(duì)應(yīng)處理
if (characteristic.isNotifying) {
[peripheral setNotifyValue:YES forCharacteristic:characteristic];
}
else {
[peripheral readValueForCharacteristic:characteristic];
}
}
}
- 讀取數(shù)據(jù) - 直接讀取方式
- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error{}
- 讀取數(shù)據(jù) - Notify方式
- (void)peripheral:(CBPeripheral *)peripheral didUpdateNotificationStateForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error{}
未完待續(xù)