我正在尝试使用Serial DataReceivedListener来自动从串行端口读取数据。在添加此活动之前,一切正常。
某些命令无法继续,因为C#抱怨“端口已经打开”。如果我注释掉“port.Open();”,那么C#会抱怨“端口已关闭。”
以下是我认为完整的代码。
SerialPort port;
String buffer;
String[] bufferArray;
String tellArduino; // any random one-byte character to "ping" Arduino for a data point
Queue<String> date = new Queue<String>();
Queue<String> time = new Queue<String>();
Queue<double> dcGen = new Queue<double>();
public Form1()
{
//
// IDE created this thing
//
InitializeComponent();
}
void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
getDataPoint();
}
private void selectPort()
{
//
// Creates new instance of SerialPort with the same
// settings as that of the Arduino. Checks if the selected
// port can be opened. Catches common exceptions found while debugging
//
try
{
port = new SerialPort((string)ports.SelectedItem);
port.BaudRate = 9600;
port.Parity = Parity.None;
port.StopBits = StopBits.One;
port.Open(); // check if port can be opened
port.Close();
portUsedLabel.Text = (string)ports.SelectedItem;
port.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);
getDataPoint(); // called here for testing. Values successfully split
}
// gotta catch 'em all
catch { stuff here }
}
private void getDataPoint()
{
/* still incomplete due to debugging phase */
//
// Method for getting a data point from the Arduino unit
// Pings Arduino unit for a data point. Program then reads
// entire serial output until new line (\n) is found.
// Program splits the entire buffer in to the bufferArray
// and proceeds to distribute each element in to their
// respective Queues
//
buffer = "";
bufferArray = new String[] { "" };
tellArduino = "m"; // any random one-byte string to "ping" Arduino for a data point
// it |must| remain exactly one byte to avoid duplicate data
port.Open();
port.WriteLine(tellArduino);
for (int x = 0; x < tellArduino.Length; x++)
{
buffer += port.ReadLine();
}
port.Close();
// Split each value then add to respective queues
bufferArray = buffer.Split(',');
date.Enqueue(bufferArray[0]);
time.Enqueue(bufferArray[1]);
dcGen.Enqueue(double.Parse(bufferArray[2], System.Globalization.CultureInfo.InvariantCulture));
// Start debugging code
// adding to ListBox for debugging and checking reasons
ports.BeginUpdate();
foreach (String value in bufferArray)
{
ports.Items.Add(value);
}
// for testing type double printing
ports.Items.Add(dcGen.ElementAt(0));
//
ports.EndUpdate();
// End debugging code
}
答案 0 :(得分:0)
您可能会同时执行getDataPoint()。 DataReceived将触发你的getDataPoint(),然后你打开和关闭端口。只需在选择端口打开端口一次,然后在退出程序时关闭它或单击“断开连接”。
答案 1 :(得分:0)
我认为您应该尝试在方法 selectPort 中选择端口时打开一次端口,并在关闭应用程序时关闭端口一次(窗体关闭事件)。
因为port_DataReceived会在接收数据时触发,因此您不应将port.Open();
放入方法 getDataPoint。
答案 2 :(得分:0)
我总是在实例化或打开任何串口之前立即插入此代码。它也在我的Form_Closing事件处理程序中。
if ((m_SerialPort != null)) {
if (m_SerialPort.IsOpen) {
m_SerialPort.Close();
}
}
如果您必须在端口打开时停止调试程序,这一点尤其重要。