我在使用Microsoft页面中的UWP串行UART测试示例中将C#的转换代码转换为VB.NET时遇到问题。 C#中的程序工作正常,但是当我尝试在VB.NET中运行时,当我尝试连接RaspBerry Pi 3中的端口时,变量“serialPort”输入没有值并返回,就像这里的图像{{ 3}}
我在C#和VB.NET中对代码源进行了解释,以便在编译代码的时刻比较是否缺少某些东西(可能是的)。
这是一张图片 this library
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 Source中,两者都是相同的,除了具有不同名称的Disconnect Button,但不影响我的实际问题,好吧,我在这个项目的这一部分工作了将近2周,我真的很感激任何帮助
答案 0 :(得分:0)
我已使用您提供的代码进行了测试。您是否检查过VB.Net项目中App包清单中的设备功能?您需要包含串行设备功能。在 Package.appxmanifest 文件中添加以下代码后,它对我有用。本文档在uwp中显示Serial Communication。如果问题仍然无法解决,请随时告诉我。
<DeviceCapability Name="serialcommunication">
<Device Id="vidpid:xxxx xxxx">
<Function Type="name:serialPort"/>
</Device>
</DeviceCapability>