我的程序在啓動時檢查Arduino是否連接,如果是這種情況,它會通過串行端口發送測試消息來查看它是否正確響應。然後等待結果,如果答案是「成功」,它會繼續啓動。C# - 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初始化代碼不足。您還必須設置奇偶校驗,數據位,停止位(無,8,1)。而重要的一個,因爲Arduino沒有實現握手信號,Handshake必須是None。不設置它會產生一個隨機值,這取決於以前使用的端口。 ARE是有風險的,但只要Arduino只有在你要求的時候才發送一些東西,那麼你就會擺脫它。根本不使用DataReceived更合理。 –
更改了我的代碼,謝謝。遺憾的是沒有幫助主要問題。 – TheEpicSnowWolf