libserialport_plus 1.0.4 copy "libserialport_plus: ^1.0.4" to clipboard
libserialport_plus: ^1.0.4 copied to clipboard

A Dart wrapper (FFI package) for the libserialport library. This package provides a simple API for communicating over serial ports.

libserialport_plus #

A Flutter wrapper (FFI plugin) for the libserialport library.

This package provides a simple API for communicating over serial ports.

Features #

  • Cross-platform support for Android, Linux, macOS and Windows.
  • Reading and writing bytes to serial ports.
  • Reading bytes from serial ports in a stream.
  • Getting a list of available serial ports.
  • Getting information about serial ports.
  • Getting and setting serial port settings (baud rate, data bits, parity, stop bits, etc.).

Platform support #

Platform Supported
Windows
Linux
macOS
Android
iOS
Web

On unsupported platforms the native library is simply not built, so an app that targets, for example, both iOS and Windows will still compile for iOS. Serial functionality must be guarded by a platform check (e.g. Platform.isWindows); calling into the library on an unsupported platform fails at runtime.

Usage #

Add libserialport_plus as a dependency in your pubspec.yaml file.

flutter pub add libserialport_plus

Import the package in your Dart code:

import 'dart:typed_data';

import 'package:libserialport_plus/libserialport_plus.dart';

void communicate() {
  final ports = SerialPort.getAvailablePorts();
  if (ports.isEmpty) return;

  final port = SerialPort(ports.first);
  try {
    final info = port.getInfo();
    print('${info.name}: ${info.description} (${info.transport.name})');

    port.open();

    final isOpen = port.isOpen();
    if (isOpen) {
      final bytes = port.read(1024, timeout: 1000);
      print('Received ${bytes.length} bytes');

      final message = Uint8List.fromList([0x68, 0x69, 0x0a]);
      final written = port.write(message, timeout: 1000);
      print('Wrote $written bytes');
    }
  } on SerialPortException catch (error) {
    print('Serial port error ${error.code}: ${error.message}');
  } finally {
    if (port.isOpen()) {
      port.close();
    }
    port.dispose();
  }
}

SerialPort accepts the platform-specific name returned by SerialPort.getAvailablePorts(), such as COM3 on Windows or /dev/ttyUSB0 on Linux. Constructing a port does not open it. Always close and dispose the port when finished.

Reading and writing #

read and write operate on bytes using Uint8List. Their timeout is in milliseconds:

  • 0 (default) blocks until data is available or the write completes.
  • A negative value performs a non-blocking operation.
  • A positive value blocks until data is available, the write completes, or the timeout expires.

read may return fewer bytes than requested, and write returns the number of bytes accepted by the native library. Both methods require an open port.

Configuration #

Use SerialPortConfig to read or update serial settings. Every configuration property is optional; a null property is left unchanged by setConfig.

final config = port.getConfig();
print('Current baud rate: ${config.baudRate}');

port.setConfig(const SerialPortConfig(
  baudRate: 115200,
  bits: 8,
  parity: SerialPortParity.none,
  stopBits: 1,
  xonXoff: SerialPortXonXoff.disabled,
));

Background reader #

SerialPortReader reads incoming data on a background isolate and exposes non-empty byte chunks through a stream. The port must be open before creating the reader. Native read errors are delivered as SerialPortException stream errors.

Future<void> readInBackground() async {
  final port = SerialPort('COM3');
  port.open();

  final reader = SerialPortReader(port);

  final subscription = reader.stream.listen((bytes) {
    print('Received ${bytes.length} bytes');
  }, onError: (Object error) {
    if (error is SerialPortException) {
      print('Reader error: ${error.message}');
    }
  });

  // When finished, stop the reader before closing and disposing the port.
  await subscription.cancel();
  await reader.close();
  port.close();
  port.dispose();
}

See the API documentation for the complete public API, including supported serial modes, parity, flow control, and transport types.

macOS #

If creating an app for macOS, serial permissions are required. Enable this by adding the following two lines to DebugProfile.entitlements and Release.entitlements:

<key>com.apple.security.device.serial</key>
<true/>

Development #

To get started you need to initialize the libserialport submodule with:

git submodule update --init --recursive

The native code is compiled at build time by the Dart/Flutter code-assets build hook in hook/build.dart, which uses package:native_toolchain_c to build libserialport for the target platform. Platforms without a serial backend (such as iOS and web) are skipped by the hook, so no native asset is produced for them and consuming apps still build.

Binding to native code #

To use the native code, bindings in Dart are needed. To avoid writing these by hand, they are generated from the header file (src/libserialport/libserialport.h) by package:ffigen. Regenerate the bindings by running dart run tool/ffigen.dart.

3
likes
160
points
5.33k
downloads

Documentation

API reference

Publisher

verified publisherjkob.cc

Weekly Downloads

A Dart wrapper (FFI package) for the libserialport library. This package provides a simple API for communicating over serial ports.

Repository (GitHub)
View/report issues

License

MIT (license)

Dependencies

code_assets, equatable, ffi, hooks, logging, native_toolchain_c

More

Packages that depend on libserialport_plus