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
相关产品推荐
相关产品推荐

