<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      iOS CoreBluetooth 框架

       

      1. 發現 心率服務0x180D)和 電池服務0x180F)。

      2. 讀取 電池電量特征值0x2A19)。

      3.讀取和監聽 心率數據特征值0x2A37),讓設備主動通知 App 心率變化。

       

      1. 掃描 BLE 設備,只搜索支持 心率服務 (0x180D) 的設備。

      2. 連接設備 后,發現 心率服務電池服務 (0x180F)

      3.讀取電池電量 (0x2A19),電池電量是 0-100 的整數。

      4. 監聽心率 (0x2A37)

       ??? 解析 8-bit 或 16-bit 的心率數據。

      ???設備每秒更新心率,主動通知 App。

      5.解析 BLE 數據,并顯示電池電量和心率信息。

      import UIKit
      import CoreBluetooth
      
      class ViewController: UIViewController, CBCentralManagerDelegate, CBPeripheralDelegate {
      
          var centralManager: CBCentralManager!
          var heartRatePeripheral: CBPeripheral?
      
          // 心率和電池服務 & 特征值 UUID
          let heartRateServiceUUID = CBUUID(string: "180D")   // 心率服務
          let heartRateCharacteristicUUID = CBUUID(string: "2A37")  // 心率數據特征值
          let batteryServiceUUID = CBUUID(string: "180F")  // 電池服務
          let batteryCharacteristicUUID = CBUUID(string: "2A19")  // 電池電量特征值
      
          override func viewDidLoad() {
              super.viewDidLoad()
              // 初始化 Bluetooth 中心管理器
              centralManager = CBCentralManager(delegate: self, queue: nil)
          }
      
          // MARK: - CBCentralManagerDelegate
      
          // 1. 檢查藍牙狀態
          func centralManagerDidUpdateState(_ central: CBCentralManager) {
              switch central.state {
              case .unknown:
                  print("藍牙狀態未知")
              case .resetting:
                  print("藍牙正在重置")
              case .unsupported:
                  print("設備不支持藍牙")
              case .unauthorized:
                  print("未授權使用藍牙")
              case .poweredOff:
                  print("藍牙已關閉")
              case .poweredOn:
                  print("藍牙已開啟,開始掃描設備...")
                  centralManager.scanForPeripherals(withServices: [heartRateServiceUUID], options: nil)
              @unknown default:
                  print("未知藍牙狀態")
              }
          }
      
          // 2. 發現 BLE 設備
          func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {
              print("發現設備: \(peripheral.name ?? "未知設備")")
              heartRatePeripheral = peripheral
              heartRatePeripheral?.delegate = self
              centralManager.stopScan()  // 停止掃描,連接設備
              centralManager.connect(peripheral, options: nil)
          }
      
          // 3. 連接設備成功
          func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {
              print("成功連接設備: \(peripheral.name ?? "未知設備")")
              peripheral.discoverServices([heartRateServiceUUID, batteryServiceUUID]) // 發現服務
          }
      
          // MARK: - CBPeripheralDelegate
      
          // 4. 發現服務
          func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) {
              guard let services = peripheral.services else { return }
              for service in services {
                  print("發現服務: \(service.uuid)")
                  if service.uuid == heartRateServiceUUID || service.uuid == batteryServiceUUID {
                      peripheral.discoverCharacteristics(nil, for: service) // 發現特征值
                  }
              }
          }
      
          // 5. 發現特征值
          func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) {
              guard let characteristics = service.characteristics else { return }
              for characteristic in characteristics {
                  print("發現特征值: \(characteristic.uuid)")
                  
                  if characteristic.uuid == batteryCharacteristicUUID {
                      // 讀取電池電量
                      peripheral.readValue(for: characteristic)
                  } else if characteristic.uuid == heartRateCharacteristicUUID {
                      // 監聽心率數據(開啟通知)
                      peripheral.setNotifyValue(true, for: characteristic)
                  }
              }
          }
      
          // 6. 讀取數據(適用于電池電量)
          func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) {
              guard let data = characteristic.value else { return }
      
              if characteristic.uuid == batteryCharacteristicUUID {
                  let batteryLevel = data.first ?? 0
                  print("電池電量: \(batteryLevel)%")
              } else if characteristic.uuid == heartRateCharacteristicUUID {
                  let heartRate = parseHeartRateData(data)
                  print("心率: \(heartRate) BPM")
              }
          }
      
          // 解析心率數據(部分設備用第一個字節標志心率格式)
          private func parseHeartRateData(_ data: Data) -> Int {
              let bytes = [UInt8](data)
              if bytes.first! & 0x01 == 0 {
                  return Int(bytes[1]) // 8-bit 心率值
              } else {
                  return Int(bytes[1]) | (Int(bytes[2]) << 8) // 16-bit 心率值
              }
          }
      
          // 7. 設備主動通知心率變化
          func peripheral(_ peripheral: CBPeripheral, didUpdateNotificationStateFor characteristic: CBCharacteristic, error: Error?) {
              if error != nil {
                  print("設置通知失敗: \(error!.localizedDescription)")
              } else {
                  print("成功開啟心率通知")
              }
          }
      }

       

      藍牙已開啟,開始掃描設備...
      發現設備: MyHeartRateMonitor
      成功連接設備: MyHeartRateMonitor
      發現服務: 180D
      發現服務: 180F
      發現特征值: 2A37
      發現特征值: 2A19
      電池電量: 85%
      成功開啟心率通知
      心率: 72 BPM
      心率: 73 BPM
      心率: 74 BPM
      ...

       

       

      如果你的 BLE 設備 需要 定期主動獲取(輪詢)某個特征值(比如每隔 5 秒讀取一次溫度、血氧等),可以使用 定時器(Timer) 來定期讀取特征值。

      方法 1:使用 Timer 定時讀取

       

      可以使用 Timer.scheduledTimer 每隔 N 秒主動讀取 BLE 設備的特征值:

      查看代碼
       var readTimer: Timer?  // 定時器
      var myPeripheral: CBPeripheral?  // 目標 BLE 設備
      let myCharacteristicUUID = CBUUID(string: "2A19")  // 例如讀取電池電量(0x2A19)
      
      // 啟動定時器,每 5 秒讀取一次特征值
      func startReadingCharacteristic() {
          readTimer?.invalidate()  // 先清除舊定時器
          readTimer = Timer.scheduledTimer(timeInterval: 5.0, target: self, selector: #selector(readCharacteristicValue), userInfo: nil, repeats: true)
      }
      
      // 定時器觸發,讀取特征值
      @objc func readCharacteristicValue() {
          guard let peripheral = myPeripheral,
                let characteristic = findCharacteristic(by: myCharacteristicUUID) else { return }
          
          print("定時讀取特征值: \(characteristic.uuid)")
          peripheral.readValue(for: characteristic)
      }
      
      // 停止定時器
      func stopReadingCharacteristic() {
          readTimer?.invalidate()
          readTimer = nil
      }
      
      // 通過 UUID 查找特征值
      func findCharacteristic(by uuid: CBUUID) -> CBCharacteristic? {
          guard let services = myPeripheral?.services else { return nil }
          for service in services {
              if let characteristic = service.characteristics?.first(where: { $0.uuid == uuid }) {
                  return characteristic
              }
          }
          return nil
      }
      
      // 處理讀取的特征值數據
      func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) {
          if characteristic.uuid == myCharacteristicUUID, let data = characteristic.value {
              let batteryLevel = data.first ?? 0
              print("電池電量: \(batteryLevel)%")
          }
      }

      ? 特點

      ?適用于 BLE 設備不支持 Notify,但你需要定期獲取數據。

      ? 適用于 讀取溫度、血氧、電池等信息

       

      方法 2:使用 DispatchSource 定時讀取

       

      如果你的 BLE 讀取任務運行在 后臺線程,可以使用 DispatchSource 定時讀取:

      查看代碼
       var readTimer: DispatchSourceTimer?
      
      func startReadingCharacteristicWithGCD() {
          readTimer = DispatchSource.makeTimerSource(queue: DispatchQueue.global())
          readTimer?.schedule(deadline: .now(), repeating: 5.0)
          readTimer?.setEventHandler {
              DispatchQueue.main.async {
                  self.readCharacteristicValue()
              }
          }
          readTimer?.resume()
      }
      
      func stopReadingCharacteristicWithGCD() {
          readTimer?.cancel()
          readTimer = nil
      }

      ? 特點

      ? 不需要手動定時讀取,BLE 設備主動通知更省電

      ? 適用于心率、步數等動態數據

       

      適用場景

      優點

      缺點

      方法 1: Timer 定時讀取

      設備不支持 Notify,需要手動讀取

      代碼簡單,適用于周期性數據

       

      可能增加功耗

      方法 2: DispatchSource 低功耗定時讀取

       

      后臺任務,低功耗需求

      更省電,適合后臺讀取

      代碼稍復雜

      方法 3: Notify 監聽設備主動推送

       

      設備支持 Notify(心率、步數等)

      最省電,響應快

      需要設備支持

       

      posted on 2025-02-14 16:24  youhui  閱讀(166)  評論(0)    收藏  舉報

      主站蜘蛛池模板: 国产一二三五区不在卡 | 亚洲欧美日韩在线不卡| 一级女性全黄久久生活片| 国产成人不卡一区二区| 男女激情一区二区三区| 久久综合色之久久综合| 国产在线观看免费观看| 久久久久四虎精品免费入口| 西西大胆午夜人体视频| 少妇午夜啪爽嗷嗷叫视频| 日韩一区二区三区av在线| 日本一区二区三区有码视频| 亚洲精品乱码久久久久久中文字幕| 四虎精品永久在线视频| 亚洲精品一区三区三区在| 亚洲欧洲日韩国内精品| 内射老阿姨1区2区3区4区| 国产精品∧v在线观看| 国产一区二区三区四区激情| 日韩精品一区二区三区视频 | 国产欧美久久一区二区| 又粗又紧又湿又爽的视频| 潜江市| 国产美女被遭强高潮免费一视频| 无遮无挡爽爽免费视频| 无码精品人妻一区二区三区湄公河| 国产极品粉嫩尤物一线天| 伊人久久大香线蕉AV网禁呦| 99久久精品国产一区二区蜜芽| 人人妻人人澡人人爽人人精品av | 四虎精品国产精品亚洲精| 亚洲精品国产一区二区三| 国产精品国产三级国快看| 亚洲精品中文字幕码专区| 久久夜色精品国产噜噜亚洲sv| 国产成人综合在线女婷五月99播放| 欧美亚洲一区二区三区在线| 国产激情精品一区二区三区| 国产永久免费高清在线观看| 亚洲精品有码在线观看| 日韩东京热一区二区三区|