CoreBluetooth For Central (8)

CoreBluetooth For Central (8)

前言

從2012年接觸CoreBluetooth至今也蠻長一段時間,不過還是純研究,也沒寫出相關的APP。不過,真正理解BLE溝通是在接觸TI CC2540並撰寫相關的程式,回過頭來又再看看CoreBluetooth整個流程與操作其實已經非常完整也較穩定,未來或許會有幾篇CC2540或BLE的相關心得說明。

RSSI

RSSI是Received Signal Strength Indication的縮寫,也就代表接收的訊號深度(強度),訊號愈好代表連線品質愈好,它的單位是以負值的dBm表示,RSSI愈接近0連線品質愈好,所以-50dBm訊號會比-89dBm來的好。

這篇所要介紹的是如何即時讀取連線中Peripheral的RSSI值,使用方式很簡單,但要配合ReadRSSI與Delegate。

ReadRSSI

每個Pheripheral都會有method ReadRSSI,利用此方式來觸發讀取RSSI的事件後再引發Delegate,當你連線成功後就能執行

[peripheral readRSSI];

告知要進行讀取目前Peripheral的RSSI值,此時會引發Delegate:

iOS 7

- (void)peripheralDidUpdateRSSI:(CBPeripheral *)peripheral error:(NSError *)error {
 NSLog(@"name: %@ RSSI:%@",peripheral.name,peripheral.RSSI);
}

iOS 8 以上

因iOS 8後棄用peripheral中的RSSI method,所以delegate直接回傳該peripheral RSSI值

- (void)peripheral:(CBPeripheral *)peripheral didReadRSSI:(NSNumber *)RSSI error:(nullable NSError *)error {
 NSLog(@"name: %@ RSSI:%@",peripheral.name,RSSI);
}

BluetoothLE-ReadRSSI

CoreBluetooth For Central (7)中的範例BluetoothLE-Interact,將它另存成BluetoothLE-ReadRSSI,並修改內容增加讀取RSSI的功能,RSSI的更新在iOS中最好以超過2秒為單位來執行Timer,在此設定為2秒一次。

設定2秒timeout執行程式

範例中在連線完成後會將peripheral相應存至connectPeripheral變數:

- (void)execReadRSSI:(NSTimer *)timer
{
    [connectPeripheral readRSSI];
}


連線時啟動Timer

避免重覆執行,執行前先將Timer停止

