TI Sensor Tag 連iOS

偶得一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];
}

連接步驟:

  1. 掃描藍(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è)。

  1. 連接外設(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];
}
  1. 發(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];
}
  1. 發(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];
    }
}
  1. 更新特征值 / 通過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];
        }
    }
}
  1. 讀取數(shù)據(jù) - 直接讀取方式
- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error{}
  1. 讀取數(shù)據(jù) - Notify方式
- (void)peripheral:(CBPeripheral *)peripheral didUpdateNotificationStateForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error{}

未完待續(xù)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容