Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/arduino/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arduino Windows 10 IOT串行-正在RP2上工作,但读取串行数据不完整_Arduino_Serial Port_Win Universal App_Raspberry Pi2_Windows 10 Iot Core - Fatal编程技术网

Arduino Windows 10 IOT串行-正在RP2上工作,但读取串行数据不完整

Arduino Windows 10 IOT串行-正在RP2上工作,但读取串行数据不完整,arduino,serial-port,win-universal-app,raspberry-pi2,windows-10-iot-core,Arduino,Serial Port,Win Universal App,Raspberry Pi2,Windows 10 Iot Core,因此,自从10月份的版本开放了串行引脚以来,我一直在试验IOT串行样本和RP2。Im使用windows iot串行示例。有几个问题我想不出来 读取的数据似乎不完整。我有一个arduino以9600波特的速度通过串口输出模拟输入读数。在windows Universal应用程序上,我先读完整的一行,然后读不完整的一行。例如:如果arduiono输出的值为“2.25”,则应用程序将读取一行2.25,然后读取下一行“.25”(周期前面没有任何内容)。我在应用程序端和arduino上尝试了延迟,但没有成

因此,自从10月份的版本开放了串行引脚以来,我一直在试验IOT串行样本和RP2。Im使用windows iot串行示例。有几个问题我想不出来

  • 读取的数据似乎不完整。我有一个arduino以9600波特的速度通过串口输出模拟输入读数。在windows Universal应用程序上,我先读完整的一行,然后读不完整的一行。例如:如果arduiono输出的值为“2.25”,则应用程序将读取一行2.25,然后读取下一行“.25”(周期前面没有任何内容)。我在应用程序端和arduino上尝试了延迟,但没有成功

  • 在尝试连接时,它会抛出格式异常。有时可以点击“断开连接”和“重新连接”,这样就可以正常工作。其他人我必须重新启动arduino

  • 我认为这是代码示例中的一些东西,因为如果我使用笔记本电脑或raspberry pi运行,我也会遇到同样的问题

    这是节目的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
        /// - Add text to rcvdText textbox to invoke rcvdText_TextChanged event
        /// </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);
    
                // 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;
    
                // Display configured settings
                status.Text = "Serial port configured successfully!\n ----- Properties ----- \n";
                status.Text += "BaudRate: " + serialPort.BaudRate.ToString() + "\n";
                status.Text += "DataBits: " + serialPort.DataBits.ToString() + "\n";
                status.Text += "Handshake: " + serialPort.Handshake.ToString() + "\n";
                status.Text += "Parity: " + serialPort.Parity.ToString() + "\n";
                status.Text += "StopBits: " + serialPort.StopBits.ToString() + "\n";                            
    
                // 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;
            }
            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 + '\n';
                    status.Text += "Bytes written successfully!";
                }
                sendText.Text = "";
            }
            else
            {
                status.Text = "Enter the text you want to write and then click on 'WRITE'";
            }
        }
    
        /// <summary>
        /// rcvdText_TextChanged: Action to take when text is entered in the 'Read Data' textbox
        /// - 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 rcvdText_TextChanged(object sender, TextChangedEventArgs e)
        {
            try
            {
                if (serialPort != null)
                {
                    dataReaderObject = new DataReader(serialPort.InputStream);
                    await ReadAsync(ReadCancellationTokenSource.Token);
                }
            }
            catch (Exception ex)
            {
                if (ex.GetType().Name == "TaskCanceledException")
                {
                    status.Text = "Reading task was cancelled, closing device and cleaning up";
                    CloseDevice();
                }
                else
                {
                    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 = 128;
    
            // 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;
    
            // Create a task object to wait for data on the serialPort.InputStream
            loadAsyncTask = dataReaderObject.LoadAsync(ReadBufferLength).AsTask(cancellationToken);
    
            // Launch the task and wait
            UInt32 bytesRead = await loadAsyncTask;
    
            if (bytesRead > 0)
            {
    
                rcvdText.Text = dataReaderObject.ReadString(bytesRead);
                status.Text = bytesRead.ToString();
                //status.Text = "\nBytes 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;
            }          
        }        
    }
    }
    
    这是一个显示该问题的快速视频链接。你会知道,它第一次连接到视频,哈哈哈


    提前感谢您提供的所有帮助和建议。

    我对代码进行了一些优化。我相信原始代码中的取消令牌可能是问题的一部分。现在,它每次都连接并读取:)如果有人想尝试,下面是代码

    using System;
    using System.Collections.Generic;
    using System.IO;
    using Windows.UI.Popups;
    using System.Linq;
    using System.Runtime.InteropServices.WindowsRuntime;
    using Windows.Foundation;
    using Windows.Foundation.Collections;
    using Windows.UI.Xaml;
    using Windows.UI.Xaml.Controls;
    using Windows.UI.Xaml.Controls.Primitives;
    using Windows.UI.Xaml.Data;
    using Windows.UI.Xaml.Input;
    using Windows.UI.Xaml.Media;
    using Windows.UI.Xaml.Navigation;
    using System.Collections.ObjectModel;
    using Windows.Devices.Enumeration;
    using Windows.Devices.SerialCommunication;
    using Windows.Storage.Streams;
    using System.Threading;
    using System.Threading.Tasks;
    
    
    
    namespace Serial_Data_Read
    {
    
    public sealed partial class MainPage : Page
    {
    
        private SerialDevice serialPort = null;
    
        DataReader dataReaderObject = null;
    
        public uint BytesReceived { get; }
    
        public MainPage()
        {
            this.InitializeComponent();
            ListAvailablePorts();
    
        }
    
        private async void ListAvailablePorts()
        {
            try
            {
                string aqs = SerialDevice.GetDeviceSelector();
                var dis = await DeviceInformation.FindAllAsync(aqs);
    
                var selectedPort = dis.First();
                serialPort = await SerialDevice.FromIdAsync(selectedPort.Id);
    
    
                serialPort.ReadTimeout = TimeSpan.FromMilliseconds(1000);
                serialPort.BaudRate = 9600;
                serialPort.Parity = SerialParity.None;
                serialPort.StopBits = SerialStopBitCount.One;
                serialPort.DataBits = 8;
    
                infoBox.Text = "Serial port configured successfully!\n ----- Properties ----- \n";
                infoBox.Text += "BaudRate: " + serialPort.BaudRate.ToString() + "\n";
                infoBox.Text += "DataBits: " + serialPort.DataBits.ToString() + "\n";
                infoBox.Text += "Handshake: " + serialPort.Handshake.ToString() + "\n";
                infoBox.Text += "Parity: " + serialPort.Parity.ToString() + "\n";
                infoBox.Text += "StopBits: " + serialPort.StopBits.ToString() + "\n";
    
                data.Text = "configuring port";
    
            }
    
            catch (Exception ex)
            {
                infoBox.Text = "OOps, Something went wrong! \n" + ex.Message ;
            }
        }
    
        private async void data_TextChanged(object sender, TextChangedEventArgs e)
        {
            dataReaderObject = new DataReader(serialPort.InputStream);
            try
            {
                var bytesRecieved = await dataReaderObject.LoadAsync(128);
    
                if (bytesRecieved > 0)
                {
    
                    data.Text = dataReaderObject.ReadString(bytesRecieved).Trim();
                }
    
            }
            catch (Exception ex)
            {
                data.Text = ex.Message;
                ListAvailablePorts();
            }
            finally
            {
                if (dataReaderObject != null)
                {
                    dataReaderObject.DetachStream();
                    dataReaderObject = null;
                }
            }
        }    
    }
    }
    
    还有xaml

    <Page
    x:Class="Serial_Data_Read.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:Serial_Data_Read"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
       Width="800" Height="480">
    
    <Grid Background="{ThemeResource AppBarItemDisabledForegroundThemeBrush}">
        <TextBox x:Name="infoBox" HorizontalAlignment="Left" Margin="10,288,0,0" TextWrapping="Wrap" Text="Waiting to establish a connection" VerticalAlignment="Top" Height="182" Width="382"/>
        <TextBox x:Name="data" HorizontalAlignment="Left" Margin="10,10,0,0" TextWrapping="Wrap" Text="Waiting for data" VerticalAlignment="Top" Height="154" Width="780"  TextChanged="data_TextChanged" />
    </Grid>
    
    
    

    看来你第二次读得不够早。在ReadAsync中设置一个断点并缩短等待时间?今晚我会尝试,并让您知道进展如何。谢谢
    <Page
    x:Class="Serial_Data_Read.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:Serial_Data_Read"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
       Width="800" Height="480">
    
    <Grid Background="{ThemeResource AppBarItemDisabledForegroundThemeBrush}">
        <TextBox x:Name="infoBox" HorizontalAlignment="Left" Margin="10,288,0,0" TextWrapping="Wrap" Text="Waiting to establish a connection" VerticalAlignment="Top" Height="182" Width="382"/>
        <TextBox x:Name="data" HorizontalAlignment="Left" Margin="10,10,0,0" TextWrapping="Wrap" Text="Waiting for data" VerticalAlignment="Top" Height="154" Width="780"  TextChanged="data_TextChanged" />
    </Grid>