-(void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral {
    :
    :
    :
    :
    //增加設定定時的程式碼
    //initial timer
    [_readRSSITimer invalidate];
    _readRSSITimer = [NSTimer scheduledTimerWithTimeInterval:2.0f target:self selector:@selector(execReadRSSI:) userInfo:nil repeats:YES];
    NSLog(@"readRSSI Timer start");
}

斷線停止Timer

斷線後會引發didDisconnectPeripheral,所以利用此方式將計時器順便停止:

-(void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error {
    NSLog(@"%@",@"disconnect-2");
    [_readRSSITimer invalidate];
}

執行結果

此次要連接的依然是Polar H7心跳表示範,連線成功後按下Scan and Connect後會自行找到周邊後自行連線。

連線成功後就能在Log中看到RSSI訊號值,內容像:

2015-11-18 09:32:59.979 BluetoothLE-ReadRSSI[2596:1682965] name: Polar H7 000607 RSSI:-70

以下為整個連線過程及印出RSSI值的過程:

2015-11-18 09:32:56.565 BluetoothLE-ReadRSSI[2596:1682965] UpdateState:PoweredOn
2015-11-18 09:32:57.868 BluetoothLE-ReadRSSI[2596:1682965] Scan And Connect
2015-11-18 09:32:57.888 BluetoothLE-ReadRSSI[2596:1682965] ---advertisementData--start-
2015-11-18 09:32:57.889 BluetoothLE-ReadRSSI[2596:1682965] peripheral
<CBPeripheral: 0x1563bf30, identifier = 8DC3DD90-0C17-1AB9-90FE-E9130DD07B81, name = Polar H7 000607, state = disconnected>
2015-11-18 09:32:57.889 BluetoothLE-ReadRSSI[2596:1682965] advertisementData
{
    kCBAdvDataIsConnectable = 1;
    kCBAdvDataLocalName = "Polar H7 000607";
    kCBAdvDataManufacturerData = <6b000315 00>;
    kCBAdvDataServiceUUIDs =     (
        "Heart Rate"
    );
    kCBAdvDataTxPowerLevel = 0;
}
2015-11-18 09:32:57.890 BluetoothLE-ReadRSSI[2596:1682965] RSSI
-65
2015-11-18 09:32:57.890 BluetoothLE-ReadRSSI[2596:1682965] ---advertisementData--end-
2015-11-18 09:32:57.890 BluetoothLE-ReadRSSI[2596:1682965] localName:Polar H7 000607
2015-11-18 09:32:57.890 BluetoothLE-ReadRSSI[2596:1682965] stopScan
2015-11-18 09:32:57.891 BluetoothLE-ReadRSSI[2596:1682965] connect to Polar H7 000607
2015-11-18 09:32:57.975 BluetoothLE-ReadRSSI[2596:1682965] connected
2015-11-18 09:32:57.975 BluetoothLE-ReadRSSI[2596:1682965] Connect To Peripheral with name: Polar H7 000607
with UUID:8DC3DD90-0C17-1AB9-90FE-E9130DD07B81
2015-11-18 09:32:57.975 BluetoothLE-ReadRSSI[2596:1682965] readRSSI Timer start
2015-11-18 09:32:58.271 BluetoothLE-ReadRSSI[2596:1682965] didDiscoverServices:
2015-11-18 09:32:58.271 BluetoothLE-ReadRSSI[2596:1682965] ====Polar H7 000607
2015-11-18 09:32:58.272 BluetoothLE-ReadRSSI[2596:1682965] =========== 4 of service for UUID 8DC3DD90-0C17-1AB9-90FE-E9130DD07B81 ===========
2015-11-18 09:32:58.272 BluetoothLE-ReadRSSI[2596:1682965] Service found with UUID: Heart Rate
2015-11-18 09:32:58.273 BluetoothLE-ReadRSSI[2596:1682965] Service found with UUID: Device Information
2015-11-18 09:32:58.273 BluetoothLE-ReadRSSI[2596:1682965] Service found with UUID: Battery
2015-11-18 09:32:58.274 BluetoothLE-ReadRSSI[2596:1682965] Service found with UUID: 6217FF49-AC7B-547E-EECF-016A06970BA9
2015-11-18 09:32:58.331 BluetoothLE-ReadRSSI[2596:1682965] =========== 2 Characteristics of Heart Rate service 
2015-11-18 09:32:58.331 BluetoothLE-ReadRSSI[2596:1682965]  2A37 
2015-11-18 09:32:58.332 BluetoothLE-ReadRSSI[2596:1682965] 找到 心跳測量屬性
2015-11-18 09:32:58.332 BluetoothLE-ReadRSSI[2596:1682965]  2A38 
2015-11-18 09:32:58.333 BluetoothLE-ReadRSSI[2596:1682965] 找到 心跳測量位置屬性 
2015-11-18 09:32:58.333 BluetoothLE-ReadRSSI[2596:1682965] === Finished set notification ===
2015-11-18 09:32:58.570 BluetoothLE-ReadRSSI[2596:1682965] =========== 7 Characteristics of Device Information service 
2015-11-18 09:32:58.571 BluetoothLE-ReadRSSI[2596:1682965]  System ID 
2015-11-18 09:32:58.571 BluetoothLE-ReadRSSI[2596:1682965]  Model Number String 
2015-11-18 09:32:58.572 BluetoothLE-ReadRSSI[2596:1682965]  Serial Number String 
2015-11-18 09:32:58.572 BluetoothLE-ReadRSSI[2596:1682965]  Firmware Revision String 
2015-11-18 09:32:58.572 BluetoothLE-ReadRSSI[2596:1682965]  Hardware Revision String 
2015-11-18 09:32:58.572 BluetoothLE-ReadRSSI[2596:1682965]  Software Revision String 
2015-11-18 09:32:58.572 BluetoothLE-ReadRSSI[2596:1682965]  Manufacturer Name String 
2015-11-18 09:32:58.573 BluetoothLE-ReadRSSI[2596:1682965] === Finished set notification ===
2015-11-18 09:32:58.630 BluetoothLE-ReadRSSI[2596:1682965] =========== 1 Characteristics of Battery service 
2015-11-18 09:32:58.631 BluetoothLE-ReadRSSI[2596:1682965]  Battery Level 
2015-11-18 09:32:58.631 BluetoothLE-ReadRSSI[2596:1682965] === Finished set notification ===
2015-11-18 09:32:58.779 BluetoothLE-ReadRSSI[2596:1682965] =========== 1 Characteristics of 6217FF49-AC7B-547E-EECF-016A06970BA9 service 
2015-11-18 09:32:58.780 BluetoothLE-ReadRSSI[2596:1682965]  6217FF4A-B07D-5DEB-261E-2586752D942E 
2015-11-18 09:32:58.781 BluetoothLE-ReadRSSI[2596:1682965] === Finished set notification ===
2015-11-18 09:32:58.900 BluetoothLE-ReadRSSI[2596:1682965] 0 bpm
2015-11-18 09:32:58.959 BluetoothLE-ReadRSSI[2596:1682965] 位置: 胸部
2015-11-18 09:32:59.919 BluetoothLE-ReadRSSI[2596:1682965] 89 bpm
2015-11-18 09:32:59.979 BluetoothLE-ReadRSSI[2596:1682965] name: Polar H7 000607 RSSI:-70
2015-11-18 09:33:00.909 BluetoothLE-ReadRSSI[2596:1682965] 89 bpm
2015-11-18 09:33:01.929 BluetoothLE-ReadRSSI[2596:1682965] 92 bpm
2015-11-18 09:33:01.978 BluetoothLE-ReadRSSI[2596:1682965] name: Polar H7 000607 RSSI:-71
2015-11-18 09:33:02.950 BluetoothLE-ReadRSSI[2596:1682965] 96 bpm
2015-11-18 09:33:03.940 BluetoothLE-ReadRSSI[2596:1682965] 97 bpm

範例程式

  • 許博均

    你好 我現在利用tableview顯示可連結的藍芽裝置在頁(a)並選取連接 然後想要在按到另一頁(頁b)時顯示讀取的藍芽值 [這是同一個app兩頁] 但是我一離開頁(a)後 藍芽隨即斷線 我的background modes 有勾選uses bluetoothLE accessories & plist 也有打上App communicates using CoreBluetooth 謝謝~~~

    • 主要是你到第二頁時,第一頁您使用的object因為ARC的關系可能不在記憶體中因而自動斷線。

      建議您使用singleton方式實作藍牙部分,有興趣請參考

      https://github.com/danny-source/DYCoreBluetoothDemo

      中我實作藍牙BLE的Object

      • 許博均

        感謝你~~~ 我最近有空嘗試後 總算能寫出來 感動得五體投地