Core Bluetooth - 与 LED 灯通信

Core Bluetooth - Communicate with LED Light

我正在研究与 LED 灯通信的 Core Bluetooth。当外围设备将值写入通信时,需要一些时间才能获得硬件(LED)的响应。由于我们使用 UISLider 写入值,因此我们面临硬件延迟。我认为每当我们快速移动滑块时就会出现队列。我该如何解决这个延迟问题?

    let slider0:UInt8 = UInt8(sliderBrightness.value) // Brightness
    let slider1:UInt8 = UInt8(mode) // Mode
    let slider2:UInt8 = UInt8(sliderDirection.value) // Direction
    let slider3:UInt8 = UInt8(sliderStrength.value) // Strength
    let slider4:UInt8 = UInt8(sliderWhite.value) // Neutral LED Dimming
    let slider5:UInt8 = UInt8(sliderOrange.value) // Warm LED Dimming
    let slider6:UInt8 = UInt8(mode == 3 ? sliderOrbit.value : sliderOnTime.value)  // According to Mode
    let slider7:UInt8 = UInt8(sliderOffTime.value) // According to Mode
    let slider8:UInt8 = UInt8(255)
    let buff: [UInt8] = [slider0,slider1,slider2,slider3,slider4,slider5,slider6,slider7,slider8]
    
    let data = Data(bytes: buff, count: buff.count)
    let sliderVal = Int(sender?.value ?? 0.0)
    guard let char  = ledChar else {return}
    if sender == nil || sliderVal % 1 == 0 {
        print(sliderVal)
        
        if sender != nil, previousValue == sliderVal {
            return
        }
        previousValue = sliderVal
        pendingRequestWorkItem?.cancel()

        let requestWorkItem = DispatchWorkItem { [weak self] in
            self?.writeLEDValueToChar( withCharacteristic: char, withValue: data)
        }

        pendingRequestWorkItem = requestWorkItem
        DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(12),
                                      execute: requestWorkItem)

您可以尝试的一件事是一起摆脱调度队列并直接写入值。当然,有些值不会被写入,因为 phone 仍将处理最后的值传输。您可以简单地忽略此错误。像这样的东西可以解决问题:

if sender == nil || sliderVal % 1 == 0 {
    print(sliderVal)
        
    if sender != nil, previousValue == sliderVal {
        return
    }
    previousValue = sliderVal
    writeLEDValueToChar( withCharacteristic: char, withValue: data)
}

另一种方法是通过设置滑块的 step width 不使用滑块的所有可能值:

Slider(
    value: $speed,
    in: 0...100,
    step: 5
)

这样您将仅获得值 0、5、10、15...,而不是 0.0000、0.0001、0.0002...,这会在移动滑块时减少 DispatchQueue 中的条目数量