multi_serial_port

Android 串口插件,基于 Android-SerialPort-API

相比 serialport_plus,主要解决三件事:

  • 多路串口同时通信——serialport_plus 内部只有一个 SerialPort 实例,第二次 open 必定失败
  • 按 USB 物理路径绑定设备——/dev/ttyUSB* 的编号会随插拔顺序漂移,物理路径不会
  • 枚举尚未绑定串口的 USB 端口——方便在设置界面里让用户挑物理口

安装

dependencies:
  multi_serial_port: ^0.1.0

用法

import 'package:multi_serial_port/multi_serial_port.dart';

// 每路串口一个实例,id 唯一
final relay = FlutterSerialPort('relay');
final thermal = FlutterSerialPort('thermal');

// 打开:/dev/ttyUSB0、完整 sysfs 路径、USB 拓扑地址都可以
await relay.open('2-1.2', 115200);
await thermal.open('2-1.3', 460800);

// 接收(广播流,可多处监听)
thermal.read().listen((Uint8List bytes) {
  // ...
});

// 发送
await relay.write(Uint8List.fromList([0xA0, 0x01, 0x01, 0xA2]));

枚举设备

final port = FlutterSerialPort();

await port.getAllDevices();          // ['ttyACM0', 'ttyUSB0']
await port.getAllDevicesPath();      // ['/dev/ttyACM0', '/dev/ttyUSB0']
await port.getAllPhysicalDevices();  // [UsbDevice(topology: '2-1.2', devicePaths: ['/dev/ttyUSB0']), ...]

getAllPhysicalDevices() 返回的 topology(如 2-1.2)在设备插在同一个物理口上时保持稳定,适合存进配置里作为绑定依据。

路径互转:

await FlutterSerialPort.resolveDevicePath('2-1.2');   // '/dev/ttyUSB0'
FlutterSerialPort.physicalPathOf('/dev/ttyUSB0');     // '/sys/devices/.../usb2/2-1/2-1.2'

示例程序

example/ 是一个串口调试助手:选择物理端口与波特率(1200 ~ 921600)、数据位、校验位、停止位,打开后可以按文本或十六进制收发,收发记录带时间戳并统计字节数。

cd example && flutter run

从 serialport_plus 迁移

方法名和参数顺序保持一致,改动集中在构造函数:

// 之前
final serial = SerialportPlus();
await serial.open('/dev/ttyUSB0', 115200, 8, 0, 1);

// 之后
final serial = FlutterSerialPort();               // 多路时传 id:FlutterSerialPort('relay')
await serial.open('/dev/ttyUSB0', 115200, 8, 0, 1);

两处细节差异:

  • 返回值由 Future<bool?> / Future<List?> 改成非空的 Future<bool> / Future<List<String>>,原来写 ok == truelist ?? [] 的代码仍然能编译
  • opendataBitsparitystopBits 变成可选参数,默认 8/0/1

已知限制

  • 仅支持 Android
  • 打开串口需要设备节点可读写。权限不足时插件会尝试 su -c chmod 666,非 root 设备需要自行处理 udev/SELinux 规则
  • 部分 Rockchip 板子上,关闭正被读线程占用的串口会触发 SIGABRT。长期运行的场景建议保持连接、复用实例,而不要频繁 close()
  • 底层 cfmakeraw() 不会设置 CLOCAL。若 tty 因载波掉线被挂断,read 会持续返回 EOF;此时需要重新 open()。可先用 stty -F /dev/ttyUSB0 -a 确认是否为 -clocal

Libraries

multi_serial_port
Android 多路串口插件,按 USB 物理路径绑定设备。