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 中的条目数量
我正在研究与 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 中的条目数量