Flutter USB串口通信插件breno_usb_serial的使用

Flutter USB串口通信插件breno_usb_serial的使用

使用说明

breno_usb_serial 是一个用于在 Flutter 中实现 USB 串口通信的插件。它允许开发者通过 USB 连接与外部设备进行数据交换。本文将详细介绍如何使用该插件,并提供完整的示例代码。


安装插件

首先,在 pubspec.yaml 文件中添加以下依赖:

dependencies:
  breno_usb_serial: ^版本号

然后运行以下命令以安装依赖:

flutter pub get

示例代码

以下是一个完整的示例代码,展示了如何使用 breno_usb_serial 插件实现 USB 串口通信。

示例代码(main.dart

import 'dart:async';
import 'dart:typed_data';

import 'package:flutter/material.dart';

import 'package:breno_usb_serial/breno_usb_serial.dart';

void main() => runApp(MyApp());

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  UsbPort? _port;
  String _status = "Idle";
  List<Widget> _ports = [];
  List<Widget> _serialData = [];

  StreamSubscription<String>? _subscription;
  Transaction<String>? _transaction;
  UsbDevice? _device;

  TextEditingController _textController = TextEditingController();

  // 连接到指定设备
  Future<bool> _connectTo(device) async {
    _serialData.clear();

    // 取消现有订阅和事务
    if (_subscription != null) {
      _subscription!.cancel();
      _subscription = null;
    }

    if (_transaction != null) {
      _transaction!.dispose();
      _transaction = null;
    }

    if (_port != null) {
      _port!.close();
      _port = null;
    }

    // 如果设备为空,则断开连接
    if (device == null) {
      _device = null;
      setState(() {
        _status = "Disconnected";
      });
      return true;
    }

    // 创建并打开端口
    _port = await device.create();
    if (await _port!.open() != true) {
      setState(() {
        _status = "Failed to open port";
      });
      return false;
    }
    _device = device;

    // 配置端口参数
    await _port!.setDTR(true);
    await _port!.setRTS(true);
    await _port!.setPortParameters(
        115200, UsbPort.DATABITS_8, UsbPort.STOPBITS_1, UsbPort.PARITY_NONE);

    // 设置输入流处理
    _transaction = Transaction.stringTerminated(
        _port!.inputStream as Stream<Uint8List>, Uint8List.fromList([13, 10]));

    _subscription = _transaction!.stream.listen((String line) {
      setState(() {
        _serialData.add(Text(line));
        if (_serialData.length > 20) {
          _serialData.removeAt(0);
        }
      });
    });

    setState(() {
      _status = "Connected";
    });
    return true;
  }

  // 获取可用设备列表
  void _getPorts() async {
    _ports = [];
    List<UsbDevice> devices = await UsbSerial.listDevices();
    if (!devices.contains(_device)) {
      _connectTo(null);
    }
    print(devices);

    devices.forEach((device) {
      _ports.add(ListTile(
          leading: Icon(Icons.usb),
          title: Text(device.productName!),
          subtitle: Text(device.manufacturerName!),
          trailing: ElevatedButton(
            child: Text(_device == device ? "Disconnect" : "Connect"),
            onPressed: () {
              _connectTo(_device == device ? null : device).then((res) {
                _getPorts();
              });
            },
          )));
    });

    setState(() {
      print(_ports);
    });
  }

  @override
  void initState() {
    super.initState();

    // 监听 USB 事件
    UsbSerial.usbEventStream!.listen((UsbEvent event) {
      _getPorts();
    });

    // 初始化设备列表
    _getPorts();
  }

  @override
  void dispose() {
    super.dispose();
    _connectTo(null); // 断开所有连接
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        home: Scaffold(
      appBar: AppBar(
        title: const Text('USB Serial Plugin example app'),
      ),
      body: Center(
          child: Column(children: <Widget>[
        Text(
            _ports.length > 0
                ? "Available Serial Ports"
                : "No serial devices available",
            style: Theme.of(context).textTheme.headline6),
        ..._ports,
        Text('Status: $_status\n'),
        Text('info: ${_port.toString()}\n'),
        ListTile(
          title: TextField(
            controller: _textController,
            decoration: InputDecoration(
              border: OutlineInputBorder(),
              labelText: 'Text To Send',
            ),
          ),
          trailing: ElevatedButton(
            child: Text("Send"),
            onPressed: _port == null
                ? null
                : () async {
                    if (_port == null) {
                      return;
                    }
                    String data = _textController.text + "\r\n";
                    await _port!.write(Uint8List.fromList(data.codeUnits));
                    _textController.text = "";
                  },
          ),
        ),
        Text("Result Data", style: Theme.of(context).textTheme.headline6),
        ..._serialData,
      ])),
    ));
  }
}

功能说明

  1. 设备列表获取

    • 使用 UsbSerial.listDevices() 方法获取当前系统中可用的 USB 设备。
    • 每个设备显示为一个 ListTile,包含设备名称、厂商名称以及连接或断开按钮。
  2. 连接与断开

    • 点击“Connect”按钮后,调用 _connectTo(device) 方法连接到指定设备。
    • 点击“Disconnect”按钮后,断开当前连接。
  3. 数据发送

    • 输入框中输入要发送的数据,点击“Send”按钮后,通过 _port.write() 方法将数据发送到设备。
  4. 数据接收

    • 使用 Transaction.stringTerminated 处理接收到的数据流,将字符串以换行符作为终止符解析。
  5. 状态显示

    • 显示当前连接状态(例如“Connected”或“Disconnected”)。

