Open riorizki opened 2 years ago
A great example of listening to serial events is implemented in libserialport library:
import 'package:libserialport/libserialport.dart';
final name = SerialPort.availablePorts.first;
final port = SerialPort(name);
if (!port.openReadWrite()) {
print(SerialPort.lastError);
exit(-1);
}
port.write(/* ... */);
final reader = SerialPortReader(port);
reader.stream.listen((data) {
print('received: $data');
});
It's a very nice soluton, so I hope that something simmilar could be implemented in dart_periphery
Same solution could be also developed for GPIO events.
Honestly - I have no idea how to listen to events based on this example, but there is a fantastic library (flutter_gpiod) that provides Stream<SignalEvent> stream = line.onEvent;
method in GpioLine
class and this approach could be very handy in dart_periphery
as well
@pezi , do you consider possibility to improve Serial
and GPIO
handling via Stream
?
Yes - I will write an example using an dart isolate process which passes the serial data via stream. The one thread model of dart/flutter seems to conflicts with polling hardware code - e.g. read serial data with a timeout. I tried at the beginning of this project to encapsulate polling code as a future - didn't worked.
The one thread model of dart/flutter seems to conflicts with polling hardware code - e.g. read serial data with a timeout. I tried at the beginning of this project to encapsulate polling code as a future - didn't worked.
How about using the same mechanisms as libserialport and flutter_gpiod do for Serial and GPIO? I've tested them quite intensively and they're very reliable
Yes I will take a look on these libs on a second step - but as a first step, I want to write/test general code for streaming sensor (Serial/I2C,etc) data with this lib. I wrote a a little flutter-pi app for the the bme680 sensor, air measurement. The demo works, but the code still retrieves data by polling - the i2c bus/sensor is fast enough - there are no visual glichtes in the UI - but I want to change the sensor reading to a stream model.
Awesome! I'm looking forward to see the results!
I started with the first tests - I adapted an isolate example for a long running task: gist code snippet
But this code has the problem, the possibility to stop the polling thread in a clean manner. An isolate can be killed per API, but the hardware ressources are still not closed. The ReceivePort/SendPort isolate communication works like a ping pong - send - wait for a message - reponse. But every waiting code for a termination signal stalls the running polling loop.
Next week I am in poland - familiy business , having more time, I will rethink this problem, and I am honest, I am not a expert for the dart concurrency model.
libserialport uses this approach:
void _startRead() {
_receiver = ReceivePort();
_receiver!.listen((data) {
if (data is SerialPortError) {
_controller.addError(data);
} else if (data is Uint8List) {
_controller.add(data);
}
});
final args = _SerialPortReaderArgs(
address: _port.address,
timeout: _timeout,
sendPort: _receiver!.sendPort,
);
Isolate.spawn(
_waitRead,
args,
debugName: toString(),
).then((value) => _isolate = value);
}
https://github.com/jpnurmi/libserialport.dart/blob/main/lib/src/reader.dart
I played arround with reflection and annotation to pass generic code into a the scope of an isolate. The isolate class calls annotated static methods to pass data to an event stream.
Real world example Cozir CO2 Sensor
Next step - flutter_pi test application.
New subproject which handles isolates is available https://github.com/pezi/flutter-pi-sensor-tester
Hi I'm trying to use this library to receive data from serial (raspberry) how can i listen to incoming data? does it use poll data inside a timer like this?
is using a timer like this good ? or is there another more efficient way?
Thank you for your help