Здравствуйте, возникла проблема с чтением регистров оборудования. Суть в том, что одновременно можно считывать только 1 регистр, а требуется прочитать 7 регистров. Пробовал использовать ChGroupReq, но насколько я понял, он читает все регистры разом. Пробовал оставлять ему один аргумент и все равно не считывает значение. Была информация, что можно сделать как-то через AsyncCollection, но так и не понял как. Протокол modbus.
Posted by АдАстра. Техподдержка (Участник № / Member № 4) on :
ChGroupReq организовывает групповой запрос. Количество запрошенных регистров зависит от количества аргументов канала Call.
Создаете 7 источников ModBus для чтения 1 регистра (разных). Создаете Call.ChGroupReq с одним аргументов необходимого типа. Источники привязываете к каналам. Каналы Call.ChGroupReq привязываете к Call.AsyncCollection
Posted by АдАстра. Техподдержка (Участник № / Member № 4) on :
Так же задачу можно решить без Call.ChGroupReq и Call.AsyncCollection.
Каналы отрабатываются последовательно, согласно их id. У Вас есть 7 источников ModBus для опроса. Перенесите их в узел в обратном порядке. В этом случае первым отрабатывать будет канал, который должен запросить данные с последнего адреса. Группового запроса не будет.
Posted by kashpir88 (Участник № / Member № 8429) on :
Все получилось, большое спасибо.
Posted by Udjin (Участник № / Member № 8428) on :
Добрый день. Задача: Опросить последовательно 56 регистров (DiscreteInput, адрес 0 - 55) одним запросом. Создаю канал в "Источники/приемники" Rin_Byte(2) связываю его с каналом CALL.ChGroupReq в котором создаю 7 аргументов типа USINT, запускаю проект. Запускаю программу ModBusSlave в котором указываю статусы в данных регистров и запускаю "просмотр трафика" и вижу, что МРВ опрашивает только 32 регистра. Если меняю тип аргументов с USINT на INT тогда все работает и опрашивает 56 регистров. Почему так происходит ведь тип USINT это однобайтовая переменная, как и указано в справочнике "....Выполняется соответственно групповое чтение или групповая запись (WORD, FLOAT) при обмене с заданным устройством по MODBUS RTU или MODBUS TCP/IP. Устройство и начальный адрес задаются в источнике, количество считываемых/устанавливаемых параметров определяется числом аргументов канала. В зависимости от дополнения к подтипу привязанного источника/приемника: Rout_Byte, Rin_Byte (1, 2) – 8 бит в аргументе;".... Может я что-то упускаю?
Posted by АдАстра. Техподдержка (Участник № / Member № 4) on :
Релиз 6.10.2 канал в "Источники/приемники" Rin_Byte(2) связываю его с каналом CALL.ChGroupReq в котором создаю 7 аргументов типа USINT. Запускаю программу ModSim.
При изменении любого бита с 1 по 56, в аргументы канала CALL.ChGroupReq корректно записываются считанные значения (каждый аргумент принимает значение от 0 до 255 в зависимости от взведенных бит).
Posted by Udjin (Участник № / Member № 8428) on :
Ничего подобного. Не работает так... Даже совсем в пустом проекте сделал именно так как Вы описали. Выдает значение только 32 регистров. Проверяю линию "RS-485", действительно запрос от СКАДА идет только 32 регистров....
Posted by Udjin (Участник № / Member № 8428) on :
В чистом проекте в "Источники/приемники" создаю канал Rout_Float(3), связываю его с каналом CALL.ChGroupReq в котором создаю 2 аргумента типа Float, запускаю проект. Запускаю программу ModBusSlave в котором указываю статусы в данных регистров и запускаю "просмотр трафика" и вижу, что МРВ опрашивает 8 регистра. Зачем? Ему по всей логике необходимо 4 регистра (НО 8 Байт).....может быть тут какая-то путаница или она у меня в голове?! Открываю "Служебную панель МРВ", далее канал тот самый Call и в аргументе 124 вижу, что он получил значения 2 аргументов А0 и А1. Но если у меня в удаленном устройстве ограниченное количество регистров тогда выскакивает ошибка по запросы ModBus
Posted by АдАстра. Техподдержка (Участник № / Member № 4) on :
Если привязываете CALL.CGR с двумя аргументами float к источнику Rout_Float(3), у которого в строке IP-адрес не задан ключ BYARG, то суммы длин аргументов Call не анализируются и запрашивается 2 регистра. Для RTU запрашивается количество регистров, согласно заданным аргументам. В Вашем случае будет 4 регистра.
Количество запрашиваемых регистров можно наблюдать по перехвату в тексте запроса.
Как Вы наблюдаете, что МРВ опрашивает именно 8 регистров?
Posted by Udjin (Участник № / Member № 8428) on :
Чтобы наблюдать что МРВ опрашивает именно 8 регистров, я запускаю встроенный в программу ModBus Slave Version 6.2.0 снифер. И в теле запроса от МРВ вижу строку Rx:003420-01 03 00 00 00 08 44 0C. А уже из структуры запроса ModBus RTU понятно, что 0008 - это число запрашиваемых регистров.
Posted by АдАстра. Техподдержка (Участник № / Member № 4) on :
Возможно в проекте задано несколько запросов Modbus подряд? Если несколько и вызываемые каналы идут по возрастанию ID, то будет реализовываться групповой запрос для оптимизации обмена. И возможно наблюдаете именно его.
Если в пустом проекте задать Call.CGR in c 2 аргументами Float in, привязать к источнику Rout_Float(3) (с адресом устройства 1 и адресом регистра 0 в данном случае), задать в проекте COM-порт, то в этот порт будет писаться следующий запрос:
Информация о транзакциях и COM-порте будет писаться в текcтовый файл <имя проекта>_<№ узла>.txt. (По окончанию отладки диагностику уберите, т.к. текстовый файл пишется без ограничений до следующего перезапуска.)
Если все равно желаемое не сойдется с полученным результатом, то чтобы не гадать, пришлите, пожалуйста, используемый проект на адрес техподдержки со ссылкой на этот топик. Адрес указан в личном кабинете в разделе "Обратиться за технической поддержкой".
Posted by Udjin (Участник № / Member № 8428) on :
Сделал как Вы сказали...ничего не изменилось, только подтвердилось что сниффер от ModBus Salve работает исправно )))) (0:27:46) INFO:COM4<ch1>send=010300000008440C Сейчас вышлю сам проект.
Posted by АдАстра. Техподдержка (Участник № / Member № 4) on :
Проект получили.
Для чтения переменных типа Float создайте источник Rout_Word(3), привяжите его к каналу Call.CGR (тип IN) с 2 аргументами типа REAL IN. При этом будут запрошены 4 регистра.
Для чтения переменных типа Bool создайте источник Rin_Byte(2), привяжите его к каналу Call.CGR (тип IN) с 7 аргументами типа UINT IN. При этом будут запрошены 56 регистров.