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

Arduino向P5JS发送JSON串口数据解析异常问题求助

解决WebSerial接收Arduino JSON数据被拆分的问题

问题背景

用Arduino通过WebSerial给P5JS发送完整JSON字符串(示例:[{"gesture":"tap","probability":0.35,"winner":"circle"}]),Arduino串口监视器显示数据完整,但P5JS偶尔会收到拆分的片段,导致JSON解析失败。之前尝试的首尾匹配(判断开头[{"、结尾}])和长度判断方法效果不佳,可从以下三个方向解决:


解决方案

1. 从根源阻止数据拆分:用分隔符拼接完整数据

WebSerial为流式接收,单次数据包不一定是完整JSON。可以让Arduino在每个完整JSON后添加换行符作为分隔标记,P5JS端维护缓冲区,按分隔符拆分出完整数据:

Arduino端修改(关键)

每次发送完JSON后调用Serial.println(),自动在末尾添加换行符:

// 示例发送代码
String jsonStr = "[{\"gesture\":\"tap\",\"probability\":0.35,\"winner\":\"circle\"}]";
Serial.println(jsonStr); // 末尾自动追加\r\n分隔符

P5JS端修改

维护全局缓冲区,收到数据后追加,再按换行符拆分完整JSON段处理:

let serialBuffer = ""; // 全局缓冲区

function serialRead(data) {
  serialBuffer += data;
  // 循环处理所有带换行符的完整JSON段
  while (serialBuffer.includes("\n")) {
    const splitIndex = serialBuffer.indexOf("\n");
    const fullJson = serialBuffer.substring(0, splitIndex).trim(); // 清理多余的\r或空格
    serialBuffer = serialBuffer.substring(splitIndex + 1); // 剩余数据留在缓冲区
    
    // 解析并处理完整JSON
    try {
      gestureInfo = JSON.parse(fullJson);
      console.log(gestureInfo);
    } catch (e) {
      console.log("无效JSON,跳过:", fullJson);
    }
  }
}

2. 异常处理+缓冲区:容错式解析

不管数据是否拆分,将收到的内容追加到缓冲区后尝试解析,成功则处理并清空缓冲区;失败则保留缓冲区等待下一段数据:

let serialBuffer = "";

function serialRead(data) {
  serialBuffer += data.replace(/(?:\r\n|\r|\n)/g, ""); // 先清理换行符
  
  try {
    gestureInfo = JSON.parse(serialBuffer);
    console.log(gestureInfo);
    serialBuffer = ""; // 解析成功,清空缓冲区
  } catch (e) {
    // 解析失败说明数据不完整,保留缓冲区等待后续数据
    console.log("数据不完整,继续等待:", serialBuffer);
  }
}

3. 更可靠的首尾匹配+缓冲区

针对固定格式的JSON(以[{"开头、}]结尾),在缓冲区中定位完整JSON段,提取后处理:

let serialBuffer = "";

function serialRead(data) {
  serialBuffer += data.replace(/(?:\r\n|\r|\n)/g, "");
  
  // 循环查找所有完整的JSON段
  while (true) {
    const startIndex = serialBuffer.indexOf("[{\"");
    const endIndex = serialBuffer.indexOf("}]");
    
    // 确认找到完整段:起始标记存在,且结束标记在起始标记之后
    if (startIndex !== -1 && endIndex !== -1 && endIndex > startIndex) {
      const fullJson = serialBuffer.substring(startIndex, endIndex + 2); // +2对应"}]"的长度
      serialBuffer = serialBuffer.substring(endIndex + 2); // 移除已处理的部分
      
      try {
        gestureInfo = JSON.parse(fullJson);
        console.log(gestureInfo);
      } catch (e) {
        console.log("JSON格式错误,跳过:", fullJson);
      }
    } else {
      break; // 无完整段,退出循环
    }
  }
}

内容的提问来源于stack exchange,提问作者user2187427

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 02:54:36