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

如何使用node-serialport合并ESP32串口发送的JSON分块数据?

解决串口接收大JSON被拆分的问题

嘿,这个场景我太熟了!串口传输大体积数据时,因为硬件缓冲区的限制,肯定会被拆成多个片段发送。你用Readline解析后拿到的单行片段,其实就是拆分后的块,咱们只需要把这些片段拼起来,直到能得到一个完整可解析的JSON就行。给你三个实用的解决方案,按靠谱程度排序:

方案一:给JSON加边界标记(最推荐,需要修改ESP32代码)

如果能控制ESP32的发送逻辑,在每个完整JSON的前后加上唯一的标记(比如[JSON_START]和[JSON_END]),接收端就能精准识别完整的JSON块,完全避免解析错误。

ESP32端发送示例(伪代码)

// 生成你的大JSON字符串
String largeJson = getYourBigJsonObject();
// 发送开头标记+JSON+结尾标记
Serial.print("[JSON_START]");
Serial.print(largeJson);
Serial.println("[JSON_END]");

树莓派端接收代码

let jsonBuffer = '';
const START_MARK = '[JSON_START]';
const END_MARK = '[JSON_END]';

function handleData(data) {
  // 把收到的行片段加到缓冲区
  jsonBuffer += data;

  // 检查是否包含结束标记
  const endPos = jsonBuffer.indexOf(END_MARK);
  if (endPos !== -1) {
    // 找到开始标记的位置
    const startPos = jsonBuffer.indexOf(START_MARK);
    if (startPos !== -1) {
      // 提取中间的JSON内容
      const rawJson = jsonBuffer.slice(startPos + START_MARK.length, endPos).trim();
      try {
        const completeJson = JSON.parse(rawJson);
        // 这里处理完整的JSON对象
        console.log('收到完整JSON:', completeJson);
        // 清空缓冲区,注意保留结束标记之后的内容(防止下一个JSON的片段已经过来)
        jsonBuffer = jsonBuffer.slice(endPos + END_MARK.length);
      } catch (err) {
        console.error('JSON解析失败:', err);
        // 出错就清空缓冲区,避免垃圾数据积累
        jsonBuffer = '';
      }
    } else {
      // 只有结束标记没有开始,说明之前的片段丢失了,直接清空
      jsonBuffer = '';
    }
  }
}

方案二:缓冲区累加+尝试解析(无需修改ESP32代码)

如果没法改ESP32的代码,就用这个方法:每次收到片段就加到缓冲区,然后尝试用JSON.parse解析,成功就说明拿到了完整的JSON,失败就继续等待下一个片段。

树莓派端代码

// 定义模块级别的缓冲区,用来累加JSON片段
let jsonBuffer = '';

function handleData(data) {
  // 把新收到的行数据去掉多余空格后加到缓冲区
  jsonBuffer += data.trim();

  try {
    // 尝试解析缓冲区内容
    const completeJson = JSON.parse(jsonBuffer);
    // 解析成功!处理完整JSON
    console.log('完整JSON:', completeJson);
    // 清空缓冲区,准备接收下一个JSON
    jsonBuffer = '';
  } catch (err) {
    // 解析失败,说明内容还不完整,继续等待下一个片段
    console.debug('片段不完整,继续累加:', jsonBuffer);
  }
}

这个方法的核心是利用JSON.parse的特性:只有完整的JSON才能被成功解析,不完整的片段会抛出错误,我们就靠这个判断是否已经拿到了完整的对象。

方案三:大括号计数法(适合单个对象结构的JSON)

如果你的JSON是单个对象(外层是一对{}),可以通过统计大括号的数量来判断是否完整——当{和}的数量相等时,就说明可能是一个完整的JSON。

树莓派端代码

let jsonBuffer = '';
let braceCounter = 0;

function handleData(data) {
  jsonBuffer += data.trim();

  // 遍历字符,统计大括号数量
  for (const char of jsonBuffer) {
    if (char === '{') braceCounter++;
    else if (char === '}') braceCounter--;
  }

  // 当大括号数量回到0,且缓冲区不为空时尝试解析
  if (braceCounter === 0 && jsonBuffer.length > 0) {
    try {
      const completeJson = JSON.parse(jsonBuffer);
      console.log('完整JSON:', completeJson);
      jsonBuffer = '';
      braceCounter = 0;
    } catch (err) {
      console.error('JSON格式错误:', err);
      jsonBuffer = '';
      braceCounter = 0;
    }
  }
}

这个方法适合JSON结构固定的场景,比如始终是单个对象,嵌套的大括号也能正确计数。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 08:19:08