Объявление

Свернуть
Пока нет объявлений.

TCP Modbus исключение

Свернуть
X
 
  • Фильтр
  • Время
  • Показать
Очистить всё
новые сообщения

  • TCP Modbus исключение

    Добрый день.

    Возникла проблема с одним из примеров обмена данными через TCP по Modbus (/ПЛК-40/ST/ModbusTCPMaster.project), а точнее наткнулся на зависание связанное с библиотекой "AgavaModbus, 3.5.10.0 (KB Agava), которое возникает если разорвать связь с другой стороной.

    Для теста я настроил OPC сервер Lectus как сервер, ожидающий подключения, а контроллер в свою очередь подключается к нему по IP и используя функцию 6 (Function 06 (0x06) Write Single Register) пишет значение. Это все работает до тех пор пока не случится разрыв соединения, в этом случае программа зависает, а если включить watcdog то выдает по нему исключение...

    Есть ли способ защититься от зависания? Или может есть некий обработчик исключительных ситуаций?
    Посмотреть и скачать с Яндекс.Диска

  • #2
    Сообщение от Gard-S Посмотреть сообщение
    Добрый день.

    Возникла проблема с одним из примеров обмена данными через TCP по Modbus (/ПЛК-40/ST/ModbusTCPMaster.project), а точнее наткнулся на зависание связанное с библиотекой "AgavaModbus, 3.5.10.0 (KB Agava), которое возникает если разорвать связь с другой стороной.

    Для теста я настроил OPC сервер Lectus как сервер, ожидающий подключения, а контроллер в свою очередь подключается к нему по IP и используя функцию 6 (Function 06 (0x06) Write Single Register) пишет значение. Это все работает до тех пор пока не случится разрыв соединения, в этом случае программа зависает, а если включить watcdog то выдает по нему исключение...

    Есть ли способ защититься от зависания? Или может есть некий обработчик исключительных ситуаций?
    Причина в этом

    Нажмите на изображение для увеличения. 

Название:	ex.png 
Просмотров:	230 
Размер:	16.6 Кб 
ID:	691
    снимите галочку со сторожевой таймер или увеличьте время ожидания и счетчик восприимчивости, при разрыве коннекта мастер уходит на повторную попытку установки связи, там есть таймаут, сторожевой таймер отрабатывает быстрей таймаута.

    Комментарий


    • #3
      Да, тут действительно маловат таймер и при физическом разрыве линии связь восстанавливается, но вот если в Lectus остановить и снова запустить работу, то программа виснет намертво... видимо пытается наладить связь по старой сессии, в этом случае можно как-то перезапустить коннект?
      Нажмите на изображение для увеличения. 

Название:	2021-02-16_17-30-48.png 
Просмотров:	200 
Размер:	64.2 Кб 
ID:	693

      Комментарий


      • #4
        Сообщение от Gard-S Посмотреть сообщение
        Да, тут действительно маловат таймер и при физическом разрыве линии связь восстанавливается, но вот если в Lectus остановить и снова запустить работу, то программа виснет намертво... видимо пытается наладить связь по старой сессии, в этом случае можно как-то перезапустить коннект?
        Нажмите на изображение для увеличения. 

Название:	2021-02-16_17-30-48.png 
Просмотров:	200 
Размер:	64.2 Кб 
ID:	693
        в примере как раз таки и происходит попытка реконекта с сервером при ошибке обмена


        MODE_CONNECT:

        // Подключаемся к серверу.
        result := ModbusTCPMaster.Connect();

        mode := sel( result = 0, MODE_ERROR, MODE_REQUEST );


        попытка реконекта устанволена в примере в 1с


        // Ошибка.
        MODE_ERROR:

        t1( in := true, pt := t#1s );

        if t1.q then mode := MODE_CONNECT; end_if


        т.е Вы останавливаете клиента и программа зависает?



        Комментарий


        • #5
          В таком случае мне тогда нужен OPC сервер от Lectus , чтобы зафиксировать данное поведение, я проверил через Modbus Slave, устройство ПК, данной проблемы не наблюдается ни при обрыве соединения, ни при закрытии.

          Комментарий


          • #6
            Я еще потестировал эту связку передачи данных и заметил что зависание происходит после отключения в Lectus "опроса", выделенная кнопка на скрине ранее, а точнее сам сервер продолжает работать и принимает пакет данных от контроллер, но из-за выключенного опросника сам не отвечает. В свою очередь ПЛК продолжает ждать ответа и никак не обращает внимания на свой тайм-аут, ну и таким образом не отпускает задачу... Если в Lectus возобновить "опрос", то он просто ожидает от подключенного устройства очередной запрос, так и стоят молча глядя друг на друга.

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

            Выходит в процессе выполнения вот этой части программы:

            // Выполняем запрос.
            SysTimeRtcHighResGet( start );

            result := ModbusTCPMaster.MakeRequest( request, 500 );

            SysTimeRtcHighResGet( stop );

            // Фактическое время выполнения запроса, [мсек].
            t := stop - start;

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

            Я у себя врубил ватчдог и организовал функцию перезагрузки ПЛК по его срабатыванию, пока такой вариант в общем устраивает. Но может есть путь без перезагрузки устройства? Быть может можно как-то сбросить работу "ModbusTCPMaster.MakeRequest( request, 500 )" или например ребутнуть Ethernet?

            П.с. в праздники на выходные оставил ПЛК работать и слать несколько переменных с интервалом в 1с на удаленное устройство (разные провайдеры), up-time около 4 суток.

            Комментарий


            • #7
              "Соединение" - это TCP/IP соединение. Вы его не разрываете, т.е. на обеих сторонах сокеты работают нормально. В вашем примере вы лишь задерживаете ответ и метод MakeRequest() честно его ожидает. Если ответ задерживается, то modbus сервер должен вернуть состояние Busy.

              Причина, по которой метод не отдаёт управление в том, что он реализован на синхронной функции чтения сокета стандартной библиотеки. В отличие от более сложной реализации чтения в ModbusTCPSlave, которая основана на функции select. Необходимо доработать метод MakeRequest(), используя алгоритм из ModbusTCPSlave(), чтобы покрыть такой вариант поведения.

              У Прософта есть обучающий ролик, в котором рассказано как работает select в Codesys:

              Комментарий

              Обработка...
              X