【问题标题】:C# UWP reading serial data throws exceptionC# UWP 读取串行数据抛出异常
【发布时间】:2018-12-06 15:51:59
【问题描述】:

所以我找到了一种使用 windows 10 iot core 从 UART 通道读取串行数据的方法。现在,我吐出了一些数据,但是它立即崩溃并返回Exception thrown: 'System.NullReferenceException' in System.Private.CoreLib.ni.dll

我用来获取数据的代码:

private async Task read_gps_data(string port = "UART0", int baud = 9600)
        {
            try
            {
                await Task.Run(async () =>
                {
                    while (true)
                    {
                        await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async () =>
                        {
                            string aqs = SerialDevice.GetDeviceSelector("UART0");                   /* Find the selector string for the serial device   */
                            var dis = await DeviceInformation.FindAllAsync(aqs);                    /* Find the serial device with our selector string  */
                            SerialDevice SerialPort = await SerialDevice.FromIdAsync(dis[0].Id);    /* Create an serial device with our selected device */

                            /* Configure serial settings */
                            SerialPort.WriteTimeout = TimeSpan.FromMilliseconds(1000);
                            SerialPort.ReadTimeout = TimeSpan.FromMilliseconds(1000);
                            SerialPort.BaudRate = 9600;                                             /* mini UART: only standard baudrates */
                            SerialPort.Parity = SerialParity.None;                                  /* mini UART: no parities */
                            SerialPort.StopBits = SerialStopBitCount.One;                           /* mini UART: 1 stop bit */
                            SerialPort.DataBits = 8;

                            ///* Write a string out over serial */
                            //string txBuffer = "Hello Serial";
                            //DataWriter dataWriter = new DataWriter();
                            //dataWriter.WriteString(txBuffer);
                            //uint bytesWritten = await SerialPort.OutputStream.WriteAsync(dataWriter.DetachBuffer());

                            /* Read data in from the serial port */
                            const uint maxReadLength = 1024;
                            DataReader dataReader = new DataReader(SerialPort.InputStream);
                            uint bytesToRead = await dataReader.LoadAsync(maxReadLength);
                            string rxBuffer = dataReader.ReadString(bytesToRead);
                            Debug.WriteLine(rxBuffer);
                            Debug.WriteLine("\n");
                        });
                    }
                });
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex);
            }
        }

现在这个代码可以在https://docs.microsoft.com/en-us/windows/iot-core/learn-about-hardware/pinmappings/pinmappingsrpi找到

它吐出的数据:

Exception thrown: 'System.NullReferenceException' in Tripmaster.exe
,ANTSTATUS=OPEN*2B
$GPRMC,165556.000,A,5048.7305,N,00305.1325,E,0.00,109.81,270618,,,D*6F
$GPVTG,109.81,T,,M,0.00,N,0.00,K,D*39
$GPGGA,165556.000,5048.7305,N,00305.1325,E,2,7,1.41,8.2,M,47.2,M,,*58
$GPGSA,A,3,20,27,10,32,22,14,08,,,,,,2.41,1.41,1.96*05
$GPGSV,4,1,13,08,73,179,27,18,68,282,,11,54,285,,01,42,274,*7F
$GPGSV,4,2,13,10,37,055,34,27,37,145,28,22,32,214,33,32,32,101,31*70
$GPGSV,4,3,13,28,27,312,,36,25,145,35,14,21,127,31,20,10,052,29*78
$GPGSV,4,4,13,03,09,217,15*41
$GPGLL,5048.7305,N,00305.1325,E,165556.000,A,D*53
$GPTXT,01,01,02,ANTSTATUS=OPEN*2B
$GPRMC,165557.000,A,5048.7305,N,00305.1325,E,0.00,109.81,270618,,,D*6E
$GPVTG,109.81,T,,M,0.00,N,0.00,K,D*39
$GPGGA,165557.000,5048.7305,N,00305.1325,E,2,7,1.41,8.2,M,47.2,M,,*59
$GPGSA,A,3,20,27,10,32,22,14,08,,,,,,2.41,1.41,1.96*05
$GPGSV,4,1,13,08,73,179,26,18,68,282,,11,54,285,,01,42,274,*7E
$GPGSV,4,2,13,10,37,055,33,27,37,145,27,22,32,214,32,32,32,101,30*78
$GPGSV,4,3,13,28,27,312,,36,25,145,34,14,21,127,30,20,10,052,29*78
$GPGSV,


