SerialPort.DataReceived返回奇怪的结果

本文关键字:结果 DataReceived 返回 SerialPort | 更新日期: 2023-09-27 18:22:00

我目前正在使用一种名为Fluke 5500A多产品校准设备的设备。我用C#编写了一个小程序来与它交互,并了解它的工作原理,但不幸的是,SerialPort.DataReceived给了我一些非常奇怪的结果。这个程序不长,所以我要把它全部发布在这里:

class Program
{
    static public bool isExecuting = true;
    static private string serialCommand;
    static private string dataReceived;
    static void Main(string[] args)
    {
        SerialPortConnection serialPort = new SerialPortConnection();
        serialPort.OpenSerialConnection();
        while (isExecuting == true)
        {
            Console.WriteLine("Enter a command or type q to quit.");
            serialCommand = Console.ReadLine().ToUpper();
            if (serialCommand == "Q")
                isExecuting = false;
            else if (serialCommand == "CLEAR")
                Console.Clear();
            else
            {
                dataReceived = serialPort.WriteSerialConnection(serialCommand);
                Console.WriteLine(dataReceived);
            }
        }
        serialPort.CloseSerialConnection();
    }
}

}

我的SerialPortConnection类:

public class SerialPortConnection
{
    private SerialPort serialPort;
    private string dataReceived = "none";
    public SerialPortConnection(string comPort = "Com3", int baud = 9600, System.IO.Ports.Parity parity = System.IO.Ports.Parity.None, int dataBits = 8, System.IO.Ports.StopBits stopBits = System.IO.Ports.StopBits.One)
    {
        serialPort = new SerialPort(comPort, baud, parity, dataBits, stopBits);
    }
    public void OpenSerialConnection()
    {
        try
        {
            serialPort.Open();
        }
        catch (Exception e)
        {
            Console.Write("'nError");
            Console.Write(e);
        }
    }
    public string WriteSerialConnection(string SerialCommand)
    {
        try
        {
            serialPort.Write(String.Format(SerialCommand + "'r"));
            dataReceived = serialPort.ReadExisting();
            return dataReceived;
        }
        catch (Exception e)
        {
            Console.Write("'nError");
            Console.Write(e);
            return "Execution Unsuccessful";
        }
    }
    public void CloseSerialConnection()
    {
        try 
        {
            serialPort.Close();
        }
        catch (Exception e)
        {
            Console.Write("'nError");
            Console.Write(e);
        }
    }
}

我目前的问题是控制台的输出看起来像这样:

Enter a command or type q to quit.
*IDN?
Enter a command or type q to quit.
OUT 50V <-- Command input
*IDN? <-- Previous command echoed back
FLUKE,5500A,8030005,2.61+1.3+2.0+* <-- Data received from previous command
161>
Enter a command or type q to quit.
OPER
OUT 50V
162>
Enter a command or type q to quit.
STBY
OPER
163>
Enter a command or type q to quit.
*RST
STBY
164>
Enter a command or type q to quit.

命令执行得很好,但控制台的输出似乎是执行的最后一个命令以及该命令返回的任何数据。我不知道为什么会这样。

编辑:

感谢Robert p的回答,我实现了以下代码:

var received = "";
bool isReading = true;
while (isReading == true)
{
    try
    {
        received += serialPort.ReadExisting();
        if (received.Contains('>'))
            isReading = false;
    }
    catch (Exception e)
    {
    }
}
Console.WriteLine(received);

SerialPort.DataReceived返回奇怪的结果

问题的一部分是串行通信远不是即时的。.ReadExisting()方法从SerialPort对象的缓冲区中提取数据,但不采取任何措施来确保设备已完成发出命令。这样想:

+----+            +----------+           +------------+
|Your|--Command-->|Serial    |---UART--->|    Device  |
|Code|            |Port Obj  |           |            |
+----+            +----------+           +------------+
+----+            +----------+           +------------+
|Your|<--Read-----|Serial    |           |Device      |
|Code| (is empty) |          |           |(processing)|
+----+            +----------+           +------------+
+----+            +----------+           +------------+
|Your|            |Serial    |<-response-|Device      |
|Code|            |(has data)|           |(responding)|
+----+            +----------+           +------------+
+----+            +----------+           +------------+
|Your|--Command2->|Serial    |---UART--->|    Device  |
|Code|            |(has data)|           |            |
+----+            +----------+           +------------+
+----+            +----------+           +------------+
|Your|<--Read-----|Serial    |           |Device      |
|Code| (previous  |          |           |(processing)|
+----+  response) +----------+           +------------+

相反,在发送下一个命令之前,请查找模式、令牌或其他识别标记,以知道传输已完成。继续阅读(预计会超时-它们会作为异常抛出!)直到您知道您已经收到了完整的回复。在这种情况下,>字符可能表示"准备好接受更多输入"。您可以将其解释为"响应已完成"。