jpnurmi / flutter_libserialport

Serial Port for Flutter
https://pub.dev/packages/flutter_libserialport
MIT License
139 stars 80 forks source link

Sending/receiving packets #85

Closed kdesroch1 closed 2 months ago

kdesroch1 commented 9 months ago

New to Flutter, but have years of experience writing C code for embedded devices. Trying to wrap my head around how the data flow works with Dart and with this particular library. I'm finding examples of how to send a few bytes back and forth to do some simple things with an Arduino, but I'm not finding anything that shows a structured packet exchange over a serial link for something like XModem. Where you receive a fixed sized packets (128 bytes) and reassemble them at the receiver.

image

I've managed to get some code that will wait until at least 5 bytes are received before doing anything with it, and it work if I send one byte at a time. But if I send a bunch of bytes, it prints them all. The way they get split up is not consistent either ( data.length is not consistent from upcommingData.listen(data)) . Tried making buffer Uint8List, but appending data to it with .add or .addAll doesn't seem to work.

I know this code is not the best way to do it, but it's all that I've been able to get working. Haven't figured out the SerialPortBuffer() and can't find any examples. Have also tried using ChunkedStreamReader without any success (also no examples beyond what's in the API documents)

Any help would be appreciated.

` List availablePort = SerialPort.availablePorts; SerialPort port = SerialPort('COM8'); SerialPortReader reader = SerialPortReader(port); List buffer = []; // Doesn't work with just Uint8List int bufferIndex = 0;

debugPrint('Available Ports: $availablePort');

// Incoming serial port stream
Stream<Uint8List> upcommingData = reader.stream.map((data) {
  return data;
});

try {
  port.openReadWrite();
  initSerial(port);

  // Send data to serial port
  serialSend(port, 'Testing');

  upcommingData.listen((data) {
    buffer.add(data);
    bufferIndex += data.length;

    if (bufferIndex >= 5) {
      String strBuffer = '';
      for (var letter in buffer) {
        strBuffer += String.fromCharCodes(letter);
      }
      debugPrint('Buffer: $strBuffer');
      bufferIndex = 0;
      buffer = [];
      strBuffer = '';
    }
  });
} on SerialPortError catch (err, _) {
  if (kDebugMode) {
    print(SerialPort.lastError);
  }
  port.close();
} finally {
  // Catch anything not caught
}

`

kdesroch1 commented 9 months ago

So, after trying unsuccessfully to use ChunkedStreamReader and to figure out SerialPortBuffer, I discovered that Uint8List cannot be manipulated like other List in Flutter. Seems easier to make the buffer as List and then change it back to Uint8List if need by using String.fromCharCodes(). Using int for Uint8 data seems wasteful, but I can't figure out a better way.

` List availablePort = SerialPort.availablePorts; SerialPort port = SerialPort('COM8'); SerialPortReader reader = SerialPortReader(port); List buffer = []; int bufferIndex = 0;

debugPrint('Available Ports: $availablePort');

// Incoming serial port stream
Stream<Uint8List> upcommingData = reader.stream.map((data) {
  return data;
});

try {
  port.openReadWrite();
  initSerial(port);

  // Send data to serial port
  serialSend(port, 'Testing');

  upcommingData.listen((data) {
    buffer += data;
    bufferIndex += data.length;

    if (bufferIndex >= 5) {
      String strBuffer = String.fromCharCodes(buffer);
      debugPrint('Buffer: $strBuffer');
      bufferIndex = 0;
      buffer = [];
    }
  });
} on SerialPortError catch (err, _) {
  if (kDebugMode) {
    print(SerialPort.lastError);
  }
  port.close();
} finally {
  // Catch anything not caught
}

`

lucafabbri commented 2 months ago

hi @kdesroch1 I see that you manage to solve the case, could I close this one?

kdesroch1 commented 2 months ago

hi @kdesroch1 I see that you manage to solve the case, could I close this one?

Sure