1) Помогите разобраться с проблемой подключения указанного в теме прибора к ТМ по ModBus RTU.
Мгновенные параметры теплосистем данного вычислителя, такие как температура, объёмный расход, массовый расход и т.д. представлены обычным 4х байтовым float'ом (2 16-битных регистра), читаю такие параметры с помощью Rin_Float(4). Тут всё нормально.
Но вот накопительные параметры теплосистемы, такие как кол-во теплоты, суммарные масса и объём представлены числами двойной точности (4 16-битных регистра), т.е. запрашивать их нужно в групповом запросе.
Вот выдержка с форума "Взлёта"
quote: Значение находится в 0хC0BE 0хC0BF 0хC0С0 0хC0C1. Переменная, состоящая из 4 регистров, число повышенной точности. Запрашивать надо сразу 4 регистра в одном запросе. Первые два регистра 0хC0BE 0хC0BF это целая часть числа в формате signed long, вторые два 0хC0С0 0хC0C1 это дробь в формате float. Обе части имеют одинаковый знак, float находиться в пределах от -1 < float < 1. Ихнадо сложить в одно 8 байтовое число типа double после прочтения
Пробовал считать такой параметр с помощью регистров Rin_Word(4) и Rin_Float(4) в групповом запросе, но соответствующим каналам выставляется признак аппаратной недостоверности. Эксперименты с параметрами "формат" и "размерность бит" регистров устраняют выставление недостоверности каналов, но и значения в них не попадают.
При использовании 2х регистров Rin_Float(4) для группового запроса данные получаются нормально, но из-за несоответствия типов - конечный результат по прежнему не адекватен.
Сниффер ком-порта во всех случаях показывает, что запросы от ТМ к устройству по одним и тем же параметрам отличаются как друг от друга, так и от запросов ПО ЗАО "Взлёт"
2) Что за регистр Vzlet1(2,3)?
Posted by AdAstra Technical Support (Участник № / Member № 4) on :
1. Канал CALL.ChGroupReq привяжите к источнику Rin_Word(4) Modbus RTU с адресом переменной 0хC0BE. Задайте в нем 1 аргумент с типом данных UDINT. Полученный результат программным образом преобразуйте в число DFLOAT в соответствии с описанным на форуме "Взлета" алгоритмом. Передайте результат в канал типа DFLOAT.
2. Функция Vzlet1(2,3) - это попытка реализовать собственную ("Взлета") пользовательскую функцию Modbus RTU для считывания архивных данных. По опыту пользователей эта функция очень плохо вписывается в системы архивирования аналоговых величин в реальном времени. В реfльных проектах не применяется.
Posted by i.Sineev (Участник № / Member № 4448) on :
1) Правильно ли я вас понял: чтобы считать 4 шестнадцатибитных регистра 0хC0BE, 0хC0BF, 0хC0C0, 0хC0C1 (всего 8 байт), нужно использовать канал CALL.ChGroupReq всего с одним аргументом UDINT(4 байта)? А куда девать 4 байта содержащие дробную часть?
2) Никакого алгоритма преобразования в сущности нет. Просто биты регистров 0хC0BE, 0хC0BF нужно воспринимать как целое число со знаком (4 байта), для чего я использовал источник Rin_Word(4), а биты регистров 0хC0C0, 0хC0C1 - как четырёхбайтовое вещественное Rin_Float(4). А для получения результата сложить целую и дробную части.
3) Вопрос в том, как правильно организовать связь. Ведь при групповом запросе FLOAT FLOAT данные получаются, и всё что нужно в этом случае, это расшифровать биты первого FLOAT числа как UDINT. Но такой подход не совсем корректен, хоть и работает.
4) Вы советуете использовать тип UDINT. Почему!? Ведь у взлёта целая часть представлена числом signed long, наверное вы хотели написать DINT? =)
Posted by AdAstra Technical Support (Участник № / Member № 4) on :
Прощу прощения за неточность. Надо создать 2 канала CALL.ChGroupReq, каждый с 1 аргументом. У канала с адресом 0хC0BE - типа DINT, у канала с адресом 0хC0C0 - типа REAL.
Тот промежуточный результат, который Вы получили с двумя аргументами REAL, оказался достоверным только потому, что старший байт в (0хC0BE, 0хC0BF) был равен 0. Если бы это было не так, результат был неправильным.
Если воспользоваться более сложным механизмом привязки CALL.ChGroupReq к переменной MODBUS.R_FIFO_Queue, можно было бы считать сразу 2 аргумента - DINT и REAL.
Posted by i.Sineev (Участник № / Member № 4448) on :
Кое что до сих пор остаётся неясным: Как именно организовать привязки и какие источники для этого использовать.
Сейчас я использую Rin_Word(4) и Rin_Float(4), к каждому из источников привязан канал CALL.ChGroupReq с соответствующим аргументом. Обоим каналам выставляется признак аппаратной недостоверности.
Привязка к CALL.ChGroupReq (параметр=0, тип INPUT) к MODBUS.R_FIFO_Queue ничего не дала. Канал становится недостоверным на втором цикле обработки.
Posted by AdAstra Technical Support (Участник № / Member № 4) on :
Еще раз прошу прощения за оговорку. У канала CALL.ChGroupReq с привязкой к Rin_Word(4) с адресом 0хC0BE надо создать 2 аргумента с типом данных INT. Далее в программе надо превратить эти 2 INT в DINT.
Недостоверности в каналах CALL.ChGroupReq, привязанных к Rin_Word(4) и Rin_Float(4), могут возникать только при отсутствии ответа или ответе с ошибкой.
CALL.ChGroupReq с привязкой к MODBUS.R_FIFO_Queue (c адресом переменной 0хC0BE) в Вашем случае должен иметь ПАРАМЕТР=2. ARG000=4 (номепр функции Modbus), ARG001=4 (количество считываемых переменных). В ARG002 с типом данных DINT и в ARG003 с типом данных REAL должны быть записаны соответствующие переменные.
Posted by i.Sineev (Участник № / Member № 4448) on :
Спасибо за терпение. Организовал связь вторым способом. Правда наблюдается один странный побочный эффект: загрузка ЦП монитором реального времени возрасла с 7% до 50% (Pentium dual-core e6600) и изменяется по периодическому закону от 7 до 50 и наоборот =) Но это уже тема для другого обсуждения =)
Posted by AdAstra Technical Support (Участник № / Member № 4) on :
МРВ при работе с COM-портами в режиме поиска запросов к COM-портам захватывает большое время процессора с очень низким приоритетом. Для остальных потоков и задач это не является препятствием для функционирования.