0
Answered

Драйвер Modbus RTU

Владимир Нестеров 5 years ago in General updated by Vladimir Ovchinnikov (expert) 4 years ago 23

Добрый день.

При работе с драйвером Modbus RTU возник вопрос, каким образом можно получить данные из Holding Register в формате "беззнаковых 2 байта"?

Value*                        Word Size               значение
0 .. 65535                  Word(16 bit)            без знаковых 2 байта

-32768 .. 32767         Word(16 bit)            знаковых 2 байта


В контроллерах, использующих протокол Modbus RTU есть настройка, какой тип использовать для каждой переменной знаковый или беззнаковый.

Under review

Добрый день.

В драйвер Modbus RTU приходит значение "как есть", Иридиум его не обрабатывает. Если на контроллере настроен нужный тип, то в драйвер должно прийти то, что есть по факту. Сейчас что получаете?

Коллеги, добрый день.

Действительно любое устройство Modbus RTU передает значение как есть и уже на принимающем оборудовании выбирается, каким образом обрабатывать.

То есть на контроллере или в СКАДА системе мы будем выбирать данный регистр знаковый или беззнаковый, от этого будет зависеть какое значение мы получим.

Либо это будет от 0 до 65535, либо это будет от -32768 до 32768.

В протоколе не предусмотрена передача типа переменной, это обрабатывает принимающая сторона.

То есть в драйвере должна быть предусмотрена возможность выбора, какое значение получать из Holding Register Word 16bit лтбо это будет знаковое, либо беззнаковое.

Всё верно. В драйвер приходит "как есть". После - можем обрабатывать как надо (через скрипты, через шаблоны).

Владимир, шаблоны, это не то.

Если мы получаем значение 16 бит, в котором у нас прихоят 2 поля данных старший байт (первые 8 бит) и младший байт (вторые 8 бит), и нам их надо правильно обработать.

То в этой ситуации нам нужно очень точно обработать данны. Чтобы получить нужную информацию.

Например мы получили число 28155, когда мы его разложим на старший и младший байт то получим 109 и 251 соответственно. При этом мы получаем нужный нам код из данного числа.

Но вот если мы получим число на входе отрицательное, тогда получается не то, что нам надо.

пример - зачение -1349 = старший -6, что ничему не соответствует и младший 187 такого кода в системе передающей также нет!
То есть обработать не получиться(((

Waiting for user's reply

Отрицательное число в данном случае это функция пользователя. Поэтому в канале всегда будет 2 байта без знака.


1) Какое значение получаете сторонним клиентом Modbus?

2) Совпадает ли оно с получаемым значением в Иридиум?


Если совпадает, то получайте значение в HEX, а потом обрабатывайте. Кстати, шаблоны позволяют в панельном проекте получать HEX без использования скриптов. Например, в ПЛК вы записали десятичное число -1349. В панель получили FFFFFAB. Decimal from signed 2's complement = -1349.

Коллеги, я понимаю, что скриптом я могу обработать данные, полученные. И сформировать то что мне нужно. Хорошо, если это будет 1 скрипт, а если это будет 500 переменных и обработка каждой скриптом, считаю это немного утопичной идеей. 

Хочется просто получить правильные значения. С возможностью выбора первого или второго варианта для Word(16 bit).

Сейчас этого функционала нет, но на дальнейшее он очень нужен. Избавляет от дополнительных скриптов и дополнительного кодирования, и, как следствие, экономит время разработчика.

Давайте уточним:

1) В ПЛК у вас тип Holding Register, размер Word(16 bit).

2) Проект панельный или серверный?

3) Совпадают ли значения, которые получают из этого регистра сторонний клиент и Иридиум?

4) Что, по-вашему должно приходить в фидбэк драйвера Modbus RTU, если в ПЛК вы записали значение -1349?

Позвольте вмешаться. В протоколе Modbus за знак числа отвечает последний 15-ый бит. Если он установлен в 1, то число интерпретируется как отрицательное, если там 0, то число положительное. Этот 15-ый бит резервируется под знак в том случае, если используется знаковое представление числа при этом диапазон значений получается от -32767 до 32767. Если нам нужно использовать числа больше, чем 32767 (или например использовать регистр как битовое поле), то используют беззнаковое представление числа, при этом 15-ый бит используется в составе числа и не отвечает за знак. При этом мы получаем число от 0 до 65535. И это полностью зависит от драйвера опроса, а не от ПЛК. Во всех системах, работающих с протоколом Modbus есть как 16-бит signed, так и 16-бит unsigned типы регистров, иначе невозможно правильно принять те же самые битовые поля, так как при установке 15-го бита мы вместо ожидаемого числа 32768 получим -32768 и все вычисления поплывут, что и произошло в этом тикете.

