2013-04-01 24 views
1

我一直在玩CoreBluetooth周圍很多最近,雖然我可以連接到一些設備,我似乎從來沒有能夠正確讀取數據(特徵值)。如何使CoreBluetooth數據的意義

現在我與嗬BT心率監視器連接,和我得到的所有信號,但我不能讓數據變成什麼明智的。 (是的,我知道有一個API,但我試圖在沒有它的情況下連接,以便正確使用CoreBluetooth)。

我迄今未能打開NSData的(characteristic.value)到什麼明智的。如果您對如何理解這些非常令人興奮的數據有任何建議。

+0

實際規格我寫相同的代碼通過@Brabbeldas給出。它與Apple的心率監視器示例代碼中給出的代碼相同。它對我來說工作得很好。請看看它。 – ViruMax

回答

2

下面的代碼完全解析所有的HeartRate測量特徵數據。

如何處理數據取決於幾個因素:

  • 是BPM寫入或兩個單字節?
  • 有EE數據存在嗎?
  • 計算RR間隔值的數量,因爲在一條消息中可能有多個值(我見過最多三個)。

這裏的Heart_rate_measurement characteristic

// Instance method to get the heart rate BPM information 
- (void) getHeartBPMData:(CBCharacteristic *)characteristic error:(NSError *)error 
{ 
    // Get the BPM // 
    // https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.heart_rate_measurement.xml // 

    // Convert the contents of the characteristic value to a data-object // 
    NSData *data = [characteristic value]; 

    // Get the byte sequence of the data-object // 
    const uint8_t *reportData = [data bytes]; 

    // Initialise the offset variable // 
    NSUInteger offset = 1; 
    // Initialise the bpm variable // 
    uint16_t bpm = 0; 


    // Next, obtain the first byte at index 0 in the array as defined by reportData[0] and mask out all but the 1st bit // 
    // The result returned will either be 0, which means that the 2nd bit is not set, or 1 if it is set // 
    // If the 2nd bit is not set, retrieve the BPM value at the second byte location at index 1 in the array // 
    if ((reportData[0] & 0x01) == 0) { 
     // Retrieve the BPM value for the Heart Rate Monitor 
     bpm = reportData[1]; 

     offset = offset + 1; // Plus 1 byte // 
    } 
    else { 
     // If the second bit is set, retrieve the BPM value at second byte location at index 1 in the array and // 
     // convert this to a 16-bit value based on the host’s native byte order // 
     bpm = CFSwapInt16LittleToHost(*(uint16_t *)(&reportData[1])); 

     offset = offset + 2; // Plus 2 bytes // 
    } 
    NSLog(@"bpm: %i", bpm); 



    // Determine if EE data is present // 
    // If the 3rd bit of the first byte is 1 this means there is EE data // 
    // If so, increase offset with 2 bytes // 
    if ((reportData[0] & 0x03) == 1) { 
     offset = offset + 2; // Plus 2 bytes // 
    } 



    // Determine if RR-interval data is present // 
    // If the 4th bit of the first byte is 1 this means there is RR data // 
    if ((reportData[0] & 0x04) == 0) 
    { 
     NSLog(@"%@", @"Data are not present"); 
    } 
    else 
    { 
     // The number of RR-interval values is total bytes left/2 (size of uint16) // 

     NSUInteger length = [data length]; 
     NSUInteger count = (length - offset)/2; 
     NSLog(@"RR count: %lu", (unsigned long)count); 

     for (int i = 0; i < count; i++) { 

      // The unit for RR interval is 1/1024 seconds // 
      uint16_t value = CFSwapInt16LittleToHost(*(uint16_t *)(&reportData[offset])); 
      value = ((double)value/1024.0) * 1000.0; 

      offset = offset + 2; // Plus 2 bytes // 

      NSLog(@"RR value %lu: %u", (unsigned long)i, value); 

     } 

    } 

} 
0

嗯... 你必須做什麼,當你閱讀的characteric值:
NSData *data = [characteritic value]; theTypeOfTheData value; [data getByte:&value lenght:sizeof(value)];
但是,theTypeOfTheData可不管已經想到了設備的開發。因此,它可能是UInt8,UInt16或結構(有或沒有位域)...您必須通過聯繫設備的開發人員或查看是否有一些文檔來獲取信息。
例如,我的同事,我們使用的是消耗更少的空間根據什麼需要(因爲該設備還沒有無限內存)中的數據的類型。 研究特徵的描述符。它可能會指出數據的類型。

1

那麼,你應該實施心率檔案(見here),它使用心率服務。如果您查看Heart Rate Service Specifications,您會看到Heart Rate Measurement Characteristic的格式根據數據包的最低有效八位位組中設置的標誌而變化。

這意味着您需要設置您的代碼來處理動態數據包大小。

所以你的一般過程是:

  1. 獲取value屬性的第一個字節,並檢查它的:
    • 是心臟率測量8位或16位?
    • 是否支持傳感器觸點?
    • 是否檢測到傳感器接觸?
    • 能源消耗是否受到支持?
    • 是否支持RR間隔測量?
  2. 如果心率測量值是8位(字節0的位0爲0),則將下一個字節轉換爲其預期格式(提示:它是uint8_t)。如果它是16位(即字節0的位0是1),則將接下來的兩個字節轉換爲uint16_t。
  3. 如果支持Energy Expended(字節0的位3爲1),則將下一個字節轉換爲uint16_t。
  4. 與RR間隔相同。

使用NSData - 特別是使用核心藍牙 - 需要一些習慣,但一旦掌握了這個概念,並不是那麼糟糕。

祝你好運!

相關問題