Windows Iot Core上的SerialDevice上的读取任务

时间:2019-05-16 13:02:46

标签: serial-port raspberry-pi3 uart windows-10-iot-core

我正在尝试编写一个Task,它将一直运行直到被取消为止,它将读取UART接收到的所有数据,并继续通过已定义的event分派接收到的数据。我希望读循环读取200毫秒,然后返回在该时间片中可能已读取的任何数据(可能包括零数据),或者在读取了完整的缓冲区后(以先到者为准);绝大多数情况下,超时将首先发生。我已经成功地从UART发送了数据,但是即使已经确认设备已在线上接收到数据,我也无法接收任何数据。

SerialDevice device;

// Instantiate the SerialDevice.

device.ReadTimeout = new TimeSpan( 0, 0, 0, 0, 200 );
ReadDataCancellationTokenSource = new CancellationTokenSource();

const uint BufferSize_bytes = 50;

ReadDataTask = Task.Factory.StartNew( async () =>
{
    using( DataReader reader = new DataReader( device.InputStream ) )
    {
       reader.InputStreamOptions = InputStreamOptions.Partial;

       while( !ReadDataCancellationTokenSource.IsCancellationRequested )
       {
          uint dataRead = await reader.LoadAsync( BufferSize_bytes ).AsTask();

          if( dataRead > 0 )
          {
             IBuffer buffer = reader.ReadBuffer( dataRead );
             if( buffer.Length > 0 )
                PropogateReceivedData( ReadBuffer( buffer ) );
          }
       }
    }
}, ReadDataCancellationTokenSource.Token );

PropogateReceivedData( ReadBuffer( buffer ) )调用读取缓冲区中的所有数据,然后分派数据;众所周知这可以正常工作。存储ReadDataCancellationTokenSource成员以在需要时关闭Task

鉴于我在尝试这种方法时遇到的挑战,我想知道它是否应该起作用,或者我是否需要做些什么才能使它起作用。

1 个答案:

答案 0 :(得分:1)

  

我已成功从UART发送数据,但未能成功   即使已确认设备已接收到任何数据   线上的数据。

我不确定您如何“确认设备已从网络上收到数据”。设置InputStreamOptions.Partial时,即使线路上只有一个字节,此行await reader.LoadAsync( BufferSize_bytes ).AsTask();也会返回,您将在缓冲区中得到这个字节。

我也不知道如何处理PropogateReceivedData( ReadBuffer( buffer ) )中接收到的数据,这里我使用以下几行代码将数据转换为字符串并显示在UI中,您可以参考:

                                var dataReader = DataReader.FromBuffer(buffer);
                                rcvdText.Text = dataReader.ReadString(buffer.Length);

我的建议是,如果要获取字符串数据,可以使用reader.ReadString(dataRead);;如果要获取字节流,则可以使用reader.ReadBytes(readData);。您可以参考DataReader来获得更多受支持的API。

  

鉴于我在尝试这种方法时遇到的挑战,我   想知道它是否应该工作,我需要做些什么才能得到它   工作。

是的,您的逻辑应该起作用,除了我之外,读取超时永远不会发生。您可以在设置device.ReadTimeout = new TimeSpan( 0, 0, 0, 0, 200 );时确认读取超时对您有用吗?有超时信息吗?

以下是我从您的问题进行测试的整个代码行,对我来说很有效。

                device.ReadTimeout = new TimeSpan(0, 0, 0, 0, 200);
                var ReadDataCancellationTokenSource = new CancellationTokenSource();

                const uint BufferSize_bytes = 50;

                using (DataReader reader = new DataReader(device.InputStream))
                {
                    reader.InputStreamOptions = InputStreamOptions.Partial;

                    while (!ReadDataCancellationTokenSource.IsCancellationRequested)
                    {
                        uint dataRead = await reader.LoadAsync(BufferSize_bytes).AsTask();

                        if (dataRead > 0)
                        {
                            IBuffer buffer = reader.ReadBuffer(dataRead);
                            if (buffer.Length > 0)
                            {
                                //    rcvdText.Text = reader.ReadString(dataRead);

                                //    var readData = new Byte[dataRead];
                                //    reader.ReadBytes(readData);

                                var dataReader = DataReader.FromBuffer(buffer);
                                rcvdText.Text = dataReader.ReadString(buffer.Length);
                                status.Text = "bytes read successfully!";
                            }
                        }
                    }
                }

Official serial sample您可以参考。