В крайнем бите будет ноль при использовании значения без знака.

Драйвер получит набор бит по опросу. Мы не против внести доработку, если это действительно облегчит разработку интеграторам. Однако нам нужно знать - что ожидается в драйвере, если в ПЛК записано отрицательное число? Например, в регистре значение -1349. Что должно прийти в драйвер по опросу?

В драйвер придет число FFFF FABB. Но если мы пришлем в этот же драйвер число 64187, то драйвер увидит то же самое число FFFF FABB. Поэтому требуется чтобы драйвер был в курсе знаковое или беззнаковое число он опрашивает

Если вы сторонним клиентом подключитесь к ПЛК, вы увидите то же самое. Не только в Modbus RTU, но и в Modbus TCP. В Иридиум драйвер работает точно так же.

Можно обрабатывать на клиенте получаемые значения по следующему алгоритму:

1) Получаем значение "как есть".

2) Если выставлен некий флаг в драйвере и если полученное значение больше 32768, то вычитаем из этого значения 65536.

2) Выводим результат в фидбэк Modbus RTU.


По факту это будет некая "маска", которая будет делать постобработку получаемых значений. Мы правильно поняли ваши пожелания? Если правильно, то можем реализовать такую функциональность в драйвере Modbus RTU.

Владимир.

В драйвере нужно реализовать следующие типы "word size":

  • Word(16 bit) signed
  • Word(16 bit) unsigned
  • Dword(32 bit) signed
  • Dword(32 bit) unsigned

Word(16 bit) signed - будем получать значения -32768 .. 32767

Word(16 bit) unsigned - будем получать значения 0 .. 65535

Dword(32 bit) signed - будем получать значения -2147483648 .. 2147483647

Dword(32 bit) signed - будем получать значения 0 ... 4294967295


То есть для каждого канала и фидбека может бы назначен соответствующий тип "word size".

Will be answered

Добрый день.

Владимир, мы добавили вашу информацию в план доработки драйверов Modbus. Сроки пока не определены, т. к. изменения нужно будет вносить во все драйверы Modbus в Иридиум (не только RTU). Мы сообщим по готовности.

Waiting for user's reply

Добрый день.

В релизе 1.3.12 будет выполняться постобработка получаемых значений для типа Holding Register. В драйвере может
использоваться знаковый и беззнаковый тип значения.

Уточните: нужна ли возможность отправлять в драйвер знаковый и беззнаковый типы? Т. е. требуется ли предобработка отправляемых значений или ограничиваемся изначальным вопросом?

Да, нужна. Обработка требуется при передаче в обе стороны

Will be answered

Добрый день.

Запланировали, сообщим в этом тикете по готовности.

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

Уточните, что имелось в виду про токены и функции.

Токены в сети не в сети устройство Modbus, это надо для передачи в верхний уровень.
Также другие токены от устройства, как у Вас сейчас реализовано на остальных драйверах: Status, Online и пр.
Функции используемые для обращения к регистрам. В вики у Вас написано, что сервер автоматически переключается с fc5 и fc6 на fc15 и fc16 в случае возврата ошибки 01, но если устройство не возвращает ошибку, то не происходит переключения. Для этого и надо сделать выбор нужного параметра. Так как у некоторых устройств будет один вариант команды, а у других другой, также может быть разный вариант команд для разных регистров. 

Токены Online и Status имеются. Если не работают какие-то конкретные, то уточните тип драйвера Modbus и названия токенов, мы проверим.

Вы имеете в виду Coil Write Function и Holding Write Function? Эти настройки имеются:

Они не работают у вас?

Токены имеются для сети Modbus RTU
нас интересуют токены для устройства конкретного.

Также и с Coil и Holding Write Function это для сети устройств, а должно быть по каждому устройству, а точнее по каждой переменной. Но это надо обсуждать.

Токены есть и для старого драйвера Modbus:

Они у вас не работают? Или имелся в виду другой тип Modbus?

Если нужны Coil и Holding Write Function для каждого устройства, то это нужно обсуждать (хотя бы в контексте, чтоб не сломались старые проекты после изменений имеющегося драйвера).

Answered

Добрый день.

В версии 1.3.12 может использоваться знаковый (от -32768 до 32767) и беззнаковый (от 0 до 65535) тип значения.

Также добавлена постобработка отрицательных значений для типа unsigned. При отправке отрицательных значений из Иридиум этому типу в лог  выводится ошибка.