gpiod 1.0.0

  • Readme
  • Changelog
  • Example
  • Installing
  • new45

gpiod #

A library for GPIO access on linux using libgpiod.

You need to have libgpiod.so on your system for it to work. You can install it using sudo apt install gpiod.

proxy_gpiod #

A proxy library for GPIO access on linux using libgpiod.

You need to have libproxy_gpiod.so and libgpiod.so on your system for it to work. You can install 'libgpiod' using sudo apt install gpiod.

You can build 'libproxy_gpiod.so' using : cd proxy_gpiod ./build.sh

Getting Started #

Then, you can retrieve the list of GPIO chips attached to your system using [ProxyGpiod.chips]. Each chip has a name, label and a number of GPIO lines associated with it.

final gpio = ProxyGpiod.getInstance();

final chips = gpio.chips;

for (final chip in chips) {
    print("chip name: ${chip.name}, chip label: ${chip.label}");

    for (final line in chip.lines) {
        print("  line: $line");
    }
}

Each line also has some information associated with it that can be retrieved using [GpioLine.info]. The information can change at any time if the line is not owned/requested by you.

// Get the instance of the FlutterGpiod singleton.
final gpio = ProxyGpiod.getInstance();

// Get the chip with label 'pinctrl-bcm2835'.
// This is the main Raspberry Pi GPIO chip.
final chip = gpio.chips.singleWhere((chip) => chip.label == 'pinctrl-bcm2835');

// Get line 22 of the 'pinctrl-bcm2835' GPIO chip.
// This is the BCM 22 pin of the Raspberry Pi.
final line = chip.lines[22];

print("line info: ${await line.info}")

To control a line (to read or write values or to listen for edges), you need to request it using [GpioLine.requestInput] or [GpioLine.requestOutput].

final gpio = ProxyGpiod.getInstance();
final chip = gpio.chips.singleWhere((chip) => chip.label == 'pinctrl-bcm2835');
final line = chip.lines[22];

// request it as input.
line.requestInput();
print("line value: ${line.getValue()}");
line.release();

// now we're requesting it as output.
line.requestOutput(initialValue: true);
line.setValue(false);
line.release();

// request it as input again, but this time we're also listening
// for edges; both in this case.
line.requestInput(triggers: {SignalEdge.falling, SignalEdge.rising});

print("line value: ${line.getValue()}");

// line.onEvent will not emit any events if no triggers
// are requested for the line.
// this will run forever
for (final event in line.onEvent) {
  print("got GPIO line signal event: $event");
}

line.release();

1.0.0 #

  • implement FFI for proxy_gpiod
  • remove epoll, pthread

0.1.0 #

  • fix lot of bugs

0.0.2+1 #

  • Added constants

0.0.1 #

  • Initial release.

example/main.dart

import 'package:gpiod/proxy_gpiod.dart';


void main() async {
  try {
    final gpio = ProxyGpiod.getInstance();
    _status(gpio.chips);
    await _led(gpio.chips);
    await _pirTest(gpio.chips);
    await _button(gpio.chips);
    _status(gpio.chips);
  } catch(e, st){
    print('Error $e $st');
  }
}


Future _pirTest(List<GpioChip> chips) async{
  print('PIR');
  final lineLED =
  chips.singleWhere((chip) => chip.label == 'pinctrl-bcm2835').lines[14];
  final linePIR =
  chips.singleWhere((chip) => chip.label == 'pinctrl-bcm2835').lines[17];

  /// Request BCM 14 as output.
  lineLED.requestOutput(
      consumer: "flutter_gpiod test", initialValue: true);

  for (var i = 0; i<2 ;i++) {
    /// Pulse the line.
    /// Set it to inactive. (so low voltage = GND)
    lineLED.setValue(false);
    await Future.delayed(Duration(milliseconds: 500));
    lineLED.setValue(true);
    await Future.delayed(Duration(milliseconds: 500));
  }
  lineLED.setValue(false);

  linePIR.requestInput(
      consumer: "PIR",
      //        activeState: ActiveState.low,
      triggers: {SignalEdge.falling, SignalEdge.rising});

  /// Log line events for eternity.
  linePIR.onEvent.listen((event){
    print("PIR: $event");
    lineLED.setValue(event.edge == SignalEdge.falling);
  });

//    await lineLED.release();
//    await linePIR.release();
}


