代码之家  ›  专栏  ›  技术社区  ›  LuckSaiber

通用Windows平台——VB中的串行测试环回程序。NET版本不工作?

  •  0
  • LuckSaiber  · 技术社区  · 6 年前

    我在将C#翻译成VB时遇到问题。NET中的UWP串行UART测试示例在Microsoft Page中捕获。C#中的程序运行得很好,但当我尝试在VB中运行时。NET中,当我尝试连接RaspBerry Pi 3中的端口时,变量“serialPort”无值输入并返回,如图所示 serialPort without value.

    我在这里用C#和VB对代码源进行了显示。NET来比较在生成翻译代码的那一刻是否遗漏了什么(可能是的)。

    这是 C# serialPort with value.

    C#示例

    // Copyright (c) Microsoft. All rights reserved.
    
    using System;
    using System.Collections.ObjectModel;
    using Windows.UI.Xaml;
    using Windows.UI.Xaml.Controls;
    using Windows.Devices.Enumeration;
    using Windows.Devices.SerialCommunication;
    using Windows.Storage.Streams;
    using System.Threading;
    using System.Threading.Tasks;
    
    namespace SerialSample
    {    
        public sealed partial class MainPage : Page
        {
            /// <summary>
            /// Private variables
            /// </summary>
            private SerialDevice serialPort = null;
            DataWriter dataWriteObject = null;
            DataReader dataReaderObject = null;
    
            private ObservableCollection<DeviceInformation> listOfDevices;
            private CancellationTokenSource ReadCancellationTokenSource;
    
            public MainPage()
            {
                this.InitializeComponent();            
                comPortInput.IsEnabled = false;
                sendTextButton.IsEnabled = false;
                listOfDevices = new ObservableCollection<DeviceInformation>();
                ListAvailablePorts();
            }
    
            /// <summary>
            /// ListAvailablePorts
            /// - Use SerialDevice.GetDeviceSelector to enumerate all serial devices
            /// - Attaches the DeviceInformation to the ListBox source so that DeviceIds are displayed
            /// </summary>
            private async void ListAvailablePorts()
            {
                try
                {
                    string aqs = SerialDevice.GetDeviceSelector();
                    var dis = await DeviceInformation.FindAllAsync(aqs);
    
                    status.Text = "Select a device and connect";
    
                    for (int i = 0; i < dis.Count; i++)
                    {
                        listOfDevices.Add(dis[i]);
                    }
    
                    DeviceListSource.Source = listOfDevices;
                    comPortInput.IsEnabled = true;
                    ConnectDevices.SelectedIndex = -1;
                }
                catch (Exception ex)
                {
                    status.Text = ex.Message;
                }
            }
    
            /// <summary>
            /// comPortInput_Click: Action to take when 'Connect' button is clicked
            /// - Get the selected device index and use Id to create the SerialDevice object
            /// - Configure default settings for the serial port
            /// - Create the ReadCancellationTokenSource token
            /// - Start listening on the serial port input
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private async void comPortInput_Click(object sender, RoutedEventArgs e)
            {
                var selection = ConnectDevices.SelectedItems;
    
                if (selection.Count <= 0)
                {
                    status.Text = "Select a device and connect";
                    return;
                }
    
                DeviceInformation entry = (DeviceInformation)selection[0];         
    
                try
                {                
                    serialPort = await SerialDevice.FromIdAsync(entry.Id);
                    if (serialPort == null) return;
    
                    // Disable the 'Connect' button 
                    comPortInput.IsEnabled = false;
    
                    // Configure serial settings
                    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;
    
                    // Display configured settings
                    status.Text = "Serial port configured successfully: ";
                    status.Text += serialPort.BaudRate + "-";
                    status.Text += serialPort.DataBits + "-";
                    status.Text += serialPort.Parity.ToString() + "-";
                    status.Text += serialPort.StopBits;
    
                    // Set the RcvdText field to invoke the TextChanged callback
                    // The callback launches an async Read task to wait for data
                    rcvdText.Text = "Waiting for data...";
    
                    // Create cancellation token object to close I/O operations when closing the device
                    ReadCancellationTokenSource = new CancellationTokenSource();
    
                    // Enable 'WRITE' button to allow sending data
                    sendTextButton.IsEnabled = true;
    
                    Listen();
                }
                catch (Exception ex)
                {
                    status.Text = ex.Message;
                    comPortInput.IsEnabled = true;
                    sendTextButton.IsEnabled = false;
                }
            }
    
            /// <summary>
            /// sendTextButton_Click: Action to take when 'WRITE' button is clicked
            /// - Create a DataWriter object with the OutputStream of the SerialDevice
            /// - Create an async task that performs the write operation
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private async void sendTextButton_Click(object sender, RoutedEventArgs e)
            {
                try
                {                
                    if (serialPort != null)
                    {
                        // Create the DataWriter object and attach to OutputStream
                        dataWriteObject = new DataWriter(serialPort.OutputStream);
    
                        //Launch the WriteAsync task to perform the write
                        await WriteAsync();
                    }
                    else
                    {
                        status.Text = "Select a device and connect";                
                    }
                }
                catch (Exception ex)
                {
                    status.Text = "sendTextButton_Click: " + ex.Message;
                }
                finally
                {
                    // Cleanup once complete
                    if (dataWriteObject != null)
                    {
                        dataWriteObject.DetachStream();
                        dataWriteObject = null;
                    }
                }
            }
    
            /// <summary>
            /// WriteAsync: Task that asynchronously writes data from the input text box 'sendText' to the OutputStream 
            /// </summary>
            /// <returns></returns>
            private async Task WriteAsync()
            {
                Task<UInt32> storeAsyncTask;
    
                if (sendText.Text.Length != 0)
                {
                    // Load the text from the sendText input text box to the dataWriter object
                    dataWriteObject.WriteString(sendText.Text);                
    
                    // Launch an async task to complete the write operation
                    storeAsyncTask = dataWriteObject.StoreAsync().AsTask();
    
                    UInt32 bytesWritten = await storeAsyncTask;
                    if (bytesWritten > 0)
                    {                    
                        status.Text = sendText.Text + ", ";
                        status.Text += "bytes written successfully!";
                    }
                    sendText.Text = "";
                }
                else
                {
                    status.Text = "Enter the text you want to write and then click on 'WRITE'";
                }
            }
    
            /// <summary>
            /// - Create a DataReader object
            /// - Create an async task to read from the SerialDevice InputStream
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private async void Listen()
            {
                try
                {
                    if (serialPort != null)
                    {
                        dataReaderObject = new DataReader(serialPort.InputStream);
    
                        // keep reading the serial input
                        while (true)
                        {
                            await ReadAsync(ReadCancellationTokenSource.Token);
                        }
                    }
                }
                catch (TaskCanceledException tce) 
                {
                    status.Text = "Reading task was cancelled, closing device and cleaning up";
                    CloseDevice();            
                }
                catch (Exception ex)
                {
                    status.Text = ex.Message;
                }
                finally
                {
                    // Cleanup once complete
                    if (dataReaderObject != null)
                    {
                        dataReaderObject.DetachStream();
                        dataReaderObject = null;
                    }
                }
            }
    
            /// <summary>
            /// ReadAsync: Task that waits on data and reads asynchronously from the serial device InputStream
            /// </summary>
            /// <param name="cancellationToken"></param>
            /// <returns></returns>
            private async Task ReadAsync(CancellationToken cancellationToken)
            {
                Task<UInt32> loadAsyncTask;
    
                uint ReadBufferLength = 1024;
    
                // If task cancellation was requested, comply
                cancellationToken.ThrowIfCancellationRequested();
    
                // Set InputStreamOptions to complete the asynchronous read operation when one or more bytes is available
                dataReaderObject.InputStreamOptions = InputStreamOptions.Partial;
    
                using (var childCancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken))
                {
                    // Create a task object to wait for data on the serialPort.InputStream
                    loadAsyncTask = dataReaderObject.LoadAsync(ReadBufferLength).AsTask(childCancellationTokenSource.Token);
    
                    // Launch the task and wait
                    UInt32 bytesRead = await loadAsyncTask;
                    if (bytesRead > 0)
                    {
                        rcvdText.Text = dataReaderObject.ReadString(bytesRead);
                        status.Text = "bytes read successfully!";
                    }
                }
            }
    
            /// <summary>
            /// CancelReadTask:
            /// - Uses the ReadCancellationTokenSource to cancel read operations
            /// </summary>
            private void CancelReadTask()
            {         
                if (ReadCancellationTokenSource != null)
                {
                    if (!ReadCancellationTokenSource.IsCancellationRequested)
                    {
                        ReadCancellationTokenSource.Cancel();
                    }
                }         
            }
    
            /// <summary>
            /// CloseDevice:
            /// - Disposes SerialDevice object
            /// - Clears the enumerated device Id list
            /// </summary>
            private void CloseDevice()
            {            
                if (serialPort != null)
                {
                    serialPort.Dispose();
                }
                serialPort = null;
    
                comPortInput.IsEnabled = true;
                sendTextButton.IsEnabled = false;            
                rcvdText.Text = "";
                listOfDevices.Clear();               
            }
    
            /// <summary>
            /// closeDevice_Click: Action to take when 'Disconnect and Refresh List' is clicked on
            /// - Cancel all read operations
            /// - Close and dispose the SerialDevice object
            /// - Enumerate connected devices
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void closeDevice_Click(object sender, RoutedEventArgs e)
            {
                try
                {
                    status.Text = "";
                    CancelReadTask();
                    CloseDevice();
                    ListAvailablePorts();
                }
                catch (Exception ex)
                {
                    status.Text = ex.Message;
                }          
            }             
        }
    }
    

    VB。NET示例

    Imports System
    Imports System.Collections.ObjectModel
    Imports Windows.UI.Xaml
    Imports Windows.UI.Xaml.Controls
    Imports Windows.Devices.Enumeration
    Imports Windows.Devices.SerialCommunication
    Imports Windows.Storage.Streams
    Imports System.Threading
    Imports System.Threading.Tasks
    
    
    
    Public NotInheritable Class MainPage
            Inherits Page
    
        ''' <summary>
        ''' Private variables
        ''' </summary>
        Private serialPort As SerialDevice = Nothing
    
        Private dataWriteObject As DataWriter = Nothing
    
            Private dataReaderObject As DataReader = Nothing
    
            Private listOfDevices As ObservableCollection(Of DeviceInformation)
    
            Private ReadCancellationTokenSource As CancellationTokenSource
    
            Public Sub New()
                MyBase.New
                Me.InitializeComponent
                comPortInput.IsEnabled = False
                sendTextButton.IsEnabled = False
                Me.listOfDevices = New ObservableCollection(Of DeviceInformation)
                Me.ListAvailablePorts()
            End Sub
    
            ''' <summary>
            ''' ListAvailablePorts
            ''' - Use SerialDevice.GetDeviceSelector to enumerate all serial devices
            ''' - Attaches the DeviceInformation to the ListBox source so that DeviceIds are displayed
            ''' </summary>
            Private Async Sub ListAvailablePorts()
                Try
                    Dim aqs As String = SerialDevice.GetDeviceSelector
                Dim dis = Await DeviceInformation.FindAllAsync(aqs)
                status.Text = "Select a device and connect"
                    Dim i As Integer = 0
                    Do While (i < dis.Count)
                        Me.listOfDevices.Add(dis(i))
                        i = (i + 1)
                    Loop
    
                    DeviceListSource.Source = Me.listOfDevices
                    comPortInput.IsEnabled = True
                    ConnectDevices.SelectedIndex = -1
                Catch ex As Exception
                    status.Text = ex.Message
                End Try
    
            End Sub
    
        ''' <summary>
        ''' comPortInput_Click: Action to take when 'Connect' button is clicked
        ''' - Get the selected device index and use Id to create the SerialDevice object
        ''' - Configure default settings for the serial port
        ''' - Create the ReadCancellationTokenSource token
        ''' - Start listening on the serial port input
        ''' </summary>
        ''' <param name="sender"></param>
        ''' <param name="e"></param>
        Private Async Sub comPortInput_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
    
            Dim selection = ConnectDevices.SelectedItems
            If (selection.Count <= 0) Then
                status.Text = "Select a device and connect"
                Return
            End If
    
            Dim entry As DeviceInformation = CType(selection(0), DeviceInformation)
    
            Try
                serialPort = Await SerialDevice.FromIdAsync(entry.Id)
                If (serialPort Is Nothing) Then
                    Return
                End If
    
                ' Disable the 'Connect' button 
                comPortInput.IsEnabled = False
                ' Configure serial settings
                Me.serialPort.WriteTimeout = TimeSpan.FromMilliseconds(1000)
                Me.serialPort.ReadTimeout = TimeSpan.FromMilliseconds(1000)
                Me.serialPort.BaudRate = 9600
                Me.serialPort.Parity = SerialParity.None
                Me.serialPort.StopBits = SerialStopBitCount.One
                Me.serialPort.DataBits = 8
                Me.serialPort.Handshake = SerialHandshake.None
                ' Display configured settings
                status.Text = "Serial port configured successfully: "
                status.Text = (status.Text _
                                + (Me.serialPort.BaudRate + "-"))
                status.Text = (status.Text _
                                + (Me.serialPort.DataBits + "-"))
                status.Text = (status.Text _
                                + (Me.serialPort.Parity.ToString + "-"))
                status.Text = (status.Text + Me.serialPort.StopBits)
                ' Set the RcvdText field to invoke the TextChanged callback
                ' The callback launches an async Read task to wait for data
                rcvdText.Text = "Waiting for data..."
                ' Create cancellation token object to close I/O operations when closing the device
                Me.ReadCancellationTokenSource = New CancellationTokenSource
                ' Enable 'WRITE' button to allow sending data
                sendTextButton.IsEnabled = True
                Me.Listen()
            Catch ex As Exception
                status.Text = ex.Message
                comPortInput.IsEnabled = True
                sendTextButton.IsEnabled = False
            End Try
    
        End Sub
    
        ''' <summary>
        ''' sendTextButton_Click: Action to take when 'WRITE' button is clicked
        ''' - Create a DataWriter object with the OutputStream of the SerialDevice
        ''' - Create an async task that performs the write operation
        ''' </summary>
        ''' <param name="sender"></param>
        ''' <param name="e"></param>
        Private Async Sub sendTextButton_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
                Try
                    If (Not (Me.serialPort) Is Nothing) Then
                        ' Create the DataWriter object and attach to OutputStream
                        Me.dataWriteObject = New DataWriter(Me.serialPort.OutputStream)
                    'Launch the WriteAsync task to perform the write
                    Await Me.WriteAsync()
                Else
                        status.Text = "Select a device and connect"
                    End If
    
                Catch ex As Exception
                    status.Text = ("sendTextButton_Click: " + ex.Message)
                Finally
                    ' Cleanup once complete
                    If (Not (Me.dataWriteObject) Is Nothing) Then
                        Me.dataWriteObject.DetachStream()
                        Me.dataWriteObject = Nothing
                    End If
    
                End Try
    
            End Sub
    
            ''' <summary>
            ''' WriteAsync: Task that asynchronously writes data from the input text box 'sendText' to the OutputStream 
            ''' </summary>
            ''' <returns></returns>
            Private Async Function WriteAsync() As Task
                Dim storeAsyncTask As Task(Of UInt32)
                If (sendText.Text.Length <> 0) Then
                    ' Load the text from the sendText input text box to the dataWriter object
                    Me.dataWriteObject.WriteString(sendText.Text)
                    ' Launch an async task to complete the write operation
                    storeAsyncTask = Me.dataWriteObject.StoreAsync.AsTask
                Dim bytesWritten As UInt32 = Await storeAsyncTask
                If (bytesWritten > 0) Then
                    status.Text = (sendText.Text + ", ")
                    status.Text = (status.Text + "bytes written successfully!")
                End If
    
                sendText.Text = ""
                Else
                    status.Text = "Enter the text you want to write and then click on 'WRITE'"
                End If
    
            End Function
    
        ''' <summary>
        ''' - Create a DataReader object
        ''' - Create an async task to read from the SerialDevice InputStream
        ''' </summary>
        Private Async Sub Listen()
            Try
                If (Not (Me.serialPort) Is Nothing) Then
                    Me.dataReaderObject = New DataReader(Me.serialPort.InputStream)
                    ' keep reading the serial input
    
                    While True
                        Await Me.ReadAsync(Me.ReadCancellationTokenSource.Token)
    
                    End While
    
                End If
    
            Catch tce As TaskCanceledException
                status.Text = "Reading task was cancelled, closing device and cleaning up"
                Me.closeDevice()
            Catch ex As Exception
                status.Text = ex.Message
            Finally
                ' Cleanup once complete
                If (Not (Me.dataReaderObject) Is Nothing) Then
                    Me.dataReaderObject.DetachStream()
                    Me.dataReaderObject = Nothing
                End If
    
            End Try
    
        End Sub
    
        ''' <summary>
        ''' ReadAsync: Task that waits on data and reads asynchronously from the serial device InputStream
        ''' </summary>
        ''' <param name="cancellationToken"></param>
        ''' <returns></returns>
        Private Async Function ReadAsync(ByVal cancellationToken As CancellationToken) As Task
                Dim loadAsyncTask As Task(Of UInt32)
                Dim ReadBufferLength As UInteger = 1024
                ' If task cancellation was requested, comply
                cancellationToken.ThrowIfCancellationRequested()
                ' Set InputStreamOptions to complete the asynchronous read operation when one or more bytes is available
                Me.dataReaderObject.InputStreamOptions = InputStreamOptions.Partial
                Dim childCancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken)
                ' Create a task object to wait for data on the serialPort.InputStream
                loadAsyncTask = Me.dataReaderObject.LoadAsync(ReadBufferLength).AsTask(childCancellationTokenSource.Token)
            ' Launch the task and wait
            Dim bytesRead As UInt32 = Await loadAsyncTask
            If (bytesRead > 0) Then
                    rcvdText.Text = Me.dataReaderObject.ReadString(bytesRead)
                    status.Text = "bytes read successfully!"
                End If
    
            End Function
    
            ''' <summary>
            ''' CancelReadTask:
            ''' - Uses the ReadCancellationTokenSource to cancel read operations
            ''' </summary>
            Private Sub CancelReadTask()
                If (Not (Me.ReadCancellationTokenSource) Is Nothing) Then
                    If Not Me.ReadCancellationTokenSource.IsCancellationRequested Then
                        Me.ReadCancellationTokenSource.Cancel()
                    End If
    
                End If
    
            End Sub
    
            ''' <summary>
            ''' CloseDevice:
            ''' - Disposes SerialDevice object
            ''' - Clears the enumerated device Id list
            ''' </summary>
            Private Sub CloseDevice()
            If (Not (serialPort) Is Nothing) Then
                Me.serialPort.Dispose()
            End If
    
            Me.serialPort = Nothing
                comPortInput.IsEnabled = True
                sendTextButton.IsEnabled = False
                rcvdText.Text = ""
                Me.listOfDevices.Clear()
            End Sub
    
        ''' <summary>
        ''' closeDevice_Click: Action to take when 'Disconnect and Refresh List' is clicked on
        ''' - Cancel all read operations
        ''' - Close and dispose the SerialDevice object
        ''' - Enumerate connected devices
        ''' </summary>
        ''' <param name="sender"></param>
        ''' <param name="e"></param>
        Private Sub closeConnection_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
            Try
                status.Text = ""
                Me.CancelReadTask()
                Me.CloseDevice()
                Me.ListAvailablePorts()
            Catch ex As Exception
                status.Text = ex.Message
            End Try
    
        End Sub
    End Class
    

    在XAML源代码中,除了具有不同名称的Disconnect按钮之外,这两个按钮都是相同的,但不影响我的实际问题。好吧,我在项目的这一部分上花了将近2周的时间,如果能在这方面提供帮助,我将不胜感激。

    1 回复  |  直到 6 年前
        1
  •  0
  •   Michael Xu    6 年前

    我已经用您提供的代码进行了测试。您是否检查了VB中应用程序包清单中的设备功能。Net项目?您需要包括串行设备功能。在 包裹appxmanifest公司 文件此文档显示 Serial Communication 在uwp中。如果问题仍然无法解决,请随时通知我。

    <DeviceCapability Name="serialcommunication">
        <Device Id="vidpid:xxxx xxxx">
          <Function Type="name:serialPort"/>
        </Device>
    </DeviceCapability>