蓝牙低功耗(BLE)问题:iOS Swift仅接收Arduino发送的最后一条字符串
Arduino BLE发送多条数据,iOS Swift仅接收最后一条的解决办法
我发现无论通过Arduino的BLE发送什么数据,iOS端的Swift程序始终只能接收到最后一条消息。例如在下方示例代码中,Swift端始终打印出Optional("0703")。请问有谁知道解决办法吗?
Arduino 代码
void loop() { BLE.poll(); delay(1000); flag = !flag; serialEvent_3(flag); } void serialEvent_3(bool flag) { delay(100); if (flag) { outgoingDataCharacteristic.writeValue("5678"); } else { outgoingDataCharacteristic.writeValue("4567"); } outgoingDataCharacteristic.writeValue("4567"); delay(500); outgoingDataCharacteristic.writeValue("0703"); if (Serial.available() > 0) { String response_str = Serial.readString(); response_str.trim(); byte value[response_str.length()]; response_str.getBytes(value, response_str.length()); outgoingDataCharacteristic.writeValue(value, response_str.length()); outgoingDataCharacteristic.writeValue("1234"); delay(100); //Serial.flush(); } Serial.flush(); }
Swift 代码
func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) { switch characteristic.uuid { case UartGattCharacteristicReceiveId: print("data received") print(String(data: characteristic.value!, encoding: .utf8)); break default: break } }
问题原因
BLE特征值的写入默认是覆盖式更新,当你连续快速调用writeValue时,iOS的BLE栈会合并多次更新请求,只保留最后一次的写入值,因此只会触发一次didUpdateValueFor回调,导致你只能收到最后一条消息。
解决办法
以下是几种可行的解决方案:
增加写入间隔(临时方案):在每次调用
writeValue后添加足够长的延迟,给BLE栈足够时间完成通知推送。例如:if (flag) { outgoingDataCharacteristic.writeValue("5678"); delay(300); // 给BLE栈推送通知的时间 } else { outgoingDataCharacteristic.writeValue("4567"); delay(300); } outgoingDataCharacteristic.writeValue("4567"); delay(300); outgoingDataCharacteristic.writeValue("0703");注意:这种方法会降低传输效率,仅适合低频次的消息发送场景。
封装多条数据为单条消息:将所有需要发送的内容拼接成一个包含分隔符的字符串,一次性发送,再在Swift端拆分解析。
Arduino端修改示例:String combinedMsg = ""; if (flag) { combinedMsg += "5678|"; } else { combinedMsg += "4567|"; } combinedMsg += "4567|0703"; outgoingDataCharacteristic.writeValue(combinedMsg.c_str());Swift端解析示例:
if let receivedStr = String(data: characteristic.value!, encoding: .utf8) { let messages = receivedStr.components(separatedBy: "|") messages.forEach { msg in print("收到消息:\(msg)") } }使用带确认的通知机制:在Arduino中监听BLE特征的确认回调,确保上一条消息已被iOS端接收后,再发送下一条数据。不同的BLE库实现方式不同,例如一些库会提供
onWrite或onNotifyConfirmed类的回调接口,你可以利用这些接口来控制消息发送的节奏。检查特征属性配置:确保你的
outgoingDataCharacteristic正确配置了NOTIFY属性,部分BLE库需要显式启用通知功能,或者在写入时指定触发通知的参数。
内容的提问来源于stack exchange,提问作者universe123
相关产品推荐
相关产品推荐

