I'm trying to implement a ModBus master on Windows 10 IoT on a Raspberry Pi 2. I'm using an external USB to RS-232 adapter since the internal serial port is reserved for Kernel Debugging.
Serial port is working. My question is mainly about timeout when reading.
Here is my code:
// Initialization
serialDevice.ReadTimeout = new TimeSpan(0, 0, 0, allowedTimeBetweenBytes);
serialDataReader.InputStreamOptions = InputStreamOptions.Partial;
// Reading
uint bytesRead = await serialDataReader.LoadAsync(MaxBufferSize); // 256
// Now use ReadBytes to get actual bytes
With no bytes awailable at the serial port RX input, I'm expecting the LoadAsync method to return 0 after wait. Unfortunately, it never returns. (Ok, it DOES return after 256 bytes are received, but that is not what I want)
Since ModBus intensively uses timeouts, I am not sure how to implement it. I am not even sure I could do it...
Does anyone already used timeouts on Windows 10 IoT serial ports?
Yeah, I couldn't get this working either. I'm not sure where ReadTimeout
is actually used by the SerialDevice
class internally. But I did end up getting something working by copying the timeout to a CancellationTokenSource
.
You can see it in use in the following example I wrote for an old serial Mettler Toledo PS 60 shipping scale, where device
is an instance of SerialDevice
. Seems to work in my case, at least.
using (var writer = new DataWriter(device.OutputStream))
{
writer.WriteString("W\r\n");
using (var cts = new CancellationTokenSource(device.WriteTimeout))
{
await writer.StoreAsync().AsTask(cts.Token);
}
writer.DetachStream();
}
using (var reader = new DataReader(device.InputStream))
{
using (var cts = new CancellationTokenSource(device.ReadTimeout))
{
var read = await reader.LoadAsync(12).AsTask(cts.Token);
if (read >= 12)
{
var data = reader.ReadString(12);
reader.DetachStream();
return ExtractWeightChangedEventArgs(data);
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With