Future _led(List<GpioChip> chips) async {
  print('LED');
  /// Retrieve the line with index 23 of the first chip.
  /// This is BCM pin 23 for the Raspberry Pi.
  ///
  /// I recommend finding the chip you want
  /// based on the chip label, as is done here.
  ///
  /// In this example, we search for the main Raspberry Pi GPIO chip,
  /// which has the label `pinctrl-bcm2835`, and then retrieve the line
  /// with index 14 of it. So [line] is GPIO pin BCM 14.
  final line14 =
  chips.singleWhere((chip) => chip.label == 'pinctrl-bcm2835').lines[14];

  /// Request BCM 14 as output.
  line14.requestOutput(
      consumer: "flutter_gpiod test", initialValue: true);

  for (var i = 0; i<5 ;i++) {
    /// Pulse the line.
    /// Set it to inactive. (so low voltage = GND)
    line14.setValue(false);
    await Future.delayed(Duration(milliseconds: 500));
    line14.setValue(true);
    await Future.delayed(Duration(milliseconds: 500));
  }
  line14.release();
}

Future _button(List<GpioChip> chips) {
  print('BUTTON');
  final line15 =
  chips.singleWhere((chip) => chip.label == 'pinctrl-bcm2835').lines[15];

  line15.requestInput(
      consumer: "BUTTON",
      activeState: ActiveState.high,
      triggers: {SignalEdge.falling, SignalEdge.rising});

  /// Log line events for eternity.
  line15.onEvent.listen((event) {
    print("Button: $event");
  });

//   /// Release the line, though we'll never reach this point.
//    await line15.release();
}

Future _status(List<GpioChip> chips) {
  /// Print out all GPIO chips and all lines
  /// for all GPIO chips.
  for (var chip in chips) {
    print("$chip");

    var index = 0;
    for (var line in chip.lines) {
      final info = line.info;
      if (info.consumer!=null) {
        print("$index:  ${line.info}");
      }

      index++;
    }
  }
}

Use this package as a library

1. Depend on it

Add this to your package's pubspec.yaml file:


dependencies:
  gpiod: ^1.0.0

2. Install it

You can install packages from the command line:

with pub:


$ pub get

with Flutter:


$ flutter pub get

Alternatively, your editor might support pub get or flutter pub get. Check the docs for your editor to learn more.

3. Import it

Now in your Dart code, you can use:


import 'package:gpiod/gpiod.dart';
  
Popularity:
Describes how popular the package is relative to other packages. [more]
20
Health:
Code health derived from static analysis. [more]
75
Maintenance:
Reflects how tidy and up-to-date the package is. [more]
60
Overall:
Weighted score of the above. [more]
45
Learn more about scoring.

We analyzed this package on May 23, 2020, and provided a score, details, and suggestions below. Analysis was completed with status completed using:

  • Dart: 2.8.1
  • pana: 0.13.8-dev

Health suggestions

Fix lib/src/bindings/gpiod/constants.dart. (-13.53 points)

Analysis of lib/src/bindings/gpiod/constants.dart reported 29 hints, including:

line 1 col 1: Prefer using /// for doc comments.

line 9 col 3: Prefer using /// for doc comments.

line 10 col 69: Avoid const keyword.

line 12 col 3: Prefer using /// for doc comments.

line 13 col 69: Avoid const keyword.

Fix lib/src/bindings/proxy_gpiod/constants.dart. (-9.99 points)

Analysis of lib/src/bindings/proxy_gpiod/constants.dart reported 21 hints, including:

line 6 col 3: Prefer using /// for doc comments.

line 7 col 38: Avoid const keyword.

