SerialPort.DataReceived 返回奇怪的结果 [英] SerialPort.DataReceived Returning Strange Results

查看:53
本文介绍了SerialPort.DataReceived 返回奇怪的结果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在使用一种名为 Fluke 5500A 多产品校准设备的设备.我已经用 C# 编写了一个小程序来与之交互并了解有关它如何工作的更多信息,但不幸的是 SerialPort.DataReceived 给了我一些非常奇怪的结果.该计划不长,所以我将在此处完整发布:

I'm currently working with a device called a Fluke 5500A Multi-Product Calibration Device. I've written a small program in C# to interact with it and learn more about how it works but unfortunately SerialPort.DataReceived is giving me some very strange results. The program's not long so I'm going to post it in its entirety here:

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 类:

And my SerialPortConnection class:

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);
        }
    }
}

我目前的问题是控制台的输出如下所示:

My problem currently is the output to the console looks something like this:

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.

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

The commands execute just fine but the output to the console appears to be the last command that was executed and whatever data was returned by that command. I don't know why this could be.

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

Thanks to Robert P's answer I implemented the following code:

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

推荐答案

您的问题之一是串行通信远非瞬时完成..ReadExisting() 方法从 SerialPort 对象的缓冲区中提取数据,但不确保设备已完成发出其命令.可以这样想:

One part of your problem is that serial communication is far from instantaneous. The .ReadExisting() method pulls data out of the SerialPort object's buffer, but does nothing to assure that the device has finished issuing its command. Think of it like this:

+----+            +----------+           +------------+
|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) +----------+           +------------+

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

Instead, look for a pattern, token, or other identifying mark to know that transmission is complete BEFORE sending the next command. Keep reading (expect timeouts - they're thrown as an exception!) until you know you have received the entire reply. In this case, it might be that the > character represents "ready for more input". You can interpret it to also mean "Response is complete."

这篇关于SerialPort.DataReceived 返回奇怪的结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