注意事项

  • 确保设备已正确连接并授权。
  • 在 Android 上,可能需要配置 AndroidManifest.xml 文件以请求权限:
    <uses-permission android:name="android.permission.USB_PERMISSION"/>
    

更多关于Flutter USB串口通信插件breno_usb_serial的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter USB串口通信插件breno_usb_serial的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


breno_usb_serial 是一个用于在 Flutter 应用中实现 USB 串口通信的插件。它允许你通过 USB 连接到外部设备(如 Arduino、传感器等)并进行串口通信。

以下是使用 breno_usb_serial 插件的基本步骤:

1. 添加依赖

首先,你需要在 pubspec.yaml 文件中添加 breno_usb_serial 插件的依赖:

dependencies:
  flutter:
    sdk: flutter
  breno_usb_serial: ^0.0.1  # 请检查最新版本

然后运行 flutter pub get 来获取依赖。

2. 配置 Android 项目

AndroidManifest.xml 文件中添加以下权限:

<uses-permission android:name="android.permission.USB_PERMISSION" />
<uses-feature android:name="android.hardware.usb.host" />

3. 初始化插件

在你的 Dart 代码中,首先导入 breno_usb_serial 插件:

import 'package:breno_usb_serial/breno_usb_serial.dart';

4. 获取 USB 设备列表

你可以通过以下代码获取连接的 USB 设备列表:

List<UsbDevice> devices = await BrenoUsbSerial.getDevices();

5. 打开 USB 设备并配置串口

选择一个设备并打开它,然后配置串口参数(如波特率、数据位、停止位等):

UsbDevice device = devices[0]; // 选择第一个设备
await BrenoUsbSerial.openDevice(device);

// 配置串口参数
await BrenoUsbSerial.setParameters(9600, UsbPort.DATABITS_8, UsbPort.STOPBITS_1, UsbPort.PARITY_NONE);

6. 发送和接收数据

你可以使用以下代码发送和接收数据:

// 发送数据
await BrenoUsbSerial.write(Uint8List.fromList([0x01, 0x02, 0x03]));

// 接收数据
Uint8List data = await BrenoUsbSerial.read();

7. 关闭 USB 设备

通信完成后,记得关闭 USB 设备:

await BrenoUsbSerial.closeDevice();

8. 处理权限

在 Android 上,你可能需要请求用户授予 USB 权限。你可以使用以下代码来请求权限:

bool hasPermission = await BrenoUsbSerial.hasPermission(device);
if (!hasPermission) {
  await BrenoUsbSerial.requestPermission(device);
}

9. 示例代码

以下是一个简单的示例代码,展示了如何使用 breno_usb_serial 插件进行 USB 串口通信:

import 'package:flutter/material.dart';
import 'package:breno_usb_serial/breno_usb_serial.dart';
import 'dart:typed_data';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      home: UsbSerialDemo(),
    );
  }
}

class UsbSerialDemo extends StatefulWidget {
  [@override](/user/override)
  _UsbSerialDemoState createState() => _UsbSerialDemoState();
}

class _UsbSerialDemoState extends State<UsbSerialDemo> {
  List<UsbDevice> devices = [];
  UsbDevice? selectedDevice;

  [@override](/user/override)
  void initState() {
    super.initState();
    _getDevices();
  }

  Future<void> _getDevices() async {
    devices = await BrenoUsbSerial.getDevices();
    setState(() {});
  }

  Future<void> _openDevice() async {
    if (selectedDevice == null) return;

    bool hasPermission = await BrenoUsbSerial.hasPermission(selectedDevice!);
    if (!hasPermission) {
      await BrenoUsbSerial.requestPermission(selectedDevice!);
    }

    await BrenoUsbSerial.openDevice(selectedDevice!);
    await BrenoUsbSerial.setParameters(9600, UsbPort.DATABITS_8, UsbPort.STOPBITS_1, UsbPort.PARITY_NONE);

    // 发送数据
    await BrenoUsbSerial.write(Uint8List.fromList([0x01, 0x02, 0x03]));

    // 接收数据
    Uint8List data = await BrenoUsbSerial.read();
    print("Received data: $data");

    // 关闭设备
    await BrenoUsbSerial.closeDevice();
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('USB Serial Demo'),
      ),
      body: Column(
        children: [
          DropdownButton<UsbDevice>(
            value: selectedDevice,
            items: devices.map((UsbDevice device) {
              return DropdownMenuItem<UsbDevice>(
                value: device,
                child: Text(device.deviceName),
              );
            }).toList(),
            onChanged: (UsbDevice? device) {
              setState(() {
                selectedDevice = device;
              });
            },
          ),
          ElevatedButton(
            onPressed: _openDevice,
            child: Text('Open Device'),
          ),
        ],
      ),
    );
  }
}
回到顶部