Exception thrown: 'System.NullReferenceException' in System.Private.CoreLib.ni.dll

我需要运行这个多线程,因为我需要更新 GUI 并存储数据和处理数据并从本地存储中获取数据并显示它。但这超出了这个问题的范围。这里的问题是,每一秒我都有新的 GPS 数据,但它只是崩溃,我不知道为什么......

【问题讨论】:

  • 您的阅读速度可能比 GPS 发送的速度快。在从串行端口读取之前,请确保有可用的字节。我也不会在while (true) 循环中一遍又一遍地设置串行端口。这会导致问题。
  • 我本来打算把它放在一个类中,但后来我遇到了 SerialPort 的问题,因为在当前上下文中找不到...另外,我有两个 await 运算符,所以我没有'不知道如何处理......除此之外,设备读取速度可能比接收速度快,是否有可能同步它们?还是等待数据再读取?
  • @Naikrovek 我修复了这个类,所以现在我可以通过一个类调用我的数据并且只请求数据而不是一直设置设备。

标签: c# gps raspberry-pi3 uart windows-10-iot-core


【解决方案1】:

“System.NullReferenceException”出现在这一行:var dis = await DeviceInformation.FindAllAsync(aqs);,因为您反复调用SerialDevice.GetDeviceSelector("UART0");,但只有第一次您将获得 UART0 设备,否则您将获得nullaqs 的结果。

正确的格式是初始化设备一次并在while循环中读取日期。比如这样:

    private async void read_gps_data(string port = "UART0", int baud = 9600)
    {
            string aqs = SerialDevice.GetDeviceSelector("UART0");                   /* Find the selector string for the serial device   */
            var dis = await DeviceInformation.FindAllAsync(aqs);                    /* Find the serial device with our selector string  */
            SerialDevice SerialPort = await SerialDevice.FromIdAsync(dis[0].Id);    /* Create an serial device with our selected device */

            /* Configure serial settings */
            SerialPort.WriteTimeout = TimeSpan.FromMilliseconds(1000);
            SerialPort.ReadTimeout = TimeSpan.FromMilliseconds(1000);
            SerialPort.BaudRate = 9600;                                             /* mini UART: only standard baudrates */
            SerialPort.Parity = SerialParity.None;                                  /* mini UART: no parities */
            SerialPort.StopBits = SerialStopBitCount.One;                           /* mini UART: 1 stop bit */
            SerialPort.DataBits = 8;


            /* Read data in from the serial port */
            const uint maxReadLength = 1024;
            DataReader dataReader = new DataReader(SerialPort.InputStream);

            string rxBuffer = "";

            while (true)
            {
                await Task.Run(async () =>
                {
                    try
                    {
                        uint bytesToRead = await dataReader.LoadAsync(maxReadLength);
                        rxBuffer = dataReader.ReadString(bytesToRead);
                        Debug.WriteLine(rxBuffer);
                        Debug.WriteLine("\n");
                    }
                    catch (Exception ex)
                    {
                        Debug.WriteLine(ex);
                    }

                    await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async () =>
                    {
                        // Update UI here
                        receivedData.text = rxBuffer;
                    });

                });

            }

    }

例如,您可以在按钮单击事件中调用上述函数来启动读取操作:

Private void Button_Click(object sender, RoutedEventArgs e)
{
    read_gps_data();
}

【讨论】:

  • 我尝试使用您的代码(您错过了Taskvoid),但后来我遇到了同样的问题。它获取了数据,然后就崩溃了,难道没有一种方法可以同步设备并监听传入的数据吗?
  • @Robin 据我所知,唯一的方法是等待数据到达并且没有回调或事件通知。该代码对我有用。怎么调用read_gps_data()函数,哪一行导致crash?
  • 好的,让它开始工作,但是现在所有其他线程都停止了,系统变得非常慢,没有办法“等待”直到“所有”数据在缓冲区中接收到并且每秒读取一次数据?
  • @Robin 等到所有数据都将导致 UI 在此时间段内失去响应。我的建议是设置足够大的缓冲区来接收一次(一秒)发送的数据。
  • @Robin 一次或一秒从发送方发送多少字节?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-05-19
  • 2012-11-18
  • 1970-01-01
  • 2020-07-08
  • 1970-01-01
  • 2011-05-30
  • 1970-01-01
相关资源
最近更新 更多