jpnurmi / libserialport.dart

Serial Port for Dart
https://pub.dev/packages/libserialport
GNU Lesser General Public License v3.0
86 stars 34 forks source link

Serial port "hangs" after subsequential read #53

Open eximius313 opened 2 years ago

eximius313 commented 2 years ago

Dear libserialport maintainers.

I have a "echo" serial port device, and I'm trying to perform subsequent reads and writes. My code looks like this:

void main(List<String> args) async {
  await readFromSerial();
}

Future<void> readFromSerial() async {
    List<String> availablePorts = SerialPort.availablePorts;
    print(availablePorts);

    String portAddress = availablePorts.where((p) => p.contains("ACM0")).first;
    print(portAddress);

    SerialPort _serial = SerialPort(portAddress);
    SerialPortReader _reader = SerialPortReader(_serial);

    Stream<Uint8List> _stream = _reader.stream.asBroadcastStream();

    print(">1<");
    await send("1", _serial, _stream);
    print(">2<");
    await send("2", _serial, _stream);

    print("DONE");
  }

  Future<void> send(String id, SerialPort _serial, Stream<Uint8List> _stream) async {
    if (_serial.openReadWrite()) {
      print("PORT OPEN: $id");

      //Solution 1
      Future<Uint8List> result1 = _stream
      .timeout(Duration(milliseconds: 5000), onTimeout: (sink) {
        sink.close();
      })
      .firstWhere((data) {
        print("Data from firstWhere: $data");
        return true;
      }, orElse: () => Uint8List(0));

      //Solution 2
      Future<Uint8List> result2 = _stream.expand(
        (Uint8List data) {
          print('Data from expand: $data');
          return [data];
        }
      ).firstWhere((data) {
        print("Data from firstWhere: $data");
        return true;
      }, orElse: () => Uint8List(0));

    //Solution 3
    Completer<Uint8List> c = Completer();
    _stream.listen(
      (Uint8List data) {
        print('Data from listen: $data');
        c.complete(data);
      }, 
      onError: (err) {
        SerialPortError spe = err as SerialPortError;
        print("${spe.errorCode}: ${spe.message}");
        c.completeError(err);
      }
    );
    Future<Uint8List> result3 = c.future;

      _serial.write(Uint8List.fromList([1,2,3]), timeout: 0);
      _serial.flush();
      _serial.drain();

      print("Result 1: ${await result1}");
      print("Result 2: ${await result2}");
      print("Result 3: ${await result3}");
  } else {
    print("PORT NOT OPEN: $id");
  }
}

The problem is, that sometines the result is:

: /dev/ttyACM0
: >1<
: PORT OPEN: 1
: Data from firstWhere: [1, 2, 3]
: Result 1: [1, 2, 3]
: Data from expand: [1, 2, 3]
: Data from firstWhere: [1, 2, 3]
: Result 2: [1, 2, 3]
: Data from listen: [1, 2, 3]
: Result 3: [1, 2, 3]
: >2<
: PORT NOT OPEN: 2
: DONE

while sometimes it hangs at:

: /dev/ttyACM0
: >1<
: PORT OPEN: 1
: Result 1:

and it's completly random when it hangs and when not!

Can you please make it not hang all the times?