如何为 SerialDevice 创建一个 "DataReceived" 事件?
How to create a "DataReceived" Event for SerialDevice?
我正在使用 SerialDevice class 将 RS-485 与我的串行端口一起使用。它目前没有接收数据的事件。我目前必须使用 DataReader 轮询 Listener,它并不总是捕获其缓冲区中的所有数据。
我正在寻找一种方法来为 SerialDevice class 创建接收器事件,这样我就不必进行轮询,并且可以在收到正确数据时立即触发。
我目前的方法:
async void Initialize()
{
DeviceInformationCollection devices = await DeviceInformation.FindAllAsync();
if (devices.Count > 0)
{
for (int i = 0; i < devices.Count; i++)
{
if (devices[i].Id.Contains("PNP0501#2"))
{
GpioStatus = string.Format("Connecting... {0} found", devices[i].Id);
DeviceInformation deviceInfo = devices[i];
serialDevice = await SerialDevice.FromIdAsync(deviceInfo.Id);
serialDevice.BaudRate = 9600;
serialDevice.DataBits = 8;
serialDevice.StopBits = SerialStopBitCount.Two;
serialDevice.Parity = SerialParity.None;
serialDevice.Handshake = SerialHandshake.None;
}
}
}
Listen();
}
Initialize();
DataReader dataReader;
SerialDevice serialDevice;
CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
const uint ReadBufferLength = 1024;
async void Listen()
{
try
{
dataReader = new DataReader(serialDevice.InputStream);
dataReader.InputStreamOptions = InputStreamOptions.Partial;
while (true)
{
await ReadAsync(cancellationTokenSource.Token);
}
}
catch
{
GpioStatus = "Failed to listen";
}
}
private async Task ReadAsync(CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
Task<UInt32> loadAsyncTask = dataReader.LoadAsync(ReadBufferLength).AsTask(cancellationToken);
UInt32 bytesRead = await loadAsyncTask;
GpioStatus = dataReader.ReadString(bytesRead);
}
如有任何想法,我们将不胜感激!
因为它是一个串行协议,所以你需要在输入时进行解释。如果预期的第一件事是(比如说)4 字节长度,然后是数据包的其余部分,那么:
while (dataReader.UnconsumedBufferLength > 0)
{
// Note that the call to readString requires a length of "code units"
// to read. This is the reason each string is preceded by its length
// when "on the wire".
uint bytesToRead = dataReader.ReadUInt32();
receivedStrings += dataReader.ReadString(bytesToRead) + "\n";
}
代码片段取自:https://docs.microsoft.com/en-us/uwp/api/windows.storage.streams.datareader
我正在使用 SerialDevice class 将 RS-485 与我的串行端口一起使用。它目前没有接收数据的事件。我目前必须使用 DataReader 轮询 Listener,它并不总是捕获其缓冲区中的所有数据。
我正在寻找一种方法来为 SerialDevice class 创建接收器事件,这样我就不必进行轮询,并且可以在收到正确数据时立即触发。
我目前的方法:
async void Initialize()
{
DeviceInformationCollection devices = await DeviceInformation.FindAllAsync();
if (devices.Count > 0)
{
for (int i = 0; i < devices.Count; i++)
{
if (devices[i].Id.Contains("PNP0501#2"))
{
GpioStatus = string.Format("Connecting... {0} found", devices[i].Id);
DeviceInformation deviceInfo = devices[i];
serialDevice = await SerialDevice.FromIdAsync(deviceInfo.Id);
serialDevice.BaudRate = 9600;
serialDevice.DataBits = 8;
serialDevice.StopBits = SerialStopBitCount.Two;
serialDevice.Parity = SerialParity.None;
serialDevice.Handshake = SerialHandshake.None;
}
}
}
Listen();
}
Initialize();
DataReader dataReader;
SerialDevice serialDevice;
CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
const uint ReadBufferLength = 1024;
async void Listen()
{
try
{
dataReader = new DataReader(serialDevice.InputStream);
dataReader.InputStreamOptions = InputStreamOptions.Partial;
while (true)
{
await ReadAsync(cancellationTokenSource.Token);
}
}
catch
{
GpioStatus = "Failed to listen";
}
}
private async Task ReadAsync(CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
Task<UInt32> loadAsyncTask = dataReader.LoadAsync(ReadBufferLength).AsTask(cancellationToken);
UInt32 bytesRead = await loadAsyncTask;
GpioStatus = dataReader.ReadString(bytesRead);
}
如有任何想法,我们将不胜感激!
因为它是一个串行协议,所以你需要在输入时进行解释。如果预期的第一件事是(比如说)4 字节长度,然后是数据包的其余部分,那么:
while (dataReader.UnconsumedBufferLength > 0)
{
// Note that the call to readString requires a length of "code units"
// to read. This is the reason each string is preceded by its length
// when "on the wire".
uint bytesToRead = dataReader.ReadUInt32();
receivedStrings += dataReader.ReadString(bytesToRead) + "\n";
}
代码片段取自:https://docs.microsoft.com/en-us/uwp/api/windows.storage.streams.datareader