serial_port_win32 icon indicating copy to clipboard operation
serial_port_win32 copied to clipboard

Read time too much when scanner scanned a barcode.

Open Abduraimbek opened this issue 2 years ago • 4 comments

Thanks for great work. I have problem with scanning barcode. When I scan a barcode with scanner, readBytesOnListen fires after 1 to 2 seconds. What should I do? Thanks for solution.

Abduraimbek avatar Aug 31 '22 11:08 Abduraimbek

What is the size of your data?If data is large, higher baudrate is better.

And async functions may be delayed due to other program.

There some para which you can set: ReadIntervalTimeout, ReadTotalTimeoutConstant,ReadTotalTimeoutMultiplier

Please see https://docs.microsoft.com/en-us/windows/win32/api/winbase/ns-winbase-commtimeouts

 SerialPort(
    String portName, {
    // ignore: non_constant_identifier_names
    int BaudRate = CBR_115200,
    // ignore: non_constant_identifier_names
    int Parity = NOPARITY,
    // ignore: non_constant_identifier_names
    int StopBits = ONESTOPBIT,
    // ignore: non_constant_identifier_names
    int ByteSize = 8,
    // ignore: non_constant_identifier_names
    int ReadIntervalTimeout = 10,
    // ignore: non_constant_identifier_names
    int ReadTotalTimeoutConstant = 1,
    // ignore: non_constant_identifier_names
    int ReadTotalTimeoutMultiplier = 10,

    /// if you want open port when create instance, set [openNow] true
    bool openNow = true,
  })

And I use for-loop lookup function to yield data with stream. If I/O Flag is set, WaitForSingleObject will be called up to 500 times with 1ms lookup duration until transmission is done.

I don't know if changing this parameter will solve your problem. But it does take up CPU time.

 /// look up I/O event and read data using stream
  Stream<Uint8List> _lookUpEvent(Duration interval) async* {
    int event = 0;
    Uint8List data;
    PurgeComm(handler!, PURGE_RXCLEAR | PURGE_TXCLEAR);
    while (true) {
      await Future.delayed(interval);
      event = WaitCommEvent(handler!, _dwCommEvent, _over);
      if (event != 0) {
        ClearCommError(handler!, _errors, _status);
        if (_status.ref.cbInQue < _readBytesSize) {
          data = await _read(_status.ref.cbInQue);
        } else {
          data = await _read(_readBytesSize);
        }
        if (data.isNotEmpty) {
          yield data;
        }
      } else {
        if (GetLastError() == ERROR_IO_PENDING) {
          /// For Loop 
          for (int i = 0; i < 500; i++) {
            if (WaitForSingleObject(_over.ref.hEvent, 0) == 0) {
              ClearCommError(handler!, _errors, _status);
              if (_status.ref.cbInQue < _readBytesSize) {
                data = await _read(_status.ref.cbInQue);
              } else {
                data = await _read(_readBytesSize);
              }
              if (data.isNotEmpty) {
                yield data;
              }
              ResetEvent(_over.ref.hEvent);
              break;
            }
            ResetEvent(_over.ref.hEvent);
            await Future.delayed(interval);
          }
        }
      }
    }
  }

FengChendian avatar Sep 01 '22 07:09 FengChendian

My barcode data as following: AB5229874445395 478999283349943

Thank you for attantion. But I found following in the package:

 SerialPort._internal(
    this.portName,
    this._portNameUtf16, {
    // ignore: non_constant_identifier_names
    required int BaudRate,
    // ignore: non_constant_identifier_names
    required int Parity,
    // ignore: non_constant_identifier_names
    required int StopBits,
    // ignore: non_constant_identifier_names
    required int ByteSize,
    // ignore: non_constant_identifier_names
    required int ReadIntervalTimeout,
    // ignore: non_constant_identifier_names
    required int ReadTotalTimeoutConstant,
    // ignore: non_constant_identifier_names
    required int ReadTotalTimeoutMultiplier,
    required bool openNow,
  }) {
    dcb
      ..ref.BaudRate = BaudRate
      ..ref.Parity = Parity
      ..ref.StopBits = StopBits
      ..ref.ByteSize = ByteSize;
    commTimeouts
      ..ref.ReadIntervalTimeout = 10
      ..ref.ReadTotalTimeoutMultiplier = 10
      ..ref.ReadTotalTimeoutConstant = 1;
    if (openNow) {
      open();
    }
  }

If I set values, it constructs with default values. Or am I thinking wrong?

Abduraimbek avatar Sep 01 '22 13:09 Abduraimbek

@Abduraimbek I test the barcode data with virtual serial port driver. I send data from COM6. Then I can get data immediately in COM5. The delay is about max 10ms. Are you sure that your device has no hardware delay?

image

About parameters: I mean that you can change the default to other values.

FengChendian avatar Sep 07 '22 12:09 FengChendian

Thanks for the reply. I will try with other new scanners.

Abduraimbek avatar Sep 07 '22 16:09 Abduraimbek

I have change code to improve read performance. Now read latency drops.

Updates will be released in version 1.2.0

FengChendian avatar Aug 29 '23 06:08 FengChendian