C# 如何模拟串行端口交互以进行测试?

C# 如何模拟串行端口交互以进行测试?,c#,serial-port,simulation,C#,Serial Port,Simulation,我即将开始开发一个小型应用程序(C#),它通过串口与PLC和测试单元进行通信——这是我在这一领域的第一次尝试 本质上,我将向PLC发送一个启动操作的信号,然后等待测试单元(将与PLC独立通信)返回ASCII字符串的操作结果 根据该字符串的内容,我可能想要听来自PLC的信号 这对我来说是全新的,所以目前,我只是在研究System.IO.Ports.SerialPort;题外话:除了简化与串行端口的交互之外,还有第三方产品吗?,或者内置类是否与您将获得的一样好?我考虑的是易用性,而不是更好的功能 然

我即将开始开发一个小型应用程序(C#),它通过串口与PLC和测试单元进行通信——这是我在这一领域的第一次尝试

本质上,我将向PLC发送一个启动操作的信号,然后等待测试单元(将与PLC独立通信)返回ASCII字符串的操作结果

根据该字符串的内容,我可能想要听来自PLC的信号

这对我来说是全新的,所以目前,我只是在研究System.IO.Ports.SerialPort;题外话:除了简化与串行端口的交互之外,还有第三方产品吗?,或者内置类是否与您将获得的一样好?我考虑的是易用性,而不是更好的功能

然而,硬件的开发和测试还需要几周时间,因此我想知道如何模拟串行端口之间的通信,以便开始开发我的应用程序?


[我还不知道PLC和PC是如何通信的-我知道它将是二进制的,而不是文本的,但目前我只知道这些。]

将串行端口通信抽象到接口后面,以便您可以根据接口编写应用程序代码,然后使用“假”实现进行测试。当你有了真正的硬件时,你可以对接口的“真实”实现进行编码,然后换掉假的

例如,你有一个接口

public interface ISerialComms
{
    void SendMessage(string message)
}
你会使用一个假的实现,针对该界面编写你的应用程序:

public class FakeSerialComms : ISerialComms
{
    public void SendMessage(string message)
    {
        //some implementation
    }
}

希望有帮助

我在过去的使用中取得了一些成功。

我喜欢上面David的回答,但如果您希望进行集成测试并实际测试串行端口通信,我在过去使用了名为ViN soft virtual serial cable的应用程序,基本上在您的机器上创建了两个通过虚拟电缆连接的串行端口

此外,如果您的开发机器上有一个串行端口,您可以使用它连接到另一台有串行端口的机器,并编写一个基本上模拟PLC通信的应用程序


我更愿意结合使用David的方法和此方法来确保正确的测试。

在进行串行端口工作时,我发现有两个软件非常宝贵

自由串行端口监视器

尽管它的名字很俗气,但它实际上非常有用。请注意,如果要拔下USB到串行转换器的插头,您应该让它停止侦听端口。否则它可能会崩溃(嗯……在退出时无限期地等待,这很烦人)。它不必把自己放在一个串行连接的中间来嗅探数据。它使用Win32 API监视IO

Franson串口工具

或者。。任何环回软件都可以。外面有很多。这允许您在软件中发送和接收数据。如果你最终做了任何GPS工作,Franson还有一个很好的GPS模拟器,这样你就不必整天坐在外面调试代码了


最后,如果您已经受够了内置串行类及其可怕的缺点,那么您需要更换它,而直接使用Win32 API将花费永远的时间

通信工作室
我发现它绝对坚如磐石。坦率地说,在花了5个月的时间研究和购买其他选项后,它是唯一一款能够与可移动USB适配器完美配合的产品。当设备重新插入时,所有其他解决方案都会出现问题。你可以在这里下载他们的免费“Express”版本:

如果其他人仍在寻找合适的串行调试工具,还有另一个资源可以模拟windows的串行端口

32位版本是免费的,看起来相当不错。它的名字叫。

我已经用虚拟串口驱动程序9.0标准写了一篇关于这个主题的文章,使用Microsoft SerialPort类(Sytem.IO.Ports),当然也可以使用任何其他通信端口工具

在软件中,我创建了两个虚拟端口COM1和COM2

我使用COM1作为数据发送器进行仿真

我使用COM2接收COM1发送的内容

如果您正在开发嵌入式或物联网解决方案,这将非常有用

模拟器(在本例中为随机加速计)

我的数据接收器几乎是相似的

private static bool _continue;
private static SerialPort _serialPort;

public static void Main()
{
    var stringComparer = StringComparer.OrdinalIgnoreCase;
    var readThread = new Thread(Read);

    _serialPort = new SerialPort
    {
        PortName = "COM2",
        ReadTimeout = 500,
        WriteTimeout = 500
    };

    _serialPort.Open();
    _continue = true;
    readThread.Start();

    while (_continue)
    {
        var message = Console.ReadLine();

        if (stringComparer.Equals("quit", message))
        {
            _continue = false;
        }
        else
        {
            _serialPort.WriteLine(message);
        }
    }

    readThread.Join();
    _serialPort.Close();
}

public static void Read()
{
    while (_continue)
    {
        try
        {
            var message = _serialPort.ReadLine();
            Console.WriteLine(message);
        }
        catch (TimeoutException) { }
    }
}
免责声明:本指南的链接指向我的个人网站


很老了,但对一些人来说还是有用的。不要依赖COM交互,只需使用SerialPort.BaseStream与端口通信即可。这使您可以简单地使用标准流接口进行通信,换句话说,无论您使用的是串行端口、TCP连接还是文件流。非常适合模拟。

在为我的Arduino编写一些应用程序时,我一直想知道这一点。据我所知,在串行端口上真正模拟数据的唯一方法是使用硬件环回设备(有自己的方向,这并不难)。下面的界面答案是一个很好的选择。我喜欢这个解决方案。对于集成测试,尽管我经常发现,除非我在客户现场,否则我无法访问正在连接的设备。这在一定程度上限制了我有效地进行集成测试的能力,除非我编写某种模拟器。@Cole当然,它在某个时候需要某种模拟器,但对于入门来说,接口应该足够了@n8wrl是的,当然是,应该提到这一点!:)以前没有做过类似的事情,但是很有意义…如果我能准确地知道怎么做的话。我有其他可用的机器,所以在其中一台机器上运行测试应用程序是完全可能的,这是我的备用方案。我还将查看ViN软件应用程序。谢谢+1我真的回去用了这个
private static bool _continue;
private static SerialPort _serialPort;

public static void Main()
{
    var stringComparer = StringComparer.OrdinalIgnoreCase;
    var readThread = new Thread(Read);

    _serialPort = new SerialPort
    {
        PortName = "COM2",
        ReadTimeout = 500,
        WriteTimeout = 500
    };

    _serialPort.Open();
    _continue = true;
    readThread.Start();

    while (_continue)
    {
        var message = Console.ReadLine();

        if (stringComparer.Equals("quit", message))
        {
            _continue = false;
        }
        else
        {
            _serialPort.WriteLine(message);
        }
    }

    readThread.Join();
    _serialPort.Close();
}

public static void Read()
{
    while (_continue)
    {
        try
        {
            var message = _serialPort.ReadLine();
            Console.WriteLine(message);
        }
        catch (TimeoutException) { }
    }
}