You need to enable JavaScript to run this app. Arduino软件串口输出异常:使用newSerial仅输出首条NMEA语句的问题
优惠活动
大模型
产品
解决方案
定价
更多

Arduino软件串口输出异常:使用newSerial仅输出首条NMEA语句的问题

故障核心原因
  • Software Serial半双工属性限制:你当前的代码把同一个newSerial同时用作输入接收、输出发送端口,Software Serial本身不支持全双工同时收发,发送操作会直接打断正在进行的串口接收流程,导致第一条NMEA发完后,后续正在传输的GSA、RMC语句的字节流被截断,再也没法被完整解析。这也是你之前用硬件串口Serial.println输出时功能正常的核心原因——硬件串口支持全双工收发并行,不会出现发送打断接收的问题。
  • 解码触发时机问题:通用NMEA解析库的decode()方法,仅在完整收到一条以换行符结尾的合法NMEA语句时返回true。你在刚触发第一条GGA语句的解码成功时,就立刻进入发送流程,此时后续GSA、RMC的字节还未进入串口缓冲区,发送操作直接清空了缓冲区的待接收数据。
  • 单字节读取逻辑缺陷:当前loop每次仅读取1个串口字节,在波特率适配间隙很容易漏帧,进一步加剧了后两条语句的丢失。
  • 部分开发板的Software Serial默认接收缓冲区仅能存储1条NMEA语句的长度,连续传输3条语句时会直接溢出丢弃后续数据。
可落地的修复方案
  • 拆分收发端口:不要将同一个Software Serial同时作为输入接收、输出发送通道。硬件资源允许的情况下,把GPS输入接在硬件串口上,将Software Serial专用为输出端;如果需要用Software Serial接外部GPS输入,就把输出换到硬件USB串口,从根源上避免收发冲突。
  • 调整处理顺序:先把当前串口缓冲区里的所有待接收字节全部喂给NMEA解析库,等当前批次的所有NMEA语句都完整解码完成后,再统一执行发送操作,杜绝边收边发打断接收的问题。
  • 硬件资源不足需同口收发的适配方案:如果必须用同一个Software Serial完成双向收发,每执行完一次println输出后,按波特率添加对应延时(9600波特率下建议加100ms延时),等待串口状态复位后再恢复接收逻辑。
  • 适当调大Software Serial的接收缓冲区大小,保证能存下连续传输的3条NMEA语句的全部字节。
  • 修正后的参考代码结构:
// 独立拆分接收、输出串口
SoftwareSerial outputSerial(2, 3);
NmeaParser gps;

void setup() {
  Serial.begin(9600); // 硬件串口专门接收GPS输入
  outputSerial.begin(9600);
}

void loop() {
  // 循环读完当前所有待接收字节,不提前触发发送
  while (Serial.available() > 0) {
    gps.decode(Serial.read());
  }
  // 等语句完整解码后再执行发送
  if (gps.hasValidSentence()) {
    outputSerial.println(gps.sentence());
    gps.resetBuffer(); // 清空解析缓存,准备接收下一批数据
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.12 04:45:09