line 9 col 3: Prefer using /// for doc comments.

line 10 col 39: Avoid const keyword.

line 25 col 3: Prefer using /// for doc comments.

Fix lib/src/bindings/gpiod/types.dart. (-3.93 points)

Analysis of lib/src/bindings/gpiod/types.dart reported 8 hints, including:

line 290 col 3: Prefer using /// for doc comments.

line 294 col 3: Prefer using /// for doc comments.

line 298 col 3: Prefer using /// for doc comments.

line 315 col 3: Prefer using /// for doc comments.

line 453 col 15: Unnecessary new keyword.

Fix additional 6 files with analysis or formatting issues. (-3.98 points)

Additional issues in the following files:

  • lib/proxy_gpiod.dart (4 hints)
  • lib/src/bindings/gpiod/bindings.dart (3 hints)
  • lib/src/bindings/proxy_gpiod/bindings.dart (1 hint)
  • lib/src/bindings/gpiod/signatures.dart (Run dartfmt to format lib/src/bindings/gpiod/signatures.dart.)
  • lib/src/bindings/proxy_gpiod/signatures.dart (Run dartfmt to format lib/src/bindings/proxy_gpiod/signatures.dart.)
  • lib/src/bindings/proxy_gpiod/types.dart (Run dartfmt to format lib/src/bindings/proxy_gpiod/types.dart.)

Maintenance issues and suggestions

Make sure dartdoc successfully runs on your package's source files. (-10 points)

Running dartdoc failed with the following output: NoSuchMethodError: The getter 'attributes' was called on null. Receiver: null Tried calling: attributes

