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 会产生什么样的响应。