如何模拟SerialPort交互以进行测试?

时间:2011-04-12 14:08:47

标签: c# serial-port simulation

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

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

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

这对我来说都是新手,所以目前我只是在研究System.IO.Ports.SerialPort;题外话:是否有第三部分产品,而不是简化与串行端口的交互,或者内置类是否与您一样好?我想的是易用性而不是更好的功能。

然而,在硬件可用于开发和测试之前几周,所以我想知道如何模拟与串口之间的通信以便我可以开始开发我的应用程序?

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

7 个答案:

答案 0 :(得分:15)

摘要接口后面的串口通信,以便您可以针对接口编写应用程序代码,然后使用“假”实现进行测试。当你拥有真实的硬件时,你可以编写接口的“真实”实现并换掉假的。

例如,你有一个界面

public interface ISerialComms
{
    void SendMessage(string message)
}

并且您使用虚假实现对该界面编写应用程序代码:

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

希望有所帮助!

答案 1 :(得分:12)

过去我使用com0com取得了一些成功。

答案 2 :(得分:2)

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

免费串口监视器

http://www.serial-port-monitor.com

尽管名称俗气,但实际上它非常有用。请注意,如果您要拔下USB转串口转换器,您应该让它停止收听您的端口。否则它会崩溃(好吧......在退出时无限期等待,这很烦人)。它不必将自己置于串口连接的中间以嗅探数据。它使用Win32 API监视IO。

Franson串口工具

http://franson.com/serialtools/

或者..任何环回软件真的。那里有很多。这允许您发送数据并在软件中接收数据。如果你最终做任何GPS工作,Franson也有一个漂亮的GPS模拟器,所以你不必坐在外面调试代码。


最后,如果你已经有足够的内置串行类及其可怕的缺点,那么你需要一个替代品,直接进入Win32 API需要永远。

CommStudio

我发现CommStudio绝对坚如磐石。坦率地说,经过5个月的研究和购买其他选项后,它是唯一一款与可移动USB适配器完美配合的产品。当设备重新插入时,所有其他解决方案都存在问题。您可以在此处下载免费的“Express”版本:http://www.componentsource.com/products/commstudio/downloads.html?rv=42917

答案 3 :(得分:2)

如果还有其他人仍在寻找合适的串口调试工具,还有另外一种模拟Windows窗口串口的资源。

32位版本是免费的,看起来很不错。它被称为Virtual Serial Ports Emulator

答案 4 :(得分:1)

我喜欢David的上述答案,但是如果您希望进行集成测试并实际测试您的串口通信我过去使用过的应用程序称为ViN软虚拟串行电缆,基本上可以在您的机器上创建2个串口虚拟电缆。

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

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

答案 5 :(得分:1)

我已经使用Microsoft串行端口类(Sytem.IO.Ports)使用虚拟串行端口驱动程序9.0标准为此主题编写了article,当然可以使用任何其他通讯端口工具。

在软件中,我创建了2个虚拟端口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 = "COM1",
        ReadTimeout = 500,
        WriteTimeout = 500
    };

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

    while (_continue)
    {
        var x = ValueGenerator();
        var y = ValueGenerator();
        var z = ValueGenerator();
        var message = $"x:{x};y:{y};z:{z}";

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

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

public static double ValueGenerator()
{
    const int range = 1;
    var random = new Random();
    return random.NextDouble() * range;
}

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

我的数据接收器几乎与之相似

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

免责声明:本指南的链接指向我的个人网站。

答案 6 :(得分:0)

很老了,但仍然可能对某些人有用。不依赖于 COM 交互,只需使用 SerialPort.BaseStream 与端口进行通信。这允许您简单地使用标准流接口进行通信,换句话说,您是否使用串行端口、TCP 连接甚至文件流都没有关系。非常适合模拟。