windows 10 universal (C#) 如何不断读取串口
How can I constantly read the serial port in windows 10 universal (C#)
我想不断读取串行端口并在我的 windows 10 通用应用程序 (C#) 的文本框中获取输出。我从 https://github.com/ms-iot/samples/tree/develop/SerialSample/CS 的 MS 序列样本中找到了这段代码:
private async void Listen()
{
try
{
if (serialPort != null)
{
dataReaderObject = new DataReader(serialPort.InputStream);
while (true)
{
await ReadAsync(ReadCancellationTokenSource.Token);
}
}
}
catch (Exception ex)
{
if (ex.GetType().Name == "TaskCanceledException")
{
CloseDevice();
}
}
finally
{
if (dataReaderObject != null)
{
dataReaderObject.DetachStream();
dataReaderObject = null;
}
}
}
private async Task ReadAsync(CancellationToken cancellationToken)
{
Task<UInt32> loadAsyncTask;
uint ReadBufferLength = 1024;
cancellationToken.ThrowIfCancellationRequested();
dataReaderObject.InputStreamOptions = InputStreamOptions.Partial;
loadAsyncTask = dataReaderObject.LoadAsync(ReadBufferLength).AsTask(cancellationToken);
UInt32 bytesRead = await loadAsyncTask;
if (bytesRead > 0)
{
reciveTextBox.Text = dataReaderObject.ReadString(bytesRead);
}
}
但是当我通过单击按钮调用 Listen() 函数时,有时它会读取端口,有时却不会。
请给出一个不断读取串口并在文本框中给出输出的解决方案
MainPage.xaml.cs的完整代码在这里:http://pastebin.com/dmsTUBmT
我在 GitHub 上有一个例子:Arduino_UWP_App
如果简短描述。
以下是主要变量:
private SerialDevice serialPort = null;
DataReader dataReaderObject = null;
别忘了参考:
using Windows.Devices.SerialCommunication;
using Windows.Devices.Enumeration;
using Windows.Storage.Streams;
首先你应该找到设备
string qFilter = SerialDevice.GetDeviceSelector("COM3");
DeviceInformationCollection devices = await DeviceInformation.FindAllAsync(qFilter);
if (devices.Any())
{
string deviceId = devices.First().Id;
await OpenPort(deviceId);
}
这样你可以打开端口:
private async Task OpenPort(string deviceId)
{
serialPort = await SerialDevice.FromIdAsync(deviceId);
if (serialPort != null)
{
serialPort.WriteTimeout = TimeSpan.FromMilliseconds(1000);
serialPort.ReadTimeout = TimeSpan.FromMilliseconds(1000);
serialPort.BaudRate = 9600;
serialPort.Parity = SerialParity.None;
serialPort.StopBits = SerialStopBitCount.One;
serialPort.DataBits = 8;
serialPort.Handshake = SerialHandshake.None;
}
}
现在您可以收听消息了:
while (true)
{
await Listen();
}
.......
private async Task Listen()
{
if (serialPort != null)
{
dataReaderObject = new DataReader(serialPort.InputStream);
await ReadAsync(ReadCancellationTokenSource.Token);
}
}
.......
private async Task ReadAsync(CancellationToken cancellationToken)
{
Task<UInt32> loadAsyncTask;
uint ReadBufferLength = 256; // only when this buffer would be full next code would be executed
dataReaderObject.InputStreamOptions = InputStreamOptions.Partial;
loadAsyncTask = dataReaderObject.LoadAsync(ReadBufferLength).AsTask(cancellationToken); // Create a task object
UInt32 bytesRead = await loadAsyncTask; // Launch the task and wait until buffer would be full
if (bytesRead > 0)
{
string strFromPort = dataReaderObject.ReadString(bytesRead);
}
}
看来通过操纵读取超时可以收到不同的响应。数字(毫秒)越低,读取速度越高,读取的字节数接近或等于以前的 BytesAvailable。
数字越大,响应越慢,读取缓冲区越满(可能包括来自源设备的多个响应)。
原始的 SerialSample 代码会显示这一点,如果将其修改为在循环中执行预定的定时写入,则可以看到针对每个超时值以不同方式读取的预期响应。
那些试验过 PLC 设备的人可能能够很容易地看到这一点,知道特定 PLC 会产生什么样的响应。
我想不断读取串行端口并在我的 windows 10 通用应用程序 (C#) 的文本框中获取输出。我从 https://github.com/ms-iot/samples/tree/develop/SerialSample/CS 的 MS 序列样本中找到了这段代码:
private async void Listen()
{
try
{
if (serialPort != null)
{
dataReaderObject = new DataReader(serialPort.InputStream);
while (true)
{
await ReadAsync(ReadCancellationTokenSource.Token);
}
}
}
catch (Exception ex)
{
if (ex.GetType().Name == "TaskCanceledException")
{
CloseDevice();
}
}
finally
{
if (dataReaderObject != null)
{
dataReaderObject.DetachStream();
dataReaderObject = null;
}
}
}
private async Task ReadAsync(CancellationToken cancellationToken)
{
Task<UInt32> loadAsyncTask;
uint ReadBufferLength = 1024;
cancellationToken.ThrowIfCancellationRequested();
dataReaderObject.InputStreamOptions = InputStreamOptions.Partial;
loadAsyncTask = dataReaderObject.LoadAsync(ReadBufferLength).AsTask(cancellationToken);
UInt32 bytesRead = await loadAsyncTask;
if (bytesRead > 0)
{
reciveTextBox.Text = dataReaderObject.ReadString(bytesRead);
}
}
但是当我通过单击按钮调用 Listen() 函数时,有时它会读取端口,有时却不会。
请给出一个不断读取串口并在文本框中给出输出的解决方案
MainPage.xaml.cs的完整代码在这里:http://pastebin.com/dmsTUBmT
我在 GitHub 上有一个例子:Arduino_UWP_App
如果简短描述。 以下是主要变量:
private SerialDevice serialPort = null;
DataReader dataReaderObject = null;
别忘了参考:
using Windows.Devices.SerialCommunication;
using Windows.Devices.Enumeration;
using Windows.Storage.Streams;
首先你应该找到设备
string qFilter = SerialDevice.GetDeviceSelector("COM3");
DeviceInformationCollection devices = await DeviceInformation.FindAllAsync(qFilter);
if (devices.Any())
{
string deviceId = devices.First().Id;
await OpenPort(deviceId);
}
这样你可以打开端口:
private async Task OpenPort(string deviceId)
{
serialPort = await SerialDevice.FromIdAsync(deviceId);
if (serialPort != null)
{
serialPort.WriteTimeout = TimeSpan.FromMilliseconds(1000);
serialPort.ReadTimeout = TimeSpan.FromMilliseconds(1000);
serialPort.BaudRate = 9600;
serialPort.Parity = SerialParity.None;
serialPort.StopBits = SerialStopBitCount.One;
serialPort.DataBits = 8;
serialPort.Handshake = SerialHandshake.None;
}
}
现在您可以收听消息了:
while (true)
{
await Listen();
}
.......
private async Task Listen()
{
if (serialPort != null)
{
dataReaderObject = new DataReader(serialPort.InputStream);
await ReadAsync(ReadCancellationTokenSource.Token);
}
}
.......
private async Task ReadAsync(CancellationToken cancellationToken)
{
Task<UInt32> loadAsyncTask;
uint ReadBufferLength = 256; // only when this buffer would be full next code would be executed
dataReaderObject.InputStreamOptions = InputStreamOptions.Partial;
loadAsyncTask = dataReaderObject.LoadAsync(ReadBufferLength).AsTask(cancellationToken); // Create a task object
UInt32 bytesRead = await loadAsyncTask; // Launch the task and wait until buffer would be full
if (bytesRead > 0)
{
string strFromPort = dataReaderObject.ReadString(bytesRead);
}
}
看来通过操纵读取超时可以收到不同的响应。数字(毫秒)越低,读取速度越高,读取的字节数接近或等于以前的 BytesAvailable。
数字越大,响应越慢,读取缓冲区越满(可能包括来自源设备的多个响应)。
原始的 SerialSample 代码会显示这一点,如果将其修改为在循环中执行预定的定时写入,则可以看到针对每个超时值以不同方式读取的预期响应。 那些试验过 PLC 设备的人可能能够很容易地看到这一点,知道特定 PLC 会产生什么样的响应。