libserialport.dart
libserialport.dart copied to clipboard
How to reset serial port when there is an error?
When there is an misconfiguration e.g. like DTR setting, etc, the connecting the serial port will result in error. I can change the configuration within the app but I cannot use the libserialport again because the previous error has corrupted the port.
How I reset the serial port without restarting the app again?
The best way to handle this is to catch the Exception then close the existing reader and serial port connection(s). This would close the corrupted port(s), then go through the port initialization process again.
The problem is there are no Exception raised when DTR is not configured correctly. It is wait/hang indefinitely.
final reader = SerialPortReader(port, timeout: 2000);
reader.port.drain();
reader.port.flush();
print("readSerialPort just before reader.stream.listen((data)\n");
reader.stream.listen((data) {
// Reads stuff
}, onDone: () async {
//>BLUE DONE!
print('done!');
reader.port.drain();
reader.port.flush();
reader.port.close();
serialConfig.dispose();
completer.completeError(ArgumentError("Empty Data! Please check meter"));
} else {
completer.complete(resultString);
}
//port.dispose();
}, onError: (e) {
reader.close();
reader.port.drain();
reader.port.flush();
reader.port.close();
serialConfig.dispose();
reader.port.dispose();
}, cancelOnError: true);
}
}
Would you be able to send a handshake
message to the peripheral to acknowledge the connection? Basically, test the connection with a given configuration first and if it's timed out after a certain interval, then you know it can't be connected with that configuration. Using the stream.timeout()
would let you detect the timed out condition.
final reader = SerialPortReader(port);
try {
port.flush();
final handshake = Uint8List.fromList('handshake_message'.codeUnits);
final result = port.write(handshake);
if (handshake.length != result) {
// Handle write error
return false;
}
final timeout = const Duration(seconds: 2);
// Listen for only one response and timeout after 2 seconds
await for (Uint8List value in reader.stream.timeout(timeout)) {
final response = String.fromCharCodes(value);
// Verify the `value` with the expected handshake response.
// If it's matched, then the connection is valid.
// ...
}
} finally {
port.close();
reader.close();
}
should be await for (Uint8List value in reader.stream.timeout(timeout)) {
?
I am getting old data in the serial stream/pipe. Using MacOS. Despite flush() and drain(), I am getting it. Any pointers?
Assuming you're using a single port for both write
and read
operations, and the old data is the data from the write
operation? I'm not sure if this would help, but try to add a timeout to the write
to use the sp_blocking_write()
in addition to sp_drain()
. Maybe something like this,
final reader = SerialPortReader(port);
try {
port.flush();
final handshake = Uint8List.fromList('handshake_message'.codeUnits);
final result = port.write(handshake, timeout: const Duration(milliseconds: 500).inMilliseconds);
port.write.drain();
if (SerialPort.lastError?.errorCode != 0) { // SP_OK
// Handle write error
return false;
}
if (handshake.length != result) {
// Handle write error
return false;
}
final timeout = const Duration(seconds: 2);
// Listen for only one response and timeout after 2 seconds
await for (Uint8List value in reader.stream.timeout(timeout)) {
final response = String.fromCharCodes(value);
// Verify the `value` with the expected handshake response.
// If it's matched, then the connection is valid.
// ...
}
} finally {
port.close();
reader.close();
}
You might want to consult the C libserialport's documentation for how the write
and read
operations work on Unix-like systems vs Windows, https://sigrok.org/api/libserialport/unstable/index.html