You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

蓝牙低功耗(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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 13:41:00