2016-04-29 27 views
0

我想不断读取串行端口,并在我的Windows 10通用应用程序(C#)的文本框中获得输出。我发现从MS系列样品此代码https://github.com/ms-iot/samples/tree/develop/SerialSample/CS我怎样才能不断读取在Windows 10通用(C#)的串行端口

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); 
     } 
    } 

但是当我打电话听()函数与点击一个按钮,有时它有时读端口没有。

请给出一个解决方案,它会不断读取串行端口并在文本框中输出结果。

MainPage.xaml.cs中的全部代码是在这里:http://pastebin.com/dmsTUBmT

回答

2

我在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); 
     } 
    } 
+0

尽管此链接可能回答问题,但最好在此处包含答案的基本部分,并提供供参考的链接。如果链接页面更改,则仅链接答案可能会失效。 – Marusyk

0

看来,通过操纵读取超时时间可以收到不同的响应。数字越小(毫秒),读取速度越高,读取的字节越接近或等于BytesAvailable。

数字越高,响应越慢并具有更完整的读取缓冲区(可能包含来自源设备的多个响应)。

原始SerialSample代码会显示此内容,如果修改为在循环中执行预定义的定时写操作,那么可以看到以不同方式读取每个超时值的预期响应。那些对PLC设备进行实验的人可能会很容易地知道这一点,知道对特定PLC有何期望的响应。

+0

老实说,我不明白这可能与这个问题有关,“有时它读端口有时它不。” –