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

Flutter使用flutter_libserialport读取ESP32串口数据异常求助

解决flutter_libserialport读取ESP32串口数据乱码问题

你的核心问题在于缓冲区处理逻辑错误:固定按长度5截断数据,完全忽略了串口数据按行(带换行符)发送的特性,导致完整的JSON被拆成碎片拼接,最终出现乱码。结合Arduino监视器能正常读取的情况,以下是针对性修复方案:

问题分析

  1. 代码中bufferIndex >=5的判断完全不合理,目标JSON字符串长度远大于5,直接截断会破坏数据完整性。
  2. 未按换行符分割数据:ESP32的MicroPythonprint()会自动在末尾添加\r\n,Arduino监视器正是通过换行符识别完整行,而你的代码未处理该逻辑。
  3. 串口参数配置不完整:仅设置波特率,未明确数据位、停止位、校验位,可能存在隐性参数不匹配。

修复后的Dart代码

import 'dart:convert';
import 'dart:typed_data';
import 'package:flutter_libserialport/flutter_libserialport.dart';
import 'package:flutter/foundation.dart';

void readSerialData() async {
  final port = SerialPort("/dev/cu.wchusbserial55390119721");
  final config = SerialPortConfig();
  
  // 匹配ESP32默认串口参数:115200波特率、8数据位、1停止位、无校验
  config.baudRate = 115200;
  config.bits = 8;
  config.stopBits = 1;
  config.parity = SerialPortParity.none;
  
  port.config = config;
  final reader = SerialPortReader(port, timeout: 10000);

  try {
    if (!port.openReadWrite()) {
      debugPrint('端口打开失败: ${port.error}');
      return;
    }

    List<int> buffer = [];
    reader.stream.listen((Uint8List data) {
      buffer.addAll(data);
      
      // 按换行符(\n)拆分完整数据行
      int newlinePos = buffer.indexOf(10); // 10是\n的ASCII码
      while (newlinePos != -1) {
        // 提取完整行(包含\r,后续用trim移除)
        final lineBytes = buffer.sublist(0, newlinePos + 1);
        final line = String.fromCharCodes(lineBytes).trim();
        
        if (line.isNotEmpty) {
          debugPrint('原始行数据: $line');
          // 解析JSON
          try {
            final jsonData = jsonDecode(line) as Map<String, dynamic>;
            debugPrint('解析后数据: $jsonData');
          } catch (e) {
            debugPrint('JSON解析失败: $e');
          }
        }
        
        // 移除已处理的行,保留未完成的剩余数据
        buffer = buffer.sublist(newlinePos + 1);
        newlinePos = buffer.indexOf(10);
      }
    }, onError: (err) {
      debugPrint('数据流错误: $err');
      port.close();
    }, onDone: () {
      debugPrint('数据流关闭');
      port.close();
    });
  } on SerialPortError catch (err) {
    debugPrint('串口错误: $err');
    port.close();
  }
}

关键修复点

  • 完整配置串口参数:明确设置数据位、停止位、校验位,确保与ESP32默认的8N1参数完全匹配。
  • 按行处理数据:通过查找换行符拆分完整的JSON行,避免数据碎片化。
  • 缓冲区正确维护:处理完一行后,仅移除已处理的部分,剩余不完整数据留在缓冲区等待后续数据补充。
  • 增加错误处理:覆盖端口打开失败、数据流错误、数据流关闭等场景,提升代码健壮性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 15:38:42