Flutter使用flutter_libserialport读取ESP32串口数据异常求助
解决flutter_libserialport读取ESP32串口数据乱码问题
你的核心问题在于缓冲区处理逻辑错误:固定按长度5截断数据,完全忽略了串口数据按行(带换行符)发送的特性,导致完整的JSON被拆成碎片拼接,最终出现乱码。结合Arduino监视器能正常读取的情况,以下是针对性修复方案:
问题分析
- 代码中
bufferIndex >=5的判断完全不合理,目标JSON字符串长度远大于5,直接截断会破坏数据完整性。 - 未按换行符分割数据:ESP32的MicroPython
print()会自动在末尾添加\r\n,Arduino监视器正是通过换行符识别完整行,而你的代码未处理该逻辑。 - 串口参数配置不完整:仅设置波特率,未明确数据位、停止位、校验位,可能存在隐性参数不匹配。
修复后的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
相关产品推荐
相关产品推荐

