【问题标题】:C# - Arduino Serial Communication freezes(?) while reading DataC# - Arduino 串行通信在读取数据时冻结(?)
【发布时间】:2017-08-27 15:30:10
【问题描述】:

我的程序在启动时检查是否连接了 Arduino,如果是这样,它会通过串行端口发送一条测试消息以查看它是否正确响应。然后它等待结果,如果答案是“成功”,它会继续启动。

这是代码的重要部分:

...
using System.IO.Ports;
using System.Threading;

namespace ProFlagControlApp
{
    public partial class MainWindow : Window
    {
        static AutoResetEvent autoEvent = new AutoResetEvent(false);

        ...
        private SerialPort arduinoBoard = new SerialPort();
        private string ardAnswer;

        /// <summary>
        /// Automatically detect the COM port on which an Arduino is connected.
        /// </summary>
        /// <returns>If an Aduino is connected, the port is returned as a string. If not, it returns null.</returns>
        private string AutodetectArduinoPort() { ... }

        /// <summary>
        /// Initializing communications with the Arduino.
        /// </summary>
        /// <param name="port">The identifier of the port the Arduino is connected to. Example: 'COM4'</param>
        private void OpenArduinoConnection(string port)
        {
            if (!arduinoBoard.IsOpen)
            {
            arduinoBoard.DataReceived += new SerialDataReceivedEventHandler(ArdSerPort_DataReceived);
            arduinoBoard.BaudRate = 115200;
            arduinoBoard.PortName = port;
            arduinoBoard.Parity = Parity.None;
            arduinoBoard.DataBits = 8;
            arduinoBoard.StopBits = StopBits.One;
            arduinoBoard.Handshake = Handshake.None;

            arduinoBoard.Open();
            }
            else
            {
                throw new InvalidOperationException("port is already in use");
            }
        }

        /// <summary>
        /// The event handler for receiving data from the Arduino.
        /// </summary>
        private void ArdSerPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            string data = arduinoBoard.ReadTo("\x03"); // Read Arduino data until exit code
            ardAnswer = data.Split('\x02', '\x03')[1]; // Only save information between the start and exit code
            autoEvent.Set();
        }

        public MainWindow()
        {
            InitializeComponent();

            ...

            // Detect if Arduino is connected, shutdown the application otherwise.
            if (AutodetectArduinoPort() == null) { ... }

            OpenArduinoConnection(AutodetectArduinoPort());

            // Test Arduino communication
            arduinoBoard.Write("connection#");

            autoEvent.WaitOne(500);
            if (ardAnswer != "success")
            {
                MessageBox.Show("Error communicating with Arduino", "Control Unit Error", MessageBoxButton.OK, MessageBoxImage.Warning);
                Application.Current.Shutdown();
                return;
            }

            ...
        }

        ...
    }
}

我通过 Arduino 串行监视器检查了命令是否被正确读取,并且适当的响应消息被写入串行端口,是这种情况。

但是,ArdSerPort_DataReceived 事件永远不会被触发。当我尝试在测试 ardAnswer 变量中的内容之前手动输入 ardAnswer = arduinoBoard.ReadTo("\x03"); 时,程序似乎冻结并且无法继续执行任何操作。

我真的很想知道为什么。我必须承认,我已经有一段时间没有接触过这个程序了,但是当我上次处理它时,它的表现完全正常,代码完全相同。

【问题讨论】:

  • 您的 SerialPort 初始化代码不足。您还必须设置 Parity、DataBits、StopBits (none, 8, 1)。重要的是,Handshake 必须为 None,因为 Arduino 没有实现握手信号。不设置它会产生一个随机值,该值取决于端口的先前使用情况。 ARE 是有风险的,但只要 Arduino 只在您要求时发送一​​些东西,那么您就可以侥幸逃脱。完全不使用 DataReceived 更为明智。
  • 在我的代码中更改了它,谢谢。不幸的是,没有解决主要问题。

标签: c# arduino serial-port


【解决方案1】:

您很可能有一个竞争条件:当您打开串行端口(在大多数系统上)时,DTR/RTS 串行端口信号的变化将重置 Arduino。反过来,这将导致引导加载程序运行,等待一小段时间以查看是否有任何代码要加载。如果没有,它会放入您的程序中。

我的猜测:您在引导加载程序等待时发送测试命令,导致您的部分或全部命令丢失。

尝试:在打开端口之后和发送命令之前添加延迟(启动几秒钟)。

更好的是:让您的 Arduino 代码在首次启动时发送响应或打印某种横幅。然后,让您的 C# 代码在打开串行端口之后等待,这样您就知道 Arduino 已重置,通过引导加载程序,您的代码现在已完全启动并运行。

【讨论】:

  • 不幸的是,这并没有解决它。打开串口时,引导加载程序似乎也没有运行,因为我看不到 Arduino LED 闪烁,它们通常在启动时会这样做(?)
  • 如果您将 Arduino 程序更改为在启动时在串行端口上打印横幅,当您在 Arduino IDE 中打开串行监视器时是否看到该横幅?
  • 是的,我愿意。但正如我所说,当 C# 程序打开串行端口时,Arduino 似乎没有重新启动。也许它打开端口有问题,这就是问题所在,毕竟?奇怪的是没有错误消息,虽然......
【解决方案2】:

我得到了答案。 C# / Visual Studio / .NET Framework / Whatsoever 似乎不喜欢高波特率。我把它从 115200 调低到 9600(据我所知是标准的),现在一切正常。奇怪。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多