Flutter串口通信插件webserial的使用

Flutter串口通信插件webserial的使用

WebSerial Dart package 是一个用于实现串口通信的Dart包,它基于 web 包构建。该包的存在是因为 web 包仅支持由 W3C 或 W3C 标准跟踪的 Web API,而目前 Web Serial API 还未标准化。

使用该包

  1. 在你的 pubspec.yaml 文件中添加以下依赖:

    dependencies:
      webserial: ^0.1.0
    
  2. 在你的 Flutter 应用程序中导入 webserial 包:

    import 'package:webserial/webserial.dart';
    

注意:此包建立在 web 包的基础上,因此一些类型来自 web 包,但你无需导入 package:web/web.dart,因为这些类型已经被 webserial 包重新导出。

使用示例

你可以查看 /example 文件夹中的示例 Flutter 应用程序。

示例代码

以下是完整的示例代码:

import 'dart:typed_data';

import 'package:flutter/material.dart';
import 'package:webserial/webserial.dart';
import 'dart:js_interop';

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

class MainApp extends StatelessWidget {
  const MainApp({super.key});

  void chooseSerialDevice() async {
    late final JSSerialPort? port;
    try {
      // 创建过滤选项以选择特定的供应商ID
      final filters = [
        JSFilterObject(usbVendorId: 0xcafe, usbProductId: 0x4009)
      ];

      port = await requestWebSerialPort(filters.toJS);
      print("获取到串口: $port");
    } catch (e) {
      print(e);
      return;
    }

    if (port?.readable == null) {
      // 打开串口。
      await port
          ?.open(
            JSSerialOptions(
              baudRate: 115200, // 波特率
              dataBits: 8, // 数据位
              stopBits: 1, // 停止位
              parity: "none", // 校验位
              bufferSize: 64, // 缓冲区大小
              flowControl: "none", // 流控制
            ),
          )
          .toDart;

      print("端口已打开: ${port?.readable}");
    } else {
      print("端口已经打开: ${port?.readable}");
    }
    
    // 监听从串口设备传来的数据。
    final reader = port?.readable?.getReader() as ReadableStreamDefaultReader;

    // 示例:打开端口后立即发送数据
    final request = Uint8List.fromList([0x02]);
    final JSUint8Array jsReq = request.toJS;
    final writer = port?.writable?.getWriter();
    writer?.write(jsReq);
    // 允许稍后关闭串口。
    writer?.releaseLock();

    while (true) {
      final result = await reader.read().toDart;
      if (result.done) {
        // 允许稍后关闭串口。
        reader.releaseLock();
        break;
      } else {
        // value 是一个 Uint8Array。
        print("数据: ${result.value}");
      }
    }
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Center(
          child: MaterialButton(
            child: Text("选择串口设备"),
            onPressed: () {
              chooseSerialDevice();
            },
          ),
        ),
      ),
    );
  }
}

[@JS](/user/JS)()
external set dartSerialDataCallback(JSFunction value);

void onSerialData(JSUint8Array data) {
  print("$data");
}

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

1 回复

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


Flutter 中并没有一个名为 webserial 的官方插件,但你可以使用 flutter_libserialport 或者 flutter_serial 这样的插件来进行串口通信。如果你指的是在 Flutter Web 中使用 Web Serial API 进行串口通信,那么你需要使用 web_serial 插件。以下是如何在 Flutter 中使用 web_serial 插件进行串口通信的基本步骤。

1. 添加依赖

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

dependencies:
  flutter:
    sdk: flutter
  web_serial: ^0.1.0  # 请使用最新版本

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

2. 导入包

在你的 Dart 文件中导入 web_serial 包:

import 'package:web_serial/web_serial.dart';

3. 请求串口权限

在 Web Serial API 中,首先需要请求用户授权访问串口设备:

Future<void> requestSerialPort() async {
  try {
    final SerialPort port = await WebSerial.requestPort();
    print('Serial port selected: ${port.name}');
  } catch (e) {
    print('Error requesting serial port: $e');
  }
}

4. 打开串口

在获取到串口对象后,你可以打开串口并设置波特率等参数:

Future<void> openSerialPort(SerialPort port) async {
  try {
    await port.open(baudRate: 9600);
    print('Serial port opened');
  } catch (e) {
    print('Error opening serial port: $e');
  }
}

5. 读取数据

你可以通过监听 port.readStream 来读取从串口接收到的数据:

void readData(SerialPort port) {
  port.readStream.listen((data) {
    print('Received data: ${String.fromCharCodes(data)}');
  });
}

6. 写入数据

你可以使用 port.write 方法向串口发送数据:

Future<void> writeData(SerialPort port, String data) async {
  try {
    await port.write(Uint8List.fromList(data.codeUnits));
    print('Data written: $data');
  } catch (e) {
    print('Error writing data: $e');
  }
}

7. 关闭串口

使用完毕后,记得关闭串口:

Future<void> closeSerialPort(SerialPort port) async {
  try {
    await port.close();
    print('Serial port closed');
  } catch (e) {
    print('Error closing serial port: $e');
  }
}

完整示例

以下是一个完整的示例,展示如何使用 web_serial 插件进行串口通信:

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

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

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

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

class _SerialPortPageState extends State<SerialPortPage> {
  SerialPort? _port;

  Future<void> requestSerialPort() async {
    try {
      final SerialPort port = await WebSerial.requestPort();
      setState(() {
        _port = port;
      });
      print('Serial port selected: ${port.name}');
    } catch (e) {
      print('Error requesting serial port: $e');
    }
  }

  Future<void> openSerialPort() async {
    if (_port == null) return;
    try {
      await _port!.open(baudRate: 9600);
      print('Serial port opened');
    } catch (e) {
      print('Error opening serial port: $e');
    }
  }

  void readData() {
    if (_port == null) return;
    _port!.readStream.listen((data) {
      print('Received data: ${String.fromCharCodes(data)}');
    });
  }

  Future<void> writeData(String data) async {
    if (_port == null) return;
    try {
      await _port!.write(Uint8List.fromList(data.codeUnits));
      print('Data written: $data');
    } catch (e) {
      print('Error writing data: $e');
    }
  }

  Future<void> closeSerialPort() async {
    if (_port == null) return;
    try {
      await _port!.close();
      print('Serial port closed');
    } catch (e) {
      print('Error closing serial port: $e');
    }
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Web Serial Example'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            ElevatedButton(
              onPressed: requestSerialPort,
              child: Text('Request Serial Port'),
            ),
            ElevatedButton(
              onPressed: openSerialPort,
              child: Text('Open Serial Port'),
            ),
            ElevatedButton(
              onPressed: () => writeData('Hello, Serial!'),
              child: Text('Write Data'),
            ),
            ElevatedButton(
              onPressed: closeSerialPort,
              child: Text('Close Serial Port'),
            ),
          ],
        ),
      ),
    );
  }
}
回到顶部