Просмотр полной версии : Время ответа контроллеров ПЛК 110-60
Добрый день уважаемые! Понадобилось мне переходить на другие контроллеры в связи со снятием с производства ADAM 5510. Для связи контроллеров с компьютером на котором стоит программа управления оборудованием у нас была самописная библиотека для сети ultranet, которая обеспечивала очень быструю работу по сети rs-485 до 6 контроллеров с количеством переменных порядка 2000-3000.
Был выбран ПЛК 110-60. Но встала проблема взаимодействия ПЛК с уже написаной программой управления. Использовать СКАДУ и начинать все по новой как то не хотелось. Было принято решение найти какую нибудь фришную библиотеку под СИ и прикрутить ее к нашей программе управления для использования протокола modbus rtu. Излазив пол интернета в поисках такой библиотеки, я пришел к выводу, что кроме кросплатформенной libmodbus ничего и нет. Но как оказалось, эта библиотека не подходит для нашей задачи. С одним контроллером еще кое как работает, но вот пара уже никуда не годится. Тормоза программы страшные. Решил прогуляться по коду и был немного шокирован как эта библиотека написана. Оказывается при работе с COM портом не используется асинхронный режим! Да и сам автор в комментариях кода написал, что типа ребята, я не знаю как реализовать или не захотел реализовывать этот режим. Наверное все кто пишет работу с COM портом знают, что инициализировать порт нужно с флажком FILE_FLAG_OVERLAPPED и далее организовывать два потока. На чтение и запись используя события WaitCommEvent. Иначе ничего хорошего не получится.
Пришлось отказаться от этой библиотеки и писать реализацию modbus самому. Вроде как получилось. Для решения своих задач я не реализовывал множество функций. Только чтение массива регистров, запись одиночного coil, word, dword и float. Для упрощения дальнейшей работы сделал классы типов используемых переменных. В используемой программе просто создаются новые объекты переменные. Функции работы с modbas инкапсулированы в классах.
Сейчас на столе пара контроллеров с залитыми программами. И написана тестовая программка опрашивающая эти контроллеры и посылающая на запись по нажатию кнопки некоторые переменные. Для контроля обмена по порту использован Free Serial Port Monitor
Вот скриншот что передается по порту. 29807Опрашиваются 41 и 32 регистра. Также видны посылки записи четырех переменных типа coil. На контроллерах использованы вторые порты в режиме мастера для опроса внешних модулей и управления частотными преобразователями.
Все это предисловие сводится к одному вопросу. Это минимальное время (0.0313 секунды) ответа контроллера после запроса или можно как то еще его уменьшить? Скорость порта 115200.
Странно. 62 просмотра и ни одного ответа. Неужели никто не работает по модбасу? :(
Филоненко Владислав
07.03.2017, 18:39
Я даже не знаю, как кто-то смог реализовать на наших ПЛК синхронный режим работы с COM-портом. Это фантастика.
А если Вы говорите о ПК, то да, там возможно и такое.
Спасибо! Скорее всего я невнятно задал вопрос. Само время ответа понятно зависит от количества читаемых регистров. Но меня интересует именно время задержки ответа контроллера после получения запроса. Оно стабильно равно 0.0313 секунды независимо от количества читаемых регистров или от кода команды запроса.
Можно. Используйте какой-нить другой мастер и/или ПК. Эта комбинация - слаба.
А вот этот ответ я не понял. Поясните пожалуйста, что вы имеете ввиду говоря использовать другой мастер и/или ПК? И какую вы имели ввиду комбинацию, говоря комбинация слаба?
На сейчас я реализовал следующее. Обычный компьютер (ПК?) на котором установлена самописная программа на C++ Builder 6.0 (мастер, как описано в первом посте) опрашивает по COM порту 2 контроллера ПЛК 110-60. Реализован протокол modbus-rtu. Минимальное время задержки ответа от контроллера получается 0.0313 секунды.
В CodeSys в параметрах модуля RS-485 параметр Framing time поставил 5ms. Можно поставить 0 и можно поставить 30 ms. Время задержки ответа от контроллера не меняется. А вот при увеличении более 30 ms время задержки начинает увеличиваться пропорционально увеличению параметра Framing time.
Дело в том, что для реализации проекта требуется подключение по сети до 6 контроллеров типа ПЛК 110. А на одном из шести контроллеров мне нужно читать около 150 регистров. И оперативно (в течении не более 0,5 секунды) менять содержимое примерно 40 регистров. Суммарно время опроса всех 6 контроллеров хочется иметь в пределах 0,1 секунды.
Поэтому я и стремлюсь уменьшить время задержки ответа контроллера на запрос мастера, что повысит общее быстродействие сети. Это решаемо в принципе или я просто что то не так делаю, если это время по вашему слишком большое?
Я даже не знаю, как кто-то смог реализовать на наших ПЛК синхронный режим работы с COM-портом. Это фантастика.
Говоря про реализацию асинхронного режима, я имел ввиду именно ПК. libmodbas для windows написан без использования асинхронного режима работы именно COM порта. Что вызывает блокирование работы основного потока программы, пока COM порт не получит ответ на запрос или не истечет время таймаута. Что визуально приводит к зависанию работы программы на ПК пока длится таймаут или пока не придет ответ. Поэтому мне пришлось отказаться от использования libmodbus и писать свою реализация modbus-rtu на C++ Builder 6.0. Я не программист вообще (но приходится), поэтому прошу заранее извинить за корявость изъяснения.
Филоненко Владислав
09.03.2017, 11:19
1. Осцилографом надо убедится, что реально такая задержка. А не причуды Windows. Очень уж ровное время.
2. Посмотреть цикл работы программы. Чем больше цикл - тем дольше ответ.
P.S. Всё же очень стабильное время ответа.
Осциллографа нет к сожалению. Проверка только программно. Но это похоже на правду. Добавление узлов увеличивает время отклика отдельного узла сети.
Сама программа пока тестер. На форме висит 4 TEdit, пара кнопок. Потоки чтения и записи из порта отдельные, синхронизированы мьютексом. Используется маска для WatComEvent по приходу байта. То есть цикл чтения из порта независим от основного потока программы. В основной цикл могу вставить Sleep(100000). На чтении из COM порта это никак не сказывается, хотя форма замерзает и не реагирует ни на что. Чтение из приемного буфера происходит очень быстро. Мне даже приходится вводить задержку на чтение, иначе буфер выбирается быстрее, чем заканчивается посылка от контроллера и часть пакета оказывается не прочтенной. Но эта задержка ни на что не влияет. Я пробовал убирать ее совсем и указывать ReadFile(COMport, bufrd,btr, &temp, &overlappedrd) вместо btr конкретную число ожидаемых байт. Да, функция считывает все байты, но задержка ответа от контроллера меньше не становится. Сейчас btr определяется из comstat.cbInQue. Но чтобы cbInQue был верным, приходится вводить перед функцией ReadFile, Sleep(20). Иначе идут обрывы. Все дело в том, что событие EV_RXCHAR это приход первого байта. И вызов функции ClearCommError для получения числа принятых байт, сразу после события прихода первого байта некорректна, так как посылка еще полностью не принята. Поэтому и приходится вводить Sleep(20).
Филоненко Владислав
09.03.2017, 20:34
Я не большой специалист в работе с аппаратным портом UART в Windows, но sleep (20) явно не правильное решение. Запрос 1 мс. пусть ПЛК тупит - ещё 2-3 мс, ответ идёт 5мс.
Я вообще не спец к сожалению. Без sleep(20) иногда не правильно определяется количество байт принятых в буфер uart. Соответственно и ReadFile считывает не полностью пакет из буфера uart. Это не имеет никакой системы. Как бы рандомно происходит. Как отловить и почему это происходит, не знаю. Может конечно и windows виновата, но самописная (не мной) библиотека для ultranet, работает на этой же windows без сбоев и с высокой скоростью. Значит дело не в windows, а в моей неграмотности. А жить то хочется! :D
Я вообще не спец к сожалению. Без sleep(20) иногда не правильно определяется количество байт принятых в буфер uart. Соответственно и ReadFile считывает не полностью пакет из буфера uart. Это не имеет никакой системы. Как бы рандомно происходит. Как отловить и почему это происходит, не знаю. Может конечно и windows виновата, но самописная (не мной) библиотека для ultranet, работает на этой же windows без сбоев и с высокой скоростью. Значит дело не в windows, а в моей неграмотности. А жить то хочется! :D
Windows не является ОС реального времени и может запросто похерить обмен по последовательному порту для выполнения более приоритетных задач. По этой причине битые пакеты обязательно будут и их надо просто отбраковывать.
Филоненко Владислав
10.03.2017, 18:47
И читать надо по 1 байту до победного конца или наступления таймаута ожидания ответа
И читать надо по 1 байту до победного конца или наступления таймаута ожидания ответа
Так делал. Начинает тормозить основной поток программы так, что работать невозможно. Чтение по одному байту возможно если писать COMport = CreateFile(NumPort,GENERIC_READ | GENERIC_WRITE, 0,NULL, OPEN_EXISTING, 0, NULL); У меня используется COMport = CreateFile(NumPort,GENERIC_READ | GENERIC_WRITE, 0,NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); Без этого флага основной поток встает, пока будет крутится цикл чтения по одному байту и программой пользоваться невозможно. С одним контроллером еще можно. Но когда в опросе их до 8 штук, то решение я нашел только так.
И самое забавное!!! Например настроил порт, вроде все нормально. Даже ошибок нет по тайм ауту. Но стоит запустить Гугл хром, то начинают валиться ошибки чтения! Не таймауты, а именно читает не весь пакет отправленный контроллером. Визуально на работе программы это никак не сказывается, но сам факт потери множества пакетов при работе Гугл хрома удивляет. Параллельный запуск других приложений не вызывает такой катастрофы. А с Гугл хромом примерно 50% пакетов потеряны. Интересно, что Гугл Хрому нужно от COM порта? Другие браузеры не пробовал. Просто их нет на машине.
Филоненко Владислав
22.03.2017, 14:11
Ну так создаёте отдельный процесс, там читаете без флага OVERLAPPED, обмен между процессами через майлбокс.
Процессу приоритет повыше. Ничего не тормозит, хром отдыхает.
Powered by vBulletin® Version 4.2.3 Copyright © 2026 vBulletin Solutions, Inc. All rights reserved. Перевод: zCarot