Comments (6)
I also experienced this issue and looked into it a little. The reader code uses the sp_wait call to block waiting for rx bytes to be available. This 'should' block the isolate until bytes are received. However, I found this call was always returning immediately even if no bytes have been received. This results in the isolate running in a loop hence the 100% cpu usage of a single core.
I did not have time to investigate the reason for the non-blocking call to sp_wait but I found that it was relatively simple to write an alternative version of SerialPortReader that replaces the sp_wait() call with a blocking call to read() to wait for a single byte to be received. Obviously, you must send that received byte to the send port as it is valid data but then the rest of the code is largely the same.
This will give you the correct low CPU behaviour and low latency.
Here's my alternative version of _waitRead. The rest of the code is pretty much the same with some simplifications to remove the event code which is no longer used. I am not sure how this will behave if there are serial port errors so use with caution. However, in my limited testing it has performed fine.
static void _waitRead(_SerialPortReaderArgs args) {
SerialPort port = SerialPort.fromAddress(args.address);
while (port.isOpen) {
// Read a single byte. This is a blocking call which will timeout after args.timeout ms.
var first = port.read(1, timeout: args.timeout);
if (first.isNotEmpty) {
// Send the single byte
args.sendPort.send(first);
// Read the rest of the data available.
var toRead = port.bytesAvailable;
if (toRead > 0) {
var remaining = port.read(toRead);
if (remaining.isNotEmpty) {
args.sendPort.send(remaining);
}
}
}
}
}
from flutter_libserialport.
Same issue here, worsened by the fact that my program could have more than one serial port to read from, each greatly increasing the CPU load. I solved by using a timer as suggested above (the 20ms latency is not a problem in my case), but this needs some fixing. Like an option to use either the event system or the first byte workaround.
from flutter_libserialport.
I have the same high CPU usage issue, narrowed it down to listening on SerialPortReader.stream
final reader = SerialPortReader(_sp);
_sub = reader.stream.listen((data) {
/* final List<int> values = [];
for (final v in data) {
values.add(v);
}
_sc.add(values); */
});
if I don't listen on reader
, the cpu usage goes back to normal, if I listen to it, even with an empty listener as shown, the CPU usage goes bad again
Temporary fix:
If I use a timer
instead of SerialPortReader
the problem can be avoided
_t = Timer.periodic(Duration(milliseconds: 40), (timer) {
final data = _sp.read(400);
final List<int> values = [];
for (final v in data) {
values.add(v);
}
if (values.isNotEmpty) _sc.add(values);
});
from flutter_libserialport.
I'm experiencing the same issue here, the SerialPortReader uses 100% of 1 cpu when you listen to its stream.
Timer.periodic is many orders of magnitudes more efficient, even with 1 millisecond interval.
from flutter_libserialport.
@stevecookdev
Thanks a lot for your workaround. I am using it and it works perfectly.
from flutter_libserialport.
@stevecookdev
Thank for your example code. You mentioned: "I am not sure how this will behave if there are serial port errors so use with caution". And you were right: this code snippet doesn't handle error situations like disconnecting an UART-device, etc.
I added the necessary processing:
static void _waitRead(_SerialPortReaderArgs args) {
final fport = ffi.Pointer<sp_port>.fromAddress(args.address);
final events = _createEvents(fport, _kReadEvents);
SerialPort port = SerialPort.fromAddress(args.address);
while (port.isOpen) {
// Read a single byte. This is a blocking call which will timeout after args.timeout ms.
Uint8List first;
try {
first = port.read(1, timeout: args.timeout);
} catch (e) {
args.sendPort.send(SerialPort.lastError);
break;
}
if (first.isNotEmpty) {
// Send the single byte
args.sendPort.send(first);
// Read the rest of the data available.
var toRead = port.bytesAvailable;
if (toRead > 0) {
var remaining = port.read(toRead);
if (remaining.isNotEmpty) {
args.sendPort.send(remaining);
}
}
}
}
_releaseEvents(events);
}
from flutter_libserialport.
Related Issues (20)
- Support for Gradle 8.3.0: Define namespace HOT 2
- Problème lecture et écriture
- android support HOT 5
- Windwos Incomplete writing HOT 1
- read not working on Windows HOT 4
- Cant open port on MacOS HOT 2
- Cant open port on Windows
- Failed to load dynamic library 'libserialport.so' HOT 3
- Android: Namespace not specified
- SerialPortError: Input/output error, errno = 5
- Multiple instances of serial port reader in call stack
- Android support
- It does not send hex numbers 11 and 13 HOT 1
- IOS problem HOT 1
- How to set the baud rate ? HOT 3
- How to read serial data HOT 2
- No running
- Can't read buffer that was not empty before opening serial port (Windows) HOT 3
- How to configure baudrate and port HOT 2
- Can't run android app HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from flutter_libserialport.