UWP串行端口访问-代码通常不起作用

时间:2019-08-30 00:49:21

标签: uwp serial-port gps

我正在使用标准的NMEA GPS设备。串行端口从设备读取数据,并将数据转换为可以转换为纬度和经度的字符串。这是我正在使用的代码:

    [TestMethod]
    public async Task TestReadAsync()
    {
        var aqs = SerialDevice.GetDeviceSelector("COM6");
        var deviceInformationCollection = await DeviceInformation.FindAllAsync(aqs);
        var goodRead = false;
        uint maxReadCount = 1024;
        var cancellationToken = new CancellationToken();
        var deviceInfo = deviceInformationCollection.FirstOrDefault();

        Assert.IsNotNull(deviceInfo);

        using (var serialDevice = await SerialDevice.FromIdAsync(deviceInfo.Id))
        {
            serialDevice.Parity = SerialParity.None;
            serialDevice.BaudRate = 4800;
            serialDevice.DataBits = 8;

            using (var dataReader = new DataReader(serialDevice.InputStream)
            {
                InputStreamOptions = InputStreamOptions.Partial,
                UnicodeEncoding = UnicodeEncoding.Utf8
            })
            {
                for (var i = 0; i < 15; i++)
                {
                    var dataReaderLoadOperation = dataReader.LoadAsync(maxReadCount);
                    using (var dataReaderLoadTask = dataReaderLoadOperation.AsTask(cancellationToken))
                    {

                        var readByteCount = await dataReaderLoadTask;
                        var buffer = new byte[readByteCount];
                        dataReader.ReadBytes(buffer);

                        var nmeaString = System.Text.Encoding.UTF8.GetString(buffer);

                        if (!string.IsNullOrEmpty(nmeaString))
                        {
                            Console.WriteLine(nmeaString);
                            goodRead = true;
                            break;
                        }
                    }

                    await Task.Delay(900);
                }
            }
        }

        Assert.IsTrue(goodRead);
    }

它工作了一次或两次。即它读取了数据,然后我看到了NMEA字符串。但是,大多数情况下,readByteCount为0。

我也尝试过这种方法,它似乎也可以工作一到两次:

    [TestMethod]
    public async Task TestReadAsync()
    {
        var aqs = SerialDevice.GetDeviceSelector("COM6");
        var deviceInformationCollection = await DeviceInformation.FindAllAsync(aqs);
        var goodRead = false;
        uint maxReadCount = 1024;
        var deviceInfo = deviceInformationCollection.FirstOrDefault();

        Assert.IsNotNull(deviceInfo);
        using (var serialDevice = await SerialDevice.FromIdAsync(deviceInfo.Id))
        {
            serialDevice.Parity = SerialParity.None;
            serialDevice.BaudRate = 4800;
            serialDevice.DataBits = 8;

            for (var i = 0; i < 30; i++)
            {
                var emptyArray = new byte[maxReadCount];
                var emptyBuffer = emptyArray.AsBuffer();
                var buffer = await serialDevice.InputStream.ReadAsync(emptyBuffer, maxReadCount, InputStreamOptions.Partial);

                var data = buffer.ToArray();
                var nmeaString = System.Text.Encoding.UTF8.GetString(data);

                if (!string.IsNullOrEmpty(nmeaString))
                {
                    goodRead = true;
                    Console.WriteLine($"Try: {i} {nmeaString}");
                    break;
                }
            }

            await Task.Delay(900);
        }

        Assert.IsTrue(goodRead);
    }

这里是另一个版本。 readCount总是为0;

    [TestMethod]
    public async Task TestReadAsync()
    {
        var aqs = SerialDevice.GetDeviceSelector("COM6");
        var deviceInformationCollection = await DeviceInformation.FindAllAsync(aqs);
        var goodRead = false;
        var maxReadCount = 1024;
        var deviceInfo = deviceInformationCollection.FirstOrDefault();

        Assert.IsNotNull(deviceInfo);
        using (var serialDevice = await SerialDevice.FromIdAsync(deviceInfo.Id))
        {
            serialDevice.BaudRate = 4800;
            serialDevice.Parity = SerialParity.None;
            serialDevice.DataBits = 8;

            var cancellationTokenSource = new CancellationTokenSource();

            using (var stream = serialDevice.InputStream.AsStreamForRead(0))
            {
                for (var i = 0; i < 100; i++)
                {
                    var buffer = new byte[maxReadCount];
                    var readCount = await stream.ReadAsync(buffer, 0, maxReadCount, cancellationTokenSource.Token);

                    if (readCount > 0)
                    {
                        var nmeaString = System.Text.Encoding.UTF8.GetString(buffer);

                        if (!string.IsNullOrWhiteSpace(nmeaString))
                        {
                            return;
                        }
                    }

                    Task.Delay(10);
                }
            }

        }

        Assert.IsTrue(goodRead);
    }

在具有相同设备的.Net Core(Windows)上,此代码一致地工作。我至少从串行端口获取了一个数据数组。

        using (var serialPortDevice = new WindowsSerialPortDevice(@"\\.\COM6"))
        {
            await serialPortDevice.InitializeAsync();
            var result = await serialPortDevice.ReadAsync();
            Assert.IsTrue(result.Data.Length > 0);
            var range = result.Data.ToList().GetRange(0, 10);
            Assert.IsFalse(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }.SequenceEqual(range));
        }

Above Code

良好的能力:

  <Capabilities>
    <Capability Name="internetClientServer" />
    <Capability Name="privateNetworkClientServer" />
    <DeviceCapability Name="serialcommunication">
      <Device Id="any">
        <Function Type="name:serialPort" />
      </Device>
    </DeviceCapability>
  </Capabilities>

注意:我知道设备正在运行,因为它附带的应用程序能够读取位置,并且我可以在那里看到NMEA数据流。我还尝试了三个不同的USB端口,这些端口最终变成了三个不同的COM端口。

那么,为什么这么片状?获得串口访问以一致地在UWP上工作是否有技巧?有没有从UWP上的串行端口读取方面有经验的人?我是否缺少一些代码?

0 个答案:

没有答案