Как я могу имитировать взаимодействия SerialPort для тестирования?

#c# #serial-port #simulation

#c# #последовательный порт #Симуляция

Вопрос:

Я собираюсь приступить к разработке небольшого приложения (C #), которое взаимодействует с ПЛК и модулем тестирования через последовательные порты — это мое первое предприятие в этой области.

По сути, я собираюсь отправить ПЛК сигнал для запуска операции, а затем я собираюсь дождаться результата этой операции от тестового модуля (который будет независимо взаимодействовать с ПЛК), чтобы вернуть строку ASCII.

В зависимости от содержимого этой строки я могу захотеть прослушать сигнал от ПЛК…

Для меня это все ново, поэтому на данный момент я просто исследую System.IO.Ports.SerialPort; отступление: существуют ли сторонние продукты, которые упрощают взаимодействие с последовательным портом, или встроенные классы настолько хороши, насколько вы можете получить? Я имею в виду простоту использования в отличие от улучшенных функций.

Однако пройдет несколько недель, прежде чем оборудование будет доступно для разработки и тестирования, поэтому мне было интересно, как я мог бы имитировать связь с последовательным портом, чтобы я мог начать разработку своего приложения?

[Я пока не знаю, как ПЛК и ПК должны взаимодействовать — я понимаю, что это будет двоичный файл, а не текст, но на данный момент это все, что я знаю.]

Комментарии:

1. Я всегда задавался этим вопросом при написании некоторых приложений для моего Arduino. Насколько я знаю, единственный способ действительно имитировать данные на последовательном порту — это использовать аппаратное устройство обратной связи (есть инструкции по созданию вашего собственного, и это не так уж сложно). Приведенный ниже ответ на интерфейс является хорошей альтернативой.

Ответ №1:

Абстрагируйтесь от связи с последовательным портом за интерфейсом, чтобы вы могли кодировать свое приложение в соответствии с интерфейсом, а затем тестировать с «поддельной» реализацией. Когда у вас есть аппаратное обеспечение для реальной работы, вы можете закодировать «настоящую» реализацию интерфейса и заменить поддельную.

Итак, например, у вас должен быть интерфейс

 public interface ISerialComms
{
    void SendMessage(string message)
}
  

и вы бы кодировали свое приложение для этого интерфейса, используя поддельную реализацию:

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

Надеюсь, это поможет!

Комментарии:

1. Мне нравится это решение. Для интеграционного тестирования, хотя я часто обнаруживаю, что у меня нет доступа к оборудованию, с которым я взаимодействую, если я не нахожусь на сайте заказчика. Это несколько ограничивает мою способность эффективно выполнять интеграционные тесты, если я не напишу какой-нибудь симулятор.

2. @Cole конечно, в какой-то момент понадобится какой-то симулятор, но для начала работы интерфейса должно быть достаточно. @n8wrl Да, конечно, следовало бы упомянуть об этом! 🙂

3. Ничего подобного раньше не делал, но имеет смысл … если я смогу точно выяснить, как это сделать.

Ответ №2:

В прошлом я добился некоторого успеха, используя com0com.

Комментарии:

1. 1 На самом деле я вернулся и использовал это, и оно работает лучше, чем приложение, которое я предложил ниже. Приложение, которое я предложил ниже, похоже, блокирует все вызовы к этим портам по какой-либо причине.

2. Примечание: Я изменил ссылку на фактическую страницу проекта вместо com0com.sourceforge.net : это частично «перенято» драйвером виртуального последовательного порта от Eltima Software. В этом программном обеспечении нет ничего плохого, но мы не хотим заманивать людей нажимать на их ссылку для скачивания вместо com0com, плюс это относится к отдельному ответу.

3. Дополнительное примечание: com0com работает, но прочитайте README: на момент написания установка в последних версиях Windows приведет к тому, что драйвер не будет загружен, поскольку в нем отсутствует подпись, поэтому вам нужно отключить «Принудительное использование подписи драйвера», т.е. эквивалент bcdedit.exe -set TESTSIGNING ON . Используйте на свой страх и риск.

Ответ №3:

Есть две части программного обеспечения, которые я нашел бесценными при выполнении работы с последовательным портом.

Бесплатный монитор последовательного порта

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

Несмотря на дурацкое название, на самом деле это довольно полезно. Обратите внимание, что вы должны заставить его прекратить прослушивание вашего порта, если вы собираетесь отключить конвертер USB-to-Serial. В противном случае это может привести к сбою (ну… ждать бесконечно при выходе, что раздражает). Ему не нужно вставлять себя в середину последовательного соединения, чтобы перехватывать данные. Он отслеживает ввод-вывод с помощью Win32 API.

Инструменты последовательного порта Фрэнсона

http://franson.com/serialtools/

Или .. действительно, любое программное обеспечение с обратной связью. Их там много. Это позволяет отправлять данные и получать их в программном обеспечении. Если вы в конечном итоге выполняете какую-либо работу с GPS, у Фрэнсона также есть хороший симулятор GPS, так что вам не придется все время сидеть снаружи для отладки кода.


Наконец, если вам надоел встроенный serial class и его ужасающие недостатки, тогда вам нужна замена, и переход сразу к Win32 API займет вечность.

CommStudio

Я обнаружил, что CommStudio абсолютно надежна. Честно говоря, потратив 5 месяцев на исследования и покупку других вариантов, это единственный, который отлично работает со съемными USB-адаптерами. Все другие решения имеют проблемы при повторном подключении устройства. Вы можете скачать их бесплатную «Экспресс» версию здесь:http://www.componentsource.com/products/commstudio/downloads.html?rv=42917

Ответ №4:

Я написал статью на эту тему, используя драйвер виртуального последовательного порта стандарта 9.0, используя класс Microsoft SerialPort (Sytem.IO.Ports), конечно, можно использовать любой другой инструмент для подключения к порту.

В программном обеспечении я создаю 2 виртуальных порта COM1 и COM2.

Я использую COM1 для эмуляции в качестве отправителя данных.

Я использую COM2 для получения того, что когда-либо отправлялось из COM1.

Это полезно, если вы разрабатываете встроенное решение или IoT-решение.

Эмулятор (в данном примере в качестве случайного акселерометра)

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

Отказ от ответственности: ссылка в этом руководстве относится к моему личному веб-сайту.

Ответ №5:

Мне нравится ответ Дэвида выше, но если вы хотите провести интеграционные тесты и фактически протестировать вашу связь с последовательным портом, я использовал приложение под названием ViN soft virtual serial cable в прошлом, чтобы в основном создать 2 последовательных порта на вашем компьютере, которые подключены виртуальным кабелем.

Также, если у вас есть последовательный порт на вашей машине разработки, вы могли бы использовать его для подключения к другой машине, имеющей последовательный порт, и написать приложение, которое в основном будет имитировать взаимодействие ПЛК.

Я бы предпочел использовать комбинацию метода Дэвида и этого метода для обеспечения надлежащего тестирования.

Комментарии:

1. У меня есть другие доступные компьютеры, поэтому запуск тестового приложения на одном из них вполне возможен, и это моя резервная позиция. Я также проверю приложение ViN soft. Спасибо

Ответ №6:

Существует другой ресурс, который эмулирует последовательные порты для Windows, если кто-то еще все еще ищет достойные средства последовательной отладки.

32-разрядная версия бесплатна и кажется довольно приличной. Это называется Эмулятор виртуальных последовательных портов.

Ответ №7:

Очень старый, но все еще может быть полезен некоторым. Вместо того, чтобы полагаться на взаимодействие COM, просто используйте SerialPort.BaseStream для связи с портом. Это позволяет вам просто использовать стандартный интерфейс stream для обмена данными, другими словами, не имеет значения, используете ли вы последовательные порты, TCP-соединения или даже файловые потоки. Идеально подходит для симуляции.