#0      DartdocCustomizer._addPubPackageLink (package:pub_dev/dartdoc/customization.dart:168:17)
#1      DartdocCustomizer.customizeHtml (package:pub_dev/dartdoc/customization.dart:61:7)
#2      DartdocCustomizer.customizeFile (package:pub_dev/dartdoc/customization.dart:35:31)
<asynchronous suspension>
#3      DartdocCustomizer.customizeDir (package:pub_dev/dartdoc/customization.dart:26:25)
<asynchronous suspension>
#4      DartdocJobProcessor.process (package:pub_dev/dartdoc/dartdoc_runner.dart:209:14)
<asynchronous suspension>
#5      JobProcessor.run (package:pub_dev/job/job.dart:65:28)
<asynchronous suspension>
#6      JobMaintenance.run (package:pub_dev/job/job.dart:106:18)
#7      _workerMain.<anonymous closure> (package:pub_dev/service/entrypoint/dartdoc.dart:108:26)
#8      StackZoneSpecification._registerUnaryCallback.<anonymous closure>.<anonymous closure> (package:stack_trace/src/stack_zone_specification.dart:129:26)
#9      StackZoneSpecification._run (package:stack_trace/src/stack_zone_specification.dart:209:15)
#10     StackZoneSpecification._registerUnaryCallback.<anonymous closure> (package:stack_trace/src/stack_zone_specification.dart:129:14)
#11     _rootRunUnary (dart:async/zone.dart:1192:38)
#12     _CustomZone.runUnary (dart:async/zone.dart:1085:19)
#13     _FutureListener.handleValue (dart:async/future_impl.dart:141:18)
#14     Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:682:45)
#15     Future._propagateToListeners (dart:async/future_impl.dart:711:32)
#16     Future._completeWithValue (dart:async/future_impl.dart:526:5)
#17     _AsyncAwaitCompleter.complete (dart:async-patch/async_patch.dart:36:15)
#18     _completeOnAsyncReturn (dart:async-patch/async_patch.dart:298:13)
#19     DartdocJobProcessor.generateDocsForSdk (package:pub_dev/dartdoc/dartdoc_runner.dart)
#20     StackZoneSpecification._registerUnaryCallback.<anonymous closure>.<anonymous closure> (package:stack_trace/src/stack_zone_specification.dart:129:26)
#21     StackZoneSpecification._run (package:stack_trace/src/stack_zone_specification.dart:209:15)
#22     StackZoneSpecification._registerUnaryCallback.<anonymous closure> (package:stack_trace/src/stack_zone_specification.dart:129:14)
#23     _rootRunUnary (dart:async/zone.dart:1192:38)
#24     _CustomZone.runUnary (dart:async/zone.dart:1085:19)
#25     _FutureListener.handleValue (dart:async/future_impl.dart:141:18)
#26     Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:682:45)
#27     Future._propagateToListeners (dart:async/future_impl.dart:711:32)
#28     Future._completeWithValue (dart:async/future_impl.dart:526:5)
#29     _AsyncAwaitCompleter.complete (dart:async-patch/async_patch.dart:36:15)
#30     _completeOnAsyncReturn (dart:async-patch/async_patch.dart:298:13)
#31     VersionedJsonStorage.hasCurrentData (package:pub_dev/shared/storage.dart)
#32     StackZoneSpecification._registerUnaryCallback.<anonymous closure>.<anonymous closure> (package:stack_trace/src/stack_zone_specification.dart:129:26)
#33     StackZoneSpecification._run (package:stack_trace/src/stack_zone_specification.dart:209:15)
#34     StackZoneSpecification._registerUnaryCallback.<anonymous closure> (package:stack_trace/src/stack_zone_specification.dart:129:14)
#35     _rootRunUnary (dart:async/zone.dart:1192:38)
#36     _CustomZone.runUnary (dart:async/zone.dart:1085:19)
#37     _FutureListener.handleValue (dart:async/future_impl.dart:141:18)
#38     Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:682:45)
#39     Future._propagateToListeners (dart:async/future_impl.dart:711:32)
#40     Future._completeWithValue (dart:async/future_impl.dart:526:5)
#41     _AsyncAwaitCompleter.complete (dart:async-patch/async_patch.dart:36:15)
#42     _completeOnAsyncReturn (dart:async-patch/async_patch.dart:298:13)
#43     ApiRequester.request (package:_discoveryapis_commons/src/clients.dart)
#44     StackZoneSpecification._registerUnaryCallback.<anonymous closure>.<anonymous closure> (package:stack_trace/src/stack_zone_specification.dart:129:26)
#45     StackZoneSpecification._run (package:stack_trace/src/stack_zone_specification.dart:209:15)
#46     StackZoneSpecification._registerUnaryCallback.<anonymous closure> (package:stack_trace/src/stack_zone_specification.dart:129:14)
#47     _rootRunUnary (dart:async/zone.dart:1192:38)
#48     _CustomZone.runUnary (dart:async/zone.dart:1085:19)
#49     _FutureListener.handleValue (dart:async/future_impl.dart:141:18)
#50     Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:682:45)
#51     Future._propagateToListeners (dart:async/future_impl.dart:711:32)
#52     Future._complete (dart:async/future_impl.dart:516:7)
#53     Stream.join.<anonymous closure> (dart:async/stream.dart:847:18)
#54     StackZoneSpecification._run (package:stack_trace/src/stack_zone_specification.dart:209:15)
#55     StackZoneSpecification._registerCallback.<anonymous closure> (package:stack_trace/src/stack_zone_specification.dart:119:48)
#56     _rootRun (dart:async/zone.dart:1180:38)
#57     _CustomZone.run (dart:async/zone.dart:1077:19)
#58     _CustomZone.runGuarded (dart:async/zone.dart:979:7)
#59     _BufferingStreamSubscription._sendDone.sendDone (dart:async/stream_impl.dart:392:13)
#60     _BufferingStreamSubscription._sendDone (dart:async/stream_impl.dart:402:15)
#61     _BufferingStreamSubscription._close (dart:async/stream_impl.dart:286:7)
#62     _SinkTransformerStreamSubscription._close (dart:async/stream_transformers.dart:98:11)
#63     _EventSinkWrapper.close (dart:async/stream_transformers.dart:25:11)
#64     _StringAdapterSink.close (dart:convert/string_conversion.dart:251:11)
#65     _Utf8ConversionSink.close (dart:convert/string_conversion.dart:302:20)
#66     _ConverterStreamEventSink.close (dart:convert/chunked_conversion.dart:83:18)
#67     _SinkTransformerStreamSubscription._handleDone (dart:async/stream_transformers.dart:143:24)
#68     StackZoneSpecification._run (package:stack_trace/src/stack_zone_specification.dart:209:15)
#69     StackZoneSpecification._registerCallback.<anonymous closure> (package:stack_trace/src/stack_zone_specification.dart:119:48)
#70     _rootRun (dart:async/zone.dart:1180:38)
#71     _CustomZone.run (dart:async/zone.dart:1077:19)
#72     _CustomZone.runGuarded (dart:async/zone.dart:979:7)
#73     _BufferingStreamSubscription._sendDone.sendDone (dart:async/stream_impl.dart:392:13)
#74     _BufferingStreamSubscription._sendDone (dart:async/stream_impl.dart:402:15)
#75     _BufferingStreamSubscription._close (dart:async/stream_impl.dart:286:7)
#76     _ForwardingStream._handleDone (dart:async/stream_pipe.dart:108:10)
#77     _ForwardingStreamSubscription._handleDone (dart:async/stream_pipe.dart:174:13)
#78     StackZoneSpecification._run (package:stack_trace/src/stack_zone_specification.dart:209:15)
#79     StackZoneSpecification._registerCallback.<anonymous closure> (package:stack_trace/src/stack_zone_specification.dart:119:48)
#80     _rootRun (dart:async/zone.dart:1180:38)
#81     _CustomZone.run (dart:async/zone.dart:1077:19)
#82     _CustomZone.runGuarded (dart:async/zone.dart:979:7)
#83     _BufferingStreamSubscription._sendDone.sendDone (dart:async/stream_impl.dart:392:13)
#84     _BufferingStreamSubscription._sendDone (dart:async/stream_impl.dart:402:15)
#85     _BufferingStreamSubscription._close (dart:async/stream_impl.dart:286:7)
#86     _ForwardingStream._handleDone (dart:async/stream_pipe.dart:108:10)
#87     _ForwardingStreamSubscription._handleDone (dart:async/stream_pipe.dart:174:13)
#88     StackZoneSpecification._run (package:stack_trace/src/stack_zone_specification.dart:209:15)
#89     StackZoneSpecification._registerCallback.<anonymous closure> (package:stack_trace/src/stack_zone_specification.dart:119:48)
#90     _rootRun (dart:async/zone.dart:1180:38)
#91     _CustomZone.run (dart:async/zone.dart:1077:19)
#92     _CustomZone.runGuarded (dart:async/zone.dart:979:7)
#93     _BufferingStreamSubscription._sendDone.sendDone (dart:async/stream_impl.dart:392:13)
#94     _BufferingStreamSubscription._sendDone (dart:async/stream_impl.dart:402:15)
#95     _BufferingStreamSubscription._close (dart:async/stream_impl.dart:286:7)
#96     _SyncStreamControllerDispatch._sendDone (dart:async/stream_controller.dart:787:19)
#97     _StreamController._closeUnchecked (dart:async/stream_controller.dart:644:7)
#98     _StreamController.close (dart:async/stream_controller.dart:637:5)
#99     _HttpParser._closeIncoming (dart:_http/http_parser.dart:1121:23)
#100    _HttpParser._doParse (dart:_http/http_parser.dart:815:15)
#101    _HttpParser._parse (dart:_http/http_parser.dart:328:7)
#102    _HttpParser._onData (dart:_http/http_parser.dart:850:5)
#103    StackZoneSpecification._registerUnaryCallback.<anonymous closure>.<anonymous closure> (package:stack_trace/src/stack_zone_specification.dart:129:26)
#104    StackZoneSpecification._run (package:stack_trace/src/stack_zone_specification.dart:209:15)
#105    StackZoneSpecification._registerUnaryCallback.<anonymous closure> (package:stack_trace/src/stack_zone_specification.dart:129:14)
#106    _rootRunUnary (dart:async/zone.dart:1192:38)
#107    _CustomZone.runUnary (dart:async/zone.dart:1085:19)
#108    _CustomZone.runUnaryGuarded (dart:async/zone.dart:987:7)
#109    _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:339:11)
#110    _BufferingStreamSubscription._add (dart:async/stream_impl.dart:266:7)
#111    _SyncStreamControllerDispatch._sendData (dart:async/stream_controller.dart:779:19)
#112    _StreamController._add (dart:async/stream_controller.dart:655:7)
#113    _StreamController.add (dart:async/stream_controller.dart:597:5)
#114    _Socket._onData (dart:io-patch/socket_patch.dart:1982:41)
#115    StackZoneSpecification._registerUnaryCallback.<anonymous closure>.<anonymous closure> (package:stack_trace/src/stack_zone_specification.dart:129:26)
#116    StackZoneSpecification._run (package:stack_trace/src/stack_zone_specification.dart:209:15)
#117    StackZoneSpecification._registerUnaryCallback.<anonymous closure> (package:stack_trace/src/stack_zone_specification.dart:129:14)
#118    _rootRunUnary (dart:async/zone.dart:1192:38)
#119    _CustomZone.runUnary (dart:async/zone.dart:1085:19)
#120    _CustomZone.runUnaryGuarded (dart:async/zone.dart:987:7)
#121    _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:339:11)
#122    _BufferingStreamSubscription._add (dart:async/stream_impl.dart:266:7)
#123    _SyncStreamControllerDispatch._sendData (dart:async/stream_controller.dart:779:19)
#124    _StreamController._add (dart:async/stream_controller.dart:655:7)
#125    _StreamController.add (dart:async/stream_controller.dart:597:5)
#126    _RawSecureSocket._sendReadEvent (dart:io/secure_socket.dart:1018:19)
#127    StackZoneSpecification._run (package:stack_trace/src/stack_zone_specification.dart:209:15)
#128    StackZoneSpecification._registerCallback.<anonymous closure> (package:stack_trace/src/stack_zone_specification.dart:119:48)
#129    _rootRun (dart:async/zone.dart:1180:38)
#130    _CustomZone.run (dart:async/zone.dart:1077:19)
#131    _CustomZone.runGuarded (dart:async/zone.dart:979:7)
#132    _CustomZone.bindCallbackGuarded.<anonymous closure> (dart:async/zone.dart:1019:23)
#133    StackZoneSpecification._run (package:stack_trace/src/stack_zone_specification.dart:209:15)
#134    StackZoneSpecification._registerCallback.<anonymous closure> (package:stack_trace/src/stack_zone_specification.dart:119:48)
#135    _rootRun (dart:async/zone.dart:1184:13)
#136    _CustomZone.run (dart:async/zone.dart:1077:19)
#137    _CustomZone.bindCallback.<anonymous closure> (dart:async/zone.dart:1003:23)
#138    Timer._createTimer.<anonymous closure> (dart:async-patch/timer_patch.dart:23:15)
#139    _Timer._runTimers (dart:isolate-patch/timer_impl.dart:398:19)
#140    _Timer._handleMessage (dart:isolate-patch/timer_impl.dart:429:5)
#141    _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:168:12)

Homepage URL isn't helpful. (-10 points)

Update the homepage field from pubspec.yaml: link to a website about the package or use the source repository URL.

The package description is too short. (-20 points)

Add more detail to the description field of pubspec.yaml. Use 60 to 180 characters to describe the package, what it does, and its target use case.

Dependencies

Package Constraint Resolved Available
Direct dependencies
Dart SDK >=2.7.0 <3.0.0
async ^2.4.0 2.4.1
ffi ^0.1.3 0.1.3
meta ^1.1.8 1.1.8
Transitive dependencies
collection 1.14.12