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

发布于 1周前 作者 itying888 来自 Flutter

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

Getting Started

在Windows平台上,CH340芯片可以直接视为串口使用。在Android平台上,它被视为USB设备。

Windows平台使用的插件:serial_port_win32 Android平台使用的插件:usb_serial

dependencies:
  serial_port_win32: ^0.5.2
  usb_serial: ^0.3.0

usb_serial 包的基本方法包括:

abstract class UsbSerial {
  /// 初始化
  create();

  /// 打开串口
  Future<bool> open();

  /// 关闭串口
  Future<bool> close();

  /// 写入字节列表
  Future<void> write(Uint8List data) async {}

  /// 写入字符串
  Future<void> writeString(String data) async {}

  /// 设置读数监听
  void readByteOnListen(Function(Uint8List value) onData);

  /// 串口状态
  bool isOpen();

  /// 设置参数
  Future<void> setPortParameters() async {}

  /// 获取可用串口
  Future<List<String>> getAvailablePorts();
}

使用案例

以下是一个完整的示例代码,展示了如何在Android平台上使用 flutter_usb_serial 插件进行串口通信。

import 'package:flutter/material.dart';
import 'dart:async';
import 'dart:typed_data';
import 'package:flutter/services.dart';
import 'package:usb_serial/usb_serial.dart';

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

class MyApp extends StatefulWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  UsbSerial? _usbSerial;
  String receive = '';

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

  // 平台消息异步处理,因此我们在异步方法中初始化
  Future<void> initPlatformState() async {
    _usbSerial = UsbSerialFactory().create();
    await _usbSerial?.create();

    debugPrint('Available ports: ${await _usbSerial?.getAvailablePorts()}');

    if (_usbSerial != null) {
      await _usbSerial?.open();
      _usbSerial?.readByteOnListen((value) {
        String str = utf8.decode(value);
        print(str);
        setState(() {
          receive = str;
        });
      });

      // 写入数据
      _usbSerial?.writeString("Hello, USB Serial!");
    }
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('USB Serial Example'),
        ),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Text('Receive: $receive'),
            ],
          ),
        ),
      ),
    );
  }

  @override
  void dispose() {
    if (_usbSerial != null) {
      _usbSerial?.close();
    }
    super.dispose();
  }
}

Android平台权限申请

在AndroidManifest.xml文件中添加以下内容以请求USB设备权限:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.usb_serial_example">

    <application
        ...
        <activity
            android:name=".MainActivity"
            ...>
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
            <intent-filter>
                <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
            </intent-filter>

            <meta-data
                android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"
                android:resource="@xml/device_filter" />
        </activity>
    </application>

</manifest>

创建一个名为 device_filter.xml 的文件,并将其放在 res/xml 目录下。如果目录不存在,请先创建该目录。文件内容如下:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <!-- 0x0403 / 0x6001: FTDI FT232R UART -->
    <usb-device vendor-id="1027" product-id="24577" />
    <usb-device vendor-id="6790" product-id="29987" />

    <!-- 0x0403 / 0x6015: FTDI FT231X -->
    <usb-device vendor-id="1027" product-id="24597" />

    <!-- 0x2341 / Arduino -->
    <usb-device vendor-id="9025" />

    <!-- 0x16C0 / 0x0483: Teensyduino  -->
    <usb-device vendor-id="5824" product-id="1155" />

    <!-- 0x10C4 / 0xEA60: CP210x UART Bridge -->
    <usb-device vendor-id="4292" product-id="60000" />

    <!-- 0x067B / 0x2303: Prolific PL2303 -->
    <usb-device vendor-id="1659" product-id="8963" />

    <!-- 0x1366 / 0x0105: Segger JLink -->
    <usb-device vendor-id="4966" product-id="261" />

    <!-- 0x1366 / 0x0105: CH340 JLink -->
    <usb-device vendor-id="1A86" product-id="7523" />
</resources>

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

1 回复

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


在Flutter中使用flutter_usb_serial插件进行USB串口通信,你可以按照以下步骤来实现。以下是一个基本的代码示例,展示了如何使用该插件进行串口设备的连接和数据通信。

1. 添加依赖

首先,在你的pubspec.yaml文件中添加flutter_usb_serial依赖:

dependencies:
  flutter:
    sdk: flutter
  flutter_usb_serial: ^x.y.z  # 请替换为最新版本号

然后运行flutter pub get来安装依赖。

2. 请求权限

在Android上,你需要请求USB权限。在你的AndroidManifest.xml文件中添加以下权限:

<uses-permission android:name="android.permission.USB_PERMISSION" />

3. 初始化插件

在你的Flutter应用中,初始化UsbSerial对象,并列出可用的USB设备。

import 'package:flutter/material.dart';
import 'package:flutter_usb_serial/flutter_usb_serial.dart';

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

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

class _MyAppState extends State<MyApp> {
  UsbSerial? _usbSerial;
  UsbDevice? _usbDevice;
  List<UsbDevice> _usbDevices = [];

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

  Future<void> _listUsbDevices() async {
    UsbManager usbManager = UsbManager();
    _usbDevices = await usbManager.getDeviceList();
    setState(() {});
  }

  Future<void> _openUsbDevice(UsbDevice device) async {
    _usbSerial = await UsbSerial.fromUsbDevice(device);
    await _usbSerial!.open();
    if (await _usbSerial!.setPortParameters(9600, UsbSerial.DATABITS_8, UsbSerial.STOPBITS_1, UsbSerial.PARITY_NONE)) {
      _usbSerial!.inputStream!.listen((Uint8List data) {
        // 处理接收到的数据
        print('Received: ${String.fromCharCodes(data)}');
      });
    } else {
      print('Failed to set port parameters');
    }
  }

  Future<void> _sendData(String data) async {
    if (_usbSerial != null && _usbSerial!.isOpen) {
      _usbSerial!.write(data.codeUnits);
    } else {
      print('USB serial is not open');
    }
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Flutter USB Serial Communication'),
        ),
        body: Padding(
          padding: const EdgeInsets.all(16.0),
          child: Column(
            children: [
              Expanded(
                child: ListView.builder(
                  itemCount: _usbDevices.length,
                  itemBuilder: (context, index) {
                    UsbDevice device = _usbDevices[index];
                    return ListTile(
                      title: Text(device.deviceName),
                      onTap: () {
                        _openUsbDevice(device);
                      },
                    );
                  },
                ),
              ),
              TextField(
                decoration: InputDecoration(labelText: 'Send Data'),
                onSubmitted: (String value) {
                  _sendData(value);
                },
              ),
            ],
          ),
        ),
      ),
    );
  }
}

4. 运行应用

确保你的设备已连接一个支持串口通信的USB设备,然后运行你的Flutter应用。你应该能够在应用中看到连接的USB设备列表,选择一个设备后,可以打开串口并开始发送和接收数据。

注意事项

  • 在实际使用中,你可能需要处理更多的错误情况,例如设备未连接、权限被拒绝等。
  • 确保你的设备支持OTG(On-The-Go)功能,并且已经启用了开发者选项和USB调试。
  • 根据你的具体需求,你可能需要调整波特率、数据位、停止位和校验位等串口参数。

这个示例提供了一个基本的框架,你可以根据需要进行扩展和修改。

回到顶部