Pull to refresh

Веселые уроки WinCC OA. Драйвер Modbus TCP

Level of difficultyEasy
Reading time5 min
Views3.8K

Продолжаем расширять мой базовый курс работы с системой WinCC OA. На этот раз речь пойдет о драйвере Modbus TCP. Очень хорошо эта задача уже описана у Вячеслава Лапшина на его сайте «Быстрые проекты». Тем не менее, ряд деталей у него в описании был опущен, так что создам свою версию гайда. Это уже вторая версия документа, в первой были допущены досадные оплошности.

В качестве сервера (подчиненного устройства) протокола Modbus у меня выступает свободнопрограммируемый ПЛК.

Я традиционно работаю в англоязычной среде, не переключаясь на русский.

В случае неясностей рекомендую обратиться к «номерным» частям базового курса.

В первую очередь создаем пустой проект с «классическими» настройками безопасности и выбранным архивированием NextGen. Все шаги создания проекта не описываю, это уже очевидные вещи. Рутовый пароль для учебного проекта не задаю.

Запускаем созданный проект и переходим в консоль. Добавляем драйвер Modbus (именно драйвер модбаса, а не сервер модбаса!). При добавлении опцией «-num 10» задаем ему номер 10. Номер драйвера может быть любым, единственное условие - все драйверы в системе, вне зависимости от типа, должны иметь уникальный номер.

Убеждаемся, что драйвер запустился, а он запустился, так как его статус в консоли = 2, а цвет статуса - зеленый.

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

WARNING, 54, Unexpected state, Cannot get DPID for _Driver10.AL.AClasses:_original.._value

WARNING, 54, Unexpected state, Cannot get DPID for _Driver10.AL.AckDps:_original.._value

WARNING, 54, Unexpected state, Cannot get DPID for _Driver10.AL.AckData:_original.._value

В первую очередь обращаем внимание на ошибку вида «не найден идентификатор точки данных» и имя точки _Driver10. Связано это с тем, что все настройки обмена данными хранятся во внутренних (системных) точках данных, коих в прикладном проекте не счесть. В любой системе количество предопределенных точек данных ограничено, как правило, тремя точками. А мы только что потребовали обращаться к несуществующей точке для десятого драйвера. Посмотрим в модуле Para:

WinCC OA Fun. Драйвер Modbus TCP, изображение №6

Так и есть, заданы точки данных для драйверов 1..3, но никак не 10. Добавляем две точки _Driver10 и _Driver10_2. Подчеркивание в имени точки данных является своего рода признаком «невидимости» точки данных, как обычная точке в начале имени файл юникс-систем. Создается именно две точки - одна для активной системы, другая для резервированной, даже, если мы работаем без резервирования серверов, это признак хорошего тона. Получаем в итоге

WinCC OA Fun. Драйвер Modbus TCP, изображение №7

Получаем новые ошибки в журнале:

DP does not exist, _Stat_Configs_driver_10._address:_original.._value

DP does not exist, _Stat_Configs_driver_10._cmd_conv:_original.._value

DP does not exist, _Stat_Configs_driver_10._msg_conv:_original.._value

DP does not exist, _Stat_Configs_driver_10._smooth:_original.._value

Добавляем еще одну точку данных, уже другого типа и получаем.

WinCC OA Fun. Драйвер Modbus TCP, изображение №8

Более ошибок в журнале не появляется. Это относится к любому драйверу. Как правило созданы внутренние точки данных только для первых трех номеров драйвера, остальные необходимо создавать самостоятельно. Некоторые типы драйверов требуют и других новых точек данных.

Прошу обратить внимание, что добавление секции mod_XX в конфиг-файл проекта является теперь опциональным, а не обязательным.

Далее переходим в System Management и ищем настройки драйвера модбаса.

Нажимаем кнопку Create и добавляем в список Mod_Plc_10. Ошибочно можно предположить, что 10 - это номер драйвера. Нет, 10 - это просто 10. Это внутреннее «имя» соединения, не номер драйвера и не device ID устройства Modbus. В данном случае номер драйвера и "имя" соединения совпадают, но это необязательно.

Добавляем ip-адрес нашего сервера modbus TCP, ставим галочку Active. Вот так теперь выглядят настройки.

Напоминаю, что Unit Address в полноценной реализации протокола Modbus TCP используется только для гейтов TCP - RTU. Нормальные сервера Modbus TCP этот параметр игнорируют. Но встречаются и обратные случаи, и сервер, не являясь гейтом, все равно контролирует свой Unit ID. Поскольку в реализации протокола модбас каждый сходит с ума по-своему, заранее предугадать поведение подчиненного устройства затруднительно. В нашем же случае сервер Modbus TCP реализован правильно и Unit ID игнорирует. Если вы все делаете правильно, но соединения так и не происходит, то задавайте значение Unit address. Узнать его можно в подчиненном устройстве Modbus TCP.

Нажимаем кнопку Apply. Если вы ожидаете, что после нажатия состояние вместо Not Connected станет Connecting или Connected, то зря надеетесь. Состояние соединения изменится только после добавления первого конфига _address на какую-либо точку данных, для чего традиционно открываем модуль para. Я применяю предопределенный DPT ExampleDP_Int и создаю первую DP с названием MyInt.

Добавляем конфиг _address и начинаем его настройку

Работать будем с регистрами хранения. Самый первый регистр в моем ПЛК - это шестнадцатиразрядный знаковый Int, который инкрементируется на 1 каждую секунду в программе ПЛК. Соответственно, тип преобразования указываем = Int16. Не забываем добавить группу опроса.

В группе опроса не забывает активировать группу, а то обмен не заработает.

Напоследок делаем адрес активным (ставим галочку).

Переходим на конфиг _original.

Читаемое раз в секунду значение соответствует значению в ПЛК. Этот опыт удался. Кстати, после добавления первого сигнала в окне драйвера появляется надпись Connected.

Следующие два регистра в моем случае - это 32разрядный Int. Заведем еще одну точки данных с именем MyDInt в этом же типе и настроим ее.

Тип преобразования - уже Int32, это два регистра. Задаем смещение - 1 (нулевой регистр - это MyInt, первый и второй - MyDInt). Группа опроса остается той же. Переходим на конфиг original и наблюдаем недостоверные данные.

Значение сигнала тут то ли несколько миллионов, то ли несколько миллиардов, что радикально отличается от значения в ПЛК = 5440 (для этого DInt так же запрограммирован ежесекундный инкремент). Идем смотреть в настройки драйвера. Один регистр Modbus - это 16 бит, два байта. Два регистра - это 32 бита, 4 байта или двойное слово. А порядок байт в слове у нас заранее может быть и неизвестен. Смотрим на закладку продвинутых настроек и находим порядок регистров. Что выставлено по умолчанию - я не знаю. Но на всякий случай попробуем порядок Big endian, как у интелловских процов.

Не забываем нажимать Apply. После этого изменения значение MyDInt стало соответствовать значению в ПЛК. Разумеется, пока я пишу эту заметку, идет время, и сейчас значение сигнала уже не 5440,а немного больше.

На всякий случай смотрим MyInt, не сломалось ли там что-нибудь.

Не сломалось, что вполне ожидаемо. Следующим переметром давайте заведем переменную типа Real (так же, два регистра). На стороне контроллера это значение уже не задается принудительно, так что пропишем и чтение, и запись. Создаем и настраиваем точку данных типа ExampleDP_Float

Заданное на стороне ПЛК значение считалось

Добавим к этой DP конфиг _smooth в режиме сравнения старое/новое. В противном случае будет проблематично вбить новое значение в модуле Para, ибо оно будет перезатираться каждую секунду.

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

И напоследок решил проверить - можно ли задать DPE типа bool и читать его, как бит регистра хранения. Как оказалось, можно.

Пятый регистр- это слово MyWord в ПЛК. Указываю номер бита = 1 (нумерация в этом случае с единицы). Пробую читать/записывать значение, все получается.

Шестой регистр в ПЛК у меня представлен одним битом. Обращаю внимание, что конкретно в этом случае я должен выставить номер бита не 1, а 9, так как идет переворачивание байт в слове, и это никак не победить. Это связано в первую очередь с выравниванием информации в блоках данных Симатиков по слову в случае стандартного доступа.

Tags:
Hubs:
Total votes 3: ↑3 and ↓0+3
Comments0

Articles