September 27, 2017

Расширение UNION

Давно хотел попинать полумертвое существо UNION, которому вообще сложно найти красивое и практичное применение, но тут в тему появилась статья Стефана Хеннекена о возможности расширять UNION через наследование в TwinCAT 3.

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

Можно пытаться убедить не применять UNION, что он устарел и больше не нужен, но мы по прежнему одной ногой в эмбедед, где все-таки приходится иногда экономить память (первое применение), использовать трюки с преобразованием типов данных (второе применение) и где только-только появилось ООП (привет CoDeSys 3 и TwinCAT 3).


Расчленение данных


TYPE ST_Word:
STRUCT
    Lo : BYTE;    (* младший байт *)
    Hi : BYTE;    (* старший байт *)
END_STRUCT
END_TYPE

TYPE U_Word:
UNION
    Bytes : ST_Word;
    Value : WORD;
END_UNION
END_TYPE

Объявив переменную как UNION, мы получили структуру, внутри которой два элемента (Bytes и Value) хранятся в одном адресном пространстве. Записывая, что-либо в переменную Value мы также записываем эти данные и в Bytes. Верно и обратное — записывая данные в поля структуры Bytes : ST_WORD мы одновременно заполняем данными переменную Value.

Это очень похоже на синонимы (ALIAS), но с разными типами данных, и на самом деле никакой одновременности записи в разные переменные здесь нет — просто данные лежат в одном месте и разные пересекающиеся части этого места называются по разному. К сожалению, построчная запись в объявлении UNION часто сбивает с толку разработчиков, и они забывают, что данные переменных хранятся в ячейках памяти, и контроллер работает с ячейками памяти, а не с какими-то там именами человеческих переменных.

PROGRAM MAIN
VAR
    yourWord : U_Word;
    hi       : BYTE;
    lo       : BYTE;
END_VAR

yourWord.Value := 16#AABB;
hi := yourWord.Bytes.Hi;    // == 16#AA
lo := yourWord.Bytes.Lo;    // == 16#BB

Записываем в поле Value 16-разрядное число, которое накладыватся на 16-разрядную структуру Bytes : ST_WORD, содержащую два байтовых поля. Таким образом записанное значение разбивается на две однобайтных части: старший байт и младший байт. И никаких битовых операций для доступа к байтам WORD.

В TwinCAT 3 появился механизм наследования, который мы можем применить к UNION:

TYPE U_Word EXTENDS ST_Word:
UNION
    Value : WORD;
END_UNION
END_TYPE

Код становится лаконичнее, так как отпала необходимость в указании промежуточной структуры Bytes:

PROGRAM MAIN

yourWord.Value := 16#AABB;
hi := yourWord.Hi;    // == 16#AA
lo := yourWord.Lo;    // == 16#BB


Одно поле

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



Адреса элементов Value, Lo и адрес в pYourWord (это указатель на UNION) совпадают, так как они расположены в начале области памяти выделенной под UNION. Указатель конечно же не расположен, а ссылается, но нас интересуют адреса, а не механизм работы. Теперь сравните адреса ячеек Lo и Hi (pYourWord_Lo и pYourWord_Hi, соответственно). Они различаются ровно на один байт, так как каждая из них занимает ровно один байт, а расположены они последовательно друг за другом.

Если этого недостаточно, то вот вам код:

PROGRAM MAIN
VAR
    oneWord         : WORD;
    yourWord        : U_WORD;
    
    pYourWord       : ULINT;
    pYourWord_Value : PVOID;
    pYourWord_Lo    : LWORD;
    pYourWord_Hi    : LWORD;

    wordLo          : BYTE;
    wordHi          : BYTE;
END_VAR

pYourWord       := ADR(yourWord);
pYourWord_Value := ADR(yourWord.Value);
pYourWord_Lo    := ADR(yourWord.Lo);
pYourWord_Hi    := ADR(yourWord.Hi);

oneWord         := yourWord.Value;

MEMCPY(
    ADR(wordLo), (* <-- *) pYourWord_Lo,
    SIZEOF(wordLo));

MEMCPY(
    ADR(wordHi), (* <-- *) pYourWord_Hi,
    SIZEOF(wordHi));

Вместо типов LWORD и ULINT здесь лучше использовать POINTER TO U_WORD и POINTER TO BYTE, но мне хотелось убедиться, что указатели теперь 64-х разрядные и что для хранения адресов подходят 64-х разрядные типы: LWORD, ULINT, PVOID. Последний, кстати, как и обещали в TwinCAT 3 стал 64-х разрядным.
PVOID — это синоним для UDINT в TwinCAT 2 (32-х разрядные адреса) или для ULINT в TwinCAT 3 (64-х разрядные адреса). Всегда используйте его как универсальное хранилище адреса, так как независимо от версии TwinCAT, вы всегда получите переменную с правильным типом данных. Вот еще один пример правильного использования ALIAS.
Заодно посмотрите на смертельно опасную функцию MEMCPY, позволяющую писать куда угодно в память.


Другие применения UNION


Экономим память — храним данные разных типов в одном месте. Главное, точно знать какие данные сохранены в текущий момент времени и вовремя их перезагружать.


Реинтерпретация типа данных


Мы хотим считать, что вот тот тип данных сейчас не REAL, а DWORD. Например, чтобы без лишних преобразований пересылать его через Modbus:

TYPE U_Real :
UNION
    Re : REAL;
    Dw : DWORD;
END_UNION
END_TYPE

Для работы используем поле Re, а для отправки данных Dw. И никакого преобразования данных, все происходит автоматически.


Variant


Или когда мы не знаем какой тип данных будет использован во время работы программы. Этот же прием можно использовать для создания псевдо-полиморфизма в TwinCAT 2.

Сначала готовим болванку для хранения данных разного типа:

TYPE U_VarObject :
UNION
    AsInteger  : INT;
    AsFloat    : REAL;
    AsDouble   : LREAL;
    LikeString : STRING;
END_UNION
END_TYPE

Затем описываем (перечисляем) доступные типы данных:

TYPE E_VarType :
(
    Integer,
    Float,
    Double,
    String255
);
END_TYPE

Упаковываем все это в структуру:

TYPE ST_Variant :
STRUCT
    TypeIs : E_VarType;
    Value  : U_VarObject;
END_STRUCT
END_TYPE


Работает как-то так:

PROGRAM MAIN
VAR
    xVar    : ST_Variant;

    Counter : INT;
    Text    : STRING;
END_VAR

CASE xVar.TypeIs OF
    E_VarType.Integer:
        Counter := xVar.Value.AsInteger;

    E_VarType.Float:
        ;

    E_VarType.Double:
        ;

    E_VarType.String255:
        Text := xVar.Value.LikeString;
END_CASE


Синонимы


Очень похоже на вычленение данных, но будем использовать по принципу ALIAS:

TYPE ST_Vector3R:
STRUCT
    X : REAL; 
    Y : REAL; 
    Z : REAL; 
END_STRUCT
END_TYPE

TYPE U_Vector3R EXTENDS ST_Vector3R:
UNION
    E : ARRAY [1..3] OF REAL;
END_UNION
END_TYPE


Теперь координаты вектора доступны для нас как по именам, так и по индексам:

PROGRAM MAIN
VAR
    Vec : U_Vector3R;
    i   : UINT;
END_VAR

FOR i := 1 TO 3 DO
    Vec[i] := i * 100;
END_FOR

Vec.Y := 0.0;

July 7, 2017

Вебинар. Введение в K-Bus и терминалы серии KL3xxx

Тема анонса была запутанной и заранее было непонятно — о чем же все-таки нам расскажут. В итоге все это вылилось в краткое описание модулей K-bus и почему они больше не нужны. Есть вероятность, что это было краткое введение и когда-нибудь будет более подробное, так как тема интересна хотя бы тем, что еще много живого оборудования из предыдущего поколения.

Вещал Мартин Подрушек (Martin Podrouschek): Beckhoff K-Bus and analog inputs. Introduction of KL3xxx terminals.

В 70-х годах прошлого века (ого!) была принята трехступенчатая система: ПЛК ↔ много-много-модулей-ввода-вывода ↔ сенсоры/актуаторы (исполнительные механизмы). В 95-м году Бекхофф предложил собрать все это в одном устройстве "интеллектуальная система терминалов шины" (intelligent bus terminal system) и в итоге получился Profibus bus coupler BK3000:

Система предусматривает как минимум две линии питания: одна линия питает логику коплера и логику терминалов (модулей расширения), а вторая линия предназначена для питания входов/выходов терминалов. Выхода  в принципе могут потреблять значительный ток или вообще сгореть, но логика питается по другой линии, поэтому она сможет пожаловаться коплеру о неприятностях в силовой части. Если питания не хватает или нужно развязать часть модулей по питанию — можно добавить в линейку специальный модуль подпитки и потенциальной развязки.

Кроме коплера как обычного транслятора пакетов данных (коплеры BKxxxx) были разработаны программируемые коплеры с мозгами — серия BCxxxx.


Внутренности и способности


Условно можно разделить систему на два уровня передачи данных: уровень полевой шины до коплера и уровень периферийных устройств — внутренняя шина (K-bus), то есть внутренняя шина между коплером и терминалами. Из-за такой сепарации возникает проблема диагностики, так как отсутствует непосредственная прямая связь между внешней полевой шиной и терминалами.

Внутри терминала содержится набор регистров, содержащих настройки модуля и, соответственно, позволяющие менять поведение модуля. Часть регистров хранится в ОЗУ, часть в ПЗУ, а часть в EEPROM. В результате, часть регистров жестко прописаны производителем и не меняются, какие-то можно изменять, а какие-то сбрасываются и восстанавливаются при каждом новом включении. Некоторые вообще защищены паролем.

Система поддерживает максимум 256 дискретных устройств ввода/вывода или 128 аналоговых. Так как после 64 терминалов обязательно необходим модуль подпитки шины, то в итоге максимально возможное число модулей сокращается до 250.

Каждое устройство может поддерживать до четырех каналов ввода/вывода. Каждый канал — это всего-лишь 3 байта данных. Если нужно больше каналов, то придется мультиплексировать, дробить время обработки, сокращая другие каналы. Хорошая новость — все это решается на уровне коплера. Также ограничено суммарное количество регистров на канал — 64 регистра. Если нужно больше, то вводят вторую страницу регистров.

Типичное время цикла коплера 1..2 миллисекунды.

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

Внутри память модуля разбита на две области: область входов и область выходов. Каждая из этих областей в свою очередь разбита на область байтовой памяти (регистры данных для аналоговых входов/выходов) и область битовой памяти (дискретные входа/выхода).


Доступ к регистрам


Способ первый: через специальную платную программу KS2000 и специальный кабель Serial/USB KS2000-Z2-USB.

Изображение: Beckhoff Automation

Способ второй: программный, через ПЛК Бекхофф по шине с помощью функциональных блоков библиотеки Tc2_Coupler.lib.

Способ третий: инженерный в режиме FreeRun или Run доступ к регистрам через TwinCAT System Manager: тыкаем правой кнопкой в коплер в дереве конфигурации и выбираем Register Access...

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


Сравнение и выводы


 K-Bus (1995 год прошлого века)EtherCAT, E-Bus (2003 год настоящего века)
Идентификация устройства нет производитель и код продукта
Стоимость сложный и дорогой простой и дешевый
Передача данных меньше 10 мегабит быстрая, до 10 гигабит
Синхронизация нет жесткая, распределенные часы с погрешностью меньше 100 наносекунд
Операционный образ данных 4x12 байт теоретически можно до 65 килобайт, практически используется 8 килобайт
Диагностика двух-шаговая непосредственная
Доступ опосредованный через регистры непосредственный CAN-через-ADS (CoE)

Вывод я вам лучше нарисую:

July 4, 2017

Вебинар. Что нового в сборке №4022

Некоторые новинки сборки TwinCAT №4022 я перечислял в стратегиях развития, но это было не точно и на уровне слухов. 27 июня прошел официальный вебинар TwinCAT 3.1 | New features in Build 4022, на котором Йозеф Папенфот (Dr. Josef Papenfort) подробно рассказал о новых и значимых функциях введенных в систему.

Все новые фишки более-менее перечислены на официальном сайте, но это скорее официальный бюллетень, нам же будут интересны некоторые подробности. Для начала, скачиваем с официального сайта Бекхофф новую сборку 3.1.4022.0: TwinCAT 3.1 – eXtended Automation Engineering (XAE). Один год — один новый релиз, но в этом билде только небольшие исправления и обновления.

Доктор официально подтвердил, что начиная со сборки 4020.x начата поддержка Windows 10 Redstone 4020.x. Поддержка Redstone 2 ожидается в середине 2017 года. Печальная же новость, что начиная с билда 4022 заканчивается поддержка всеми любимой Windows XP и WES 2009 (Windows Embedded Standart), то есть 4022 на них работать уже не будет.


Архив проектов


Что было удобно в TwinCAT 2, так это два файла на целый проект: программа в .pro-файле и конфигурация в .tsm. В то же время это было не удобно для систем контроля версий, так как файлы были бинарные — зато почтой отправлять удобно. Чтобы как-то скомпенсировать эти проблемы, был введен новый формат решения (solution, солюшен) — архив .tnzip. Внутри — это обычный архив ZIP, только расширение подлиннее.

Новый формат позволяет сжимать один или несколько проектов TwinCAT 3 в единственный файл архива. И сразу же отправить по почте: для этого есть специальный пункт меню. Впоследствии такой архив можно открыть как обычное решение (solution), то есть вот прямо сразу из архива, ничего не распаковывая.


Я поархивировал немного и выяснил, что в архиве хранятся только проекты TwinCAT. Все посторонние проекты, относительно TwinCAT (например, проект на C#), система игнорирует и в архив не включает. Зато архивы реально сжатые, сравните на картинке ниже размер "до" (Size) и размер "в" (Packe...)


Полезные мелочи


Постепенно улучшается редактор кода: добавлено раздельное масштабирование шрифтов в редакторе кода ST и окне объявления переменных. Для улучшения восприятия, появились специальные атрибуты создающие схлопывающиеся регионы — это кусок кода между специальными метками {region}

{region 'название для региона'}

... кусок кода

{endregion}

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

В CFC-рисовалке блоков появилось автодополнение кода (IntelliSense), а в менеджере библиотек — специальная иконка, подсказывающая когда плейсхолдер куда-то там переместился и теперь указывает на другую версию библиотеки.


Переменные ввода-вывода


Переменные ввода типа AT %I* (location variables) теперь недоступны для изменения из кода: bInputVar := NOT bInputVar — запрещено на уровне компилятора и при сборке проекта приведет к ошибке компиляции. Зато теперь, начиная с билда 4022, эти переменные могут получать начальное значение: bInputVar AT %I* : INT := 123;

Из-за таких вот нововведений, функция __ISVALIDREF теперь работает только со ссылками. Про ссылки и указатели уже было, но там не было про эту функцию, которая подсказывает существует ссылка или нет:

<результат типа BOOL> := __ISVALIDREF(переменная типа REFERENCE TO <тип данных>);

TRUE — ссылка рабочая, FALSE — ссылка нулевая, подробнее читайте в справочной системе.

Соответственно REFERENCE TO на переменные AT %I* теперь тоже запрещены, так как изменение этих переменных запрещено и такая попытка будет пресекаться ошибкой компиляции.


ADS через MQTT


Поддержка реализована как .dll модуль для Mosquitto Broker. Уже есть как 32-х разрядная так и 64-разрядная версии. Модуль поставляется бесплатно, вместе со стандартным установщиком и лежит в каталоге AdsApi:


Проект-одиночка


Начиная с этого момента ПЛК-программа и конфигурация TwinCAT — могут быть двумя разными, раздельными проектами: один проект будет содержать только программный проект (программу технологического процесса, TwinCAT PLC Project), а второй, будет содержать только конфигурацию системы (TwinCAT XAE Project).

Не обязательно так делать всегда, просто учтите, что они теперь так могут, и в сложных проектах это будет просто спасение утопающему в строках кода, но вы все еще можете засунуть в конфигурацию ПЛК-программу. Просто теперь есть выбор:


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

При таком подходе, изменяя ПЛК-проект в одном месте, мы будем изменять его во всех конфигурациях одновременно. Главной при этом не забыть пересобрать ПЛК-проект: Build → Build Solution (F7), и активировать конфигурацию в TwinCAT-XAE-проекте: Activate Configuration.

Такой принцип чем-то схож с использованием библиотек, но только пишем мы не библиотеку (Empty PLC Project), а обычную программу (Standart PLC Project).



Символьный маппинг


Теперь можно обновлять ПЛК-проект независимо от конфигурации, а новый маппинг переменных несовместим со старым. Переменные привязываются друг к другу с помощью символьной информации (грубо говоря — по именам). Прошивка контроллера должна быть новой и поддерживать.

Список системных типов данных переехал из закладок SYSTEM напрямую в дерево проекта и получил отдельную ветку с неожиданным названием Type System. Теперь туда с помощью заклинания Add New Item... и такого-то .tmc файла можно добавить распределенные типы данных (Shared Types), которые затем можно оттранслировать через EAP по TCP/IP сетям. Или через системы контроля версий, или вообще по любым каналам. Электронная почта все еще работает.


TwinSAFE


На диаграммах отображается состояние TwinSAFE-группы: в случае ошибки вы увидите толстую красную рамку, и вообще появились другие цвета, отражающие состояние входов/выходов и другие состояния. Плюс мелочи в редактировании схем безопасности: копи-паста функциональных блоков или псевдонимов (Alias Devices), разбивка на подкаталоги для псевдонимов устройств.


Книга жалоб и предложений


В XAE встроили специальный пункт меню для отправки письма сразу в тех. поддержку Бекхофф. При нажатии, появляется готовая форма, которую нужно заполнить. Причем ведет форма себя очень странно, так как доступна только из TwinCAT Measurement Project (это который про рисование графиков) и кликнуть нужно обязательно по ветке проекта Scope XY Project.



Монитор ADS


Бесплатный, но качается и устанавливается отдельно с FTP-сайта Бекхофф: TF6010-ADS-Monitor. После установки будет лежать здесь: C:\TwinCAT\Functions\TF6010-ADS-Monitor\Viewer\TcAmsAdsViewer.exe

С помощью монитора можно смотреть на пакеты ADS, иногда отправляя свои собственные. Аналогичное можно получить из WireShark, только здесь фильтры настраивать не нужно.



Установка


В остальном билд №4022 установился без проблем на Windows 10 Home. Если собираетесь запускать контроллер на локальной машине разработчика (ноутбук на котором программируете), то после установки запустите от имени "Администратора" батник: C:\TwinCAT\3.1\System\win8settick.bat и перезагрузите компьютер.

June 5, 2017

2017. Стратегия развития

Ключевая фишка Бекхоффа — это использование обычного ПК в качестве промышленного контроллера. Плюс собственное производство, тестирование, то есть полный конвейер. Давайте для разогрева посмотрим, как они двигались по этому пути.
  • 1982. P1000 — одноплатный контроллер управления движением.
  • 1986. PC Control — первый основанный на ПК контроллер ЧПУ станка.
  • 1988. S1000 — программный ПЛК/NC персональный компьютер (операционная система DOS).
  • 1989. Lightbus — высокоскоростная шина на оптоволокне.
  • 1990. All-in-one — персональный ПК типа "всё-в-одном" на материнской плате.
  • 1995. Bus Terminal — модульная архитектура шины на основе модулей расширения — терминалов.
  • 1996. TwinCAT — программный комплекс под Windows с функцией ПЛК и управлением движением.
  • 1998. IPC Control Panel — панельные компьютеры с графическим дисплеем для удаленной установки и установки по месту.
  • 1999. Fieldbus Box — защищенные IP 67 модули ввода/вывода.
  • 2002. CX1000 — модульные встраиваемые ПК для монтажа на дин-рейку.
  • 2003. EtherCAT — промышленная шина реального времени на базе Ethernet.
  • 2005. TwinSAFE — компактные решения для промышленной безопасности труда.
  • 2005. AX5000 — сервоусилители на базе EtherCAT.
  • 2007. Industrial Motherboards — собственное производство в Германии.
  • 2008. XFC — сверхскоростная технология обработки ввода/вывода (eXtreme Fast Control).
  • 2009. HD Bus Terminals — компактные многоканальные терминалы ввода/вывода (16-каналов, ширина 12 мм).
  • 2010. TwinCAT 3 — продвинутая технология автоматизации.
  • 2011. AM8000 — синхронные сервомоторы с однокабельной технологией (One Cable Technology).
  • 2012. Multi-touch — второе поколение панелей управления и панельных ПК с поддержкой сенсорного мультитач дисплея.
  • 2012. XTS — продвинутая технология транспортировки (eXtended Transport System).
  • 2014. Multicore — многоядерные системы управления и промышленные серверы для ускорения промышленных вычислительных возможностей.
  • 2014. AX8000 — много-осевые сервоусилители.
  • 2014. EtherCAT Plug-in Modules — подключаемые модули или терминалы шины для монтажа на печатные платы.
  • 2015. EtherCAT P — однокабельная технология для автоматизации в целом.
  • 2015. TwinCAT HMI — независимые от платформы пользовательские интерфейсы на основе веб-браузера и HTML5.
  • 2016. EtherCAT ELM — измерительные модули интегрируемые в систему высокоточных измерительных технологий.


2017.


Теперь ближе к нашим дням, а точнее к тому, что будет завтра.

Изображение: Beckhoff Automation
В этом году на выставке Hannover Messe '2017 Бекхофф в первую очередь пропагандировал:
  • Мультитач графические панели с новым красивым дизайном.
  • Многоядерные контроллеры на дин-рейку, такие как CX2072 (до 12 ядер).
  • "Микрокирпичи" C6015, сертифицированные Microsoft для Microsoft Azure.
  • XTS — продвинутая технология транспортировки (eXtended Transport System).
  • Анализ облачных данных в TwinCAT Analytics.
  • IoT, Индустрия 4.0, облачные технологии и другие современные трендовые слова.

Буквально на днях объявили о грядущем вебинаре на тему новой сборки TwinCAT 3.1.4022. Вероятно там будет рассказано что-то еще.


TwinCAT 3.1...


Версии TwinCAT с нечетным номером 4017–4019 — разрабатываются исключительно для внутреннего тестирования в организации. Для интеграторов и независимых разработчиков — только четные. Поэтому ближайшая будет — 4022, но без нововведений. Устранят ошибки и обновят лицензионные политики.
TwinCAT 2 все еще будет обновляться, но без новинок, только устранение багов.
Начиная с TwinCAT 3.1.4022 прекращается поддержка Windows XP и WES2009. Тем более, что Windows 10 Redstone уже полноценно поддерживается начиная с 4020.x, а с середины 2017 года появится поддержка Redstone 2.

Улучшится поддержка лицензионных USB-ключей, теперь одновременно можно будет использовать несколько TC3 USB-ключей в одной системе. TwinCAT будет распознавать их автоматически, больше не потребуется переконфигурировать систему при каждом изменении лицензионной политики.

Также можно будет условно понижать уровень лицензии: на платформах с более низким уровнем производительности (TC3 performance class) можно использовать лицензии от платформ с более высоким уровнем производительности.


ADS через MQTT


Новый способ отправки пакетов ADS — теперь через MQTT (ADS-over-MQTT). Преимущества:
  • Использует только исходящие подключения.
  • Не требует настройки фаервола, либо использует настройки по умолчанию, что упрощает работу для системных администраторов (или, как обычно, вообще без них).
  • Хорошо чувствует себя находясь за NAT.
  • Можно использовать в недоверенных сетях.
  • При участии шифрованных каналов TLS-PSK.
  • Нет жестко заданного подключения сокет-сокет.
  • Реализован как надстройка для Mosquitto Broker.

В итоге мы получаем полноценную виртуальную AMS-сеть (Virtual AMS Networks), которая умеет делать ADS-роутинг, а это дает такие стандартные возможности, как поиск TwinCAT устройств (в том числе и широковещательный) или обычная передача данных через ADS. Если взять текущие и более старые приложения, использующие протокол ADS, то они ничего не заметят, для них все будет выглядеть по старому. Процесс трансляции данных берет на себя ADS-роутер и скрывает от приложений. Так что данные теперь могут спокойно транслироваться через MQTT, что в новых приложениях, что в старых.


Независимые ПЛК программы


Появится новый вид TwinCAT проектов — независимый ПЛК проект (Standalone PLC). Проекты такого типа создаются и программируется независимо от конфигурации, то есть они могут существовать как отдельный проект в солюшене XAE. Впоследствии можно создавать множество экземпляров данного проекта, просто прикрепляя независимый проект к конфигурации через файл TMC, по аналогии с файлами TPY в TwinCAT 2.


Symbolic Mapping


Можно будет линковать не только пары адрес ↔ адрес, но и имя_переменной ↔ имя_переменной. Имя переменной — это в терминологии TwinCAT "символ" (symbol), что чуть шире, но не принципиально.


Распределенные типы данных


В оригинале — Shared Datatypes. Можно импортировать и экспортировать типы данных туда-сюда между ST и C++, ST и ST, а можно отправить по почте в виде TMC-файла или выложить в TFS (Team Foundation System), или воспользоваться любым другим способом передачи файлов.

TMC-файлы становятся все интереснее, так как все меньше ограничивают нас языком программирования.


Power Monitoring


Новая ПЛК библиотека для анализа сырых данных мониторинга электричества с модулей EL3773 и EL3783:
  • RMS, Peak, среднее значение для тока, напряжения, мощности.
  • Анализ гармоник и частот.
  • 1-фазные и 3-фазные.

Будет доступна в конце 2017 года


Библиотека и дизайнер фильтров


Новая библиотека для разработки фильтров будет интегрироваться в TwinCAT Measurement Project и позволит практически рисовать собственные цифровые фильтры. Предназначается в первую очередь для совместной работы с модулями ELM и TC3 Filter Library.

Кстати, Filter Library будет полностью ООП. Все функциональные блоки будут использовать ряд методов, такие как, например: Call, Configure, Reset (вызвать, настроить, сбросить). Функциональные блоки смогут принимать параметры и коэффициенты, предварительно нарисованные в Filter Designer. Очень похоже на принцип работы с кулачковыми механизмами и таблицами движения NC (Tables, Motion Diagram). Кроме них будут и просто готовые к использование функции со встроенными фильтрами.

Этих библиотек уже не будет в TwinCAT 2!


Многоклеточные


С середины 2017-го выйдут в серию многоядерные монстры на дин-рейку:
  • 4 ядра — CX2042, процессор Xeon D-1529 @1.3 ГГц, кэш 6Mb LL-Cache, оперативная память 8Гб.
  • 8 ядер — CX2062, процессор Xeon D-1539 @1.6 ГГц, кэш 12Мб, память 16Гб.
  • 12 ядер — CX2072, процессор Xeon D-1559 @1.5 ГГц, кэш 18Мб, память 32Гб.

В каждом будет выделенная графическая подсистема AMD с 2Гб памяти GDDR5. Оперативную память типа DDR4 можно варьировать от 8 до 32Гб. Из интерфейсов подарят: 4xUSB3, 2xEthernet Gbit LAN, 1xDVI-I, один интерфейс опционален, в том числе появится Display Port. Операционная система Windows 10 IoT Enterprise 2016 LTSB 64-разрядная. TwinCAT, конечно же, третий.

Монстры будут совместим с модулями серии CX2000. Ну, и вентилятор с контролем температуры, как в CX2040.


Новые интересные блоги


Стефан Хеннекен (Stefan Henneken) ведущий программист из Германия ведет кулинарный блог, посвященный рецептам на C# и ST в TwinCAT 3: ООП, паттерны, шаблоны программирования и другие современные вещи, но пока еще без функциональщины и других лямбда функций. Языки блога английский и немецкий. Гугл транслейт в помощь.

JoVAn — проектировщик из Португалии ведет блог Um PLC sem WatchDog (ПЛК без цензуры?) со сборной солянкой из руководств, туториалов и видео- уроков под разных производителей и сферы автоматизации.


Ранее в сериале:

May 28, 2017

Иногда RETAIN возвращаются

Переменные RETAIN снова с нами: они стали удобными, полезными и простыми как барабан. Если вы не знали или забыли  ранее они были объявлены как устаревшие и зарезервированные, а нам предлагалось использовать PERSISTENT:

Retain Variables: RETAIN is a reserved keyword in IEC61131-3. In TwinCAT 3 RETAIN is reserved. If RETAIN is used a compile error will be generated automatically. Use PERSISTENT instead.


Синоним NOVRAM


Интересным нововведением в TwinCAT 3.1.4020 стало автоматическое сохранение переменных, объявленных как VAR RETAIN, в области NOVRAM. Если в TwinCAT 2 необходимо вручную линковать ПЛК переменную с аналогичной в NOVRAM ветке, либо вызывать специализирванный ФБ, то теперь достаточно указать системе на наличие таких переменных вообще, а все остальное TwinCAT сделает сам: отследит изменения, сохранит и восстановит данные в случае провала электропитания.

NOVRAM состоит из двух областей памяти, одна  оперативная и энергоЗАвисимая, другая область  длительного хранения и энергоНЕзависимая. Оперативная часть питается от источника питания ПЛК. Когда электричество пропадает, энергия, накопленная в ионисторе, дает дополнительные несколько секунд работоспособности для сброса данных из оперативной части NOVRAM в ее энергонезависимую флэш часть. Таким образом экономится ресурс флэш памяти NOVRAM (постоянное обновление и перезапись данных происходит только в оперативной части). При восстановлении электропитания, данные переписываются из постоянной половины в оперативную.

Минимальный размер NOVRAM составляет 128 килобайт, но для энергонезависимого хранения будет доступно только 64Кб (65504 байта): вторая половина оперативная и мы имеем доступ только к ней (половине всего объема NOVRAM). В то же время NOVRAM может быть опционально расширен до 512 килобайт (будет доступно для хранения 256Кб), но обойдется это в чуть меньше, чем 499 евро, поэтому для таких объемов можно использовать PERSISTENT. Подробнее об этом можно прочитать в статье с кратким названием NOVRAM.


Retain Handler


Для проверки я использовал следующую конфигурацию:
  • ПЛК: CX2030 XAR TwinCAT 3.1.4020.32
  • Среда разработки: XAE TwinCAT 3.1.4020.32
Главный акцент на версию TwinCAT — 3.1.4020.32. Конкретно в этой версии-сборке у меня все заработало, а раньше не

В общем случае последовательность действий такая:
  1. При сканировании конфигурации оставьте "галку" для включения устройства NOV-DP-RAM в конфигурацию.
  2. После сканирования добавьте к этому устройству — Beckhoff Automation GmbH → Retain Handler.


  3. Необходимые для автоматического сохранения переменные объявляейте как VAR RETAIN.
  4. Соберите проект (Build Solution).
  5. Предположим, что проект называется Untitled1. Ткните мышой в Untitled1 Instance (смотрите на картинку с деревом проекта выше).
  6. В закладке Data Area в столбце Retain Hdl для PlcTask Retains выберите из выпадающего списка созданный на шаге (2) соответствующий Retain Handler.

Все переменные ПЛК-проекта, обозначенные как RETAIN, теперь будут контролироваться TwinCAT. Причем не важно сколько у вас программ и подпрограмм — все переменные будут сохраняться и восстанавливаться с помощью одной области NOVRAM.

При удалении RETAIN переменных из программы, необходимо очистить и пересобрать проект, а затем вручную обновить NOVRAM. Для этого кликните правой кнопкой мыши по Retain Handler в разделе конфигурации NOV-DP-RAM, затем пункт Optimize Retain Variables. Это официальная рекомендация справочной системы. Неофициальная — удалите Retain Handler, очистите и пересоберите проект, а затем повторите все шаги начиная со второго (2).


Многозадачность


Как будет вести себя область памяти NOVRAM, если в проекте несколько "рантаймов", то есть несколько, параллельно работающих задач? Начнем с того, что для каждой задачи необходимо персонально назначить область памяти Retain Hdl. Этот шаг ничем не отличается от описанного выше.
В общем случае, TwinCAT различает задачи по номеру их ADS-порта: 851, 852, ... И даже если в разных задачах будут совпадать имена переменных, функциональных блоков или программ, номер порта задачи по прежнему будет отличать переменную от ее тезки в другой задаче. 
Несмотря на то, что область памяти NOVRAM одна на все задачи, XAE спокойно и равномерно распределяет все переменные RETAIN всех задач по единственной области памяти NOVRAM. При условии, что этой памяти достаточно.

Посмотрите на адресацию (Address) и номер порта в [квадратных скобках] поля Name:



Быстродействие


На копирование данных все-равно будет затрачиваться какое-то время. В статье Note the write speed of the Retain Handler утверждается, что на 512Кб (a это максимум для NOVRAM, на данный момент) потребуется около 3,6 миллисекунды (3600 мкс). На 8Кб около 0,4 миллисекунды (400 мкс). При стандартном цикле ПЛК задачи в 10 миллисекунд — это очень даже неплохие показатели, но я все-равно проверил.

Для начала, у меня под рукой был только "толстый" ПЛК CX2030 с быстрым процессором и "широкой" шиной. Это плохо, так как он всегда быстрый, но пока только так. На контроллере установлен минимальный NOVRAM объемом 128Кб, поэтому XAE при сборке ограничила меня 65504 байтами.

Первое замечание: очень долгая сборка проекта для массива из 64000 ячеек BYTE и быстрая сборка для 8000 ячеек LREAL. Возможно, на продолжительность сборки влияет количество переменных, так как объем данных у меня не менялся. Вероятно XAE пытается вставить в дерево проекта каждую ячейку массива по отдельности, что дает неслабую нагрузку на процессор-память.

В итоге, как и ожидалось, получилось очень быстро и практически никакой нагрузки на процессор:
  • Ожидание — 213,7 микросекунд на цикл. Заполнение массива varPack и ожидание команды start (читайте Приложение ниже).
  • Сохранение — 245,2 микросекунд на 64Кб данных. Заполнение массива retPack и сохранения в NOVRAM.

Какая-то нагрузка видна, но она практически не заметна — нужен ПЛК помедленнее. Пока же буду считать, что RETAIN вполне себе полезная вещь, хотя бы для критических настроек.


Приложение


Для черновых испытаний использовались два массива: один (varPack) я изменял постоянно, но не сохранял в NOVRAM, другой же (retPack) изменялся по требованию (start) и, следовательно, в этом же цикле сохранялся системой в NOVRAM. Попеременное использование двух массивов позволяет исключить из тестирования производительности затраты на заполнение массива данными (занимает порядка 180 микросекунд).

PROGRAM MAIN
VAR
    counter  : UINT;
    i        : UINT;
    start    : BOOL;
    Max100ns : UDINT;
    varPack  : ARRAY [1..HOWMANYRETS] OF LREAL;
END_VAR
VAR RETAIN
    retPack  : ARRAY [1..HOWMANYRETS] OF LREAL;
END_VAR
VAR CONSTANT
    HOWMANYRETS : UINT := 8000;
END_VAR

[...]

counter := counter + 1;

Max100ns := MAX(_TaskInfo[1].LastExecTime, Max100ns);

IF start THEN
    start := FALSE;
    
    FOR i := 1 TO HOWMANYRETS DO
        retPack[i] := counter + i;
    END_FOR
ELSE
    FOR i := 1 TO HOWMANYRETS DO
        varPack[i] := counter + i;
    END_FOR
END_IF


Длительность работы цикла берется из глобальной системной структуры _TaskInfo[1].LastExecTime в 100 наносекундных интервалах.

May 21, 2017

Холодный и взрывопожароэлектробезопасный

Бекхофф расширил цветовую гамму дифференциации терминалов — теперь у нас есть модули холодных синих оттенков (blue terminals). Желтые модули серии ELx9xx обеспечивают безопасность, но синяя серия ELX — уже, сама по себе, безопасна.

Изображение: Beckhoff Automation GmbH

Синие модули позиционируются как специализированные модули для опасных зон обрабатывающей промышленности:
  • нефтяная и газодобывающая
  • химическая и нефтехимическая
  • фармацевтическая промышленность
  • водоснабжение и очистка
  • текстильная промышленность
  • горнодобывающая промышленность и металлургия
  • пищевая промышленность
  • табачная промышленность
  • целлюлозно-бумажная промышленность
  • и другие.


Стандарты безопасности


В России, Беларуси, Казахстане, Армении и Кыргызстане взрывозащищенное оборудование должно соответствовать требованиям технических регламентов Таможенного союза (ТР ТС). Российские стандарты взрывобезопасности были приведены в соответствие со стандартами IEC, а также с европейскими директивами ATEX 95 и ATEX 137 и соответствующими европейскими стандартами (EN).

Если оборудование сертифицировано по стандартам ATEX, IECEx, UL, FM или CSA, проверка с целью получения сертификата соответствия на взрывозащищенное оборудование согласно ТР ТС может быть сведена к анализу документов без проведения дополнительных лабораторных испытаний.


Классификация опасных зон


Чтобы лучше понимать что-где-и-зачем, разберемся, что эти зоны опасности обозначают. Подробнее можно найти в интернете, а для примера возьмем Классификация взрывоопасных зон ATEX, взрывоопасная среда, Директива 2014/34/ЕС. В [квадратных скобках] стандарт для Северной Америки (США и Канада).

Газы и пары (летучие соединения):
  • Zone 0 [Class I Division 1 (gases)] — взрывоопасная зона, в которой взрывоопасная смесь присутствует постоянно или в течение длительных периодов.
  • Zone 1 [Class I Division 1 (gases)] — взрывоопасная зона в которой существует вероятность присутствия взрывоопасной газовой смеси в нормальных условиях эксплуатации.
  • Zone 2 [Class I Division 2 (gases)] — взрывоопасная зона в которой маловероятно присутствие взрывоопасной газовой смеси в нормальных условиях эксплуатации, а если она возникает, то редко, и существует очень непродолжительное время.

Пыль:
  • Zone 20 [Class II Division 1 (dusts)] — зона, в которой горючая пыль в виде облака присутствует постоянно или частично при нормальном режиме работы оборудования в количестве, способном произвести концентрацию, достаточную для взрыва горючей или воспламеняемой пыли в смесях с воздухом, и/или где могут формироваться слои пыли произвольной или чрезмерной толщины. Это может быть облака внутри области содержания пыли, где пыль может образовывать взрывчатые смеси часто или на длительный период времени.
  • Zone 21 [Class II Division 1] — зона, в которой горючая пыль в виде облака не может присутствовать при нормальном режиме работы оборудования в количестве, способном произвести концентрацию, достаточную для взрыва горючей пыли в смесях с воздухом.
  • Zone 22 [Class II Division 2] — взрывоопасная зона, в которой облака горючей пыли могут возникать редко и сохраняются только на короткий период или в которых накопление слоев горючей пыли может иметь место при ненормальном режиме работы, что может привести к возникновению способных воспламеняться смесей пыли в воздухе.

На пальцах:
  • Zone 0 — вы в подземной цистерне с бензином.
  • Zone 1 — вы рядом с топливопроводом из подземной цистерны с бензином.
  • Zone 2 — вы рядом с заправочной колонкой на автозаправочной станции.


Серия ELX


Если раньше между датчиком в Zone 0 и модулем ввода/вывода ПЛК находящемся в Zone 2/22 необходимо было ставить промежуточное безопасное и сертифицированное оборудование, то теперь цепочку можно сократить. Для этого и служат синие модули серии ELX. Устанавливать модули непосредственно в Zone 0/1 конечно же нельзя, но к ним можно напрямую подключать датчики, расположенные в Zone 0/20.

Кроме модулей ввода/вывода существуют сертифицированные графические панели и панельные ПК серии CPX. Они также предназначены для установки в зонах 2/22.

Изображение: Beckhoff Automation GmbH

Отправной точкой по серии ELX послужит самый толстый широкий терминал из всей линейки модулей расширения — ELX9560. Это модуль питания обеспечивающий требования стандарта Ex i:
  • Гальванически развязанный.
  • Защищенный от переполюсовки.
  • Ограничивает по напряжению и току подключенные ELX терминалы.
  • Создает требуемое воздушное пространство в 50мм между обычными и безопасными цепями.
  • Выходной ток ограничен 1 Ампером.
Изображение: Beckhoff Automation GmbH

Кратко о других (но не всех) модулях расширения:
  • ELX1052 — двухканальный терминал входных сигналов NAMUR.
  • ELX2002 — двухканальные выхода 24V DC, 40mA для управления магнитными задвижками и другими исполнительными механизмами зон 0/20, 1/21.
  • ELX3152 — двухканальный аналоговый входа 0/4..20mA, NAMUR NE43.
  • ELX3162 — двухканальный аналоговый вход 0..10В.
  • ELX3181 — аналоговый вход 4..20mA, HART.
  • ELX3202/3204 — 2-/4-канальные резистивные термоэленты RTD, 2-3-4- проводные.
  • ELX5151 — энкодер NAMUR.
  • ELX9012 — крышечка для изоляции контактов шины E-bus и питания на последнем в цепочке терминале. Ее наличие — это требование IEC 60079-11.

Существуют жесткие правила по установке и размещению синих модулей:
  • Все синие терминала всегда расположены после синего модуля питания ELX9560 (от которого и запитываются).
  • Запрещается размещать обычные модули после синих терминалов (они всегда идут последними на шине).
  • Нельзя смешивать ELX терминалы с EL терминалами. Возможна только такая и никакая другая последовательность: CX...EL_ELELX9560__ELX__ELX__ELX9012].
  • Обязательно наличие крышки-терминатора ELX9012.


NAMUR и HART


Сигнал типа NAMUR автоматически подразумевает: "искробезопасный сухой контакт с контролем на короткое замыкание и обрыв".

HART-протокол (англ. Highway Addressable Remote Transducer Protocol) — цифровой промышленный протокол передачи данных, попытка внедрить информационные технологии на уровень полевых устройств. Модулированный цифровой сигнал, позволяющий получить информацию о состоянии датчика или осуществить его настройку, накладывается на токовую несущую аналоговой токовой петли уровня 4—20 мА. Таким образом, питание датчика, снятие его первичных показаний и вторичной информации осуществляется по двум проводам. HART-протокол — это практически стандарт для современных промышленных датчиков. Приём сигнала о параметре и настройка датчика осуществляется с помощью HART-модема или HART-коммуникатора. К одной паре проводов может быть подключено несколько датчиков. По этим же проводам может передаваться сигнал 4—20 мА.


Спецификации FDT/DTM


Чтобы все было еще проще, в TwinCAT XAE встроена FDT-надстройка для настройки HART-протокола с помощью компьютерной мышки. Производители оборудования стараются упростить иcпользования их оборудования в проектах других вендоров. С этой целью многие крупные производители объединились в альянс FDTField Device Tool technology, который выработал общую для всех архитектуру. Задача данной архитектуры упростить настройку и управление разнородного оборудования.

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

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

DTM по желанию производителя аппаратуры может быть как простой, так и сложной, может быть небольшой программой, состоящей из нескольких сотен килобайтов, или гораздо большей. DTM создаётся производителем аппаратуры (или, как это часто случается, сторонним производителем программного обеспечения для данной аппаратуры) как средство, предоставляющее конфигурационные данные для конечного пользователя.

FDT является спецификацией, которая определяет, каким образом DTM будет взаимодействовать с управляющим компьютером. Конечный пользователь "видит" DTM, но FDT является скрытой внутри вычислительной или управляющей системы.

Подробный рассказ про FDT/DTM в статье Виктора Жданкина — Спецификации FDT/DTM и консорциум PACTware.

May 14, 2017

Мастер Modbus RTU на шине RS485

Ненадолго станем мастером Modbus RTU на шине RS485, будем читать регистры устройств, например, ряда электросчетчиков или насосов, связанных двумя проводами и контролируемых ПЛК.
Если вам нужно наоборот — побыть подчиненным, выставляя данные наружу, читайте — Сервер Modbus TCP, про адресацию — Взгляд со стороны клиента ModbusTCP.
Для удобства и отсутствия пайки возьмем EL6021, который оснащен клемником, а не D-sub разъемом, хотя это вряд ли имеет значения — все модули организованы одинаково, включая системные, расположенные на "теле" контроллера, такие как -N031. Для RS232 и RS422 все аналогично, кроме линии связи и электрической части.

Для модулей под разъем (D-sub, 9-pin) характерно:
  • RS232, разъем на модуле — "папа" (plug), на кабеле — "мама" (socket).
  • RS485 / RS422, разъем на модуле — "мама" (socket), на кабеле — "папа" (plug).

Бекхофф пропагандирует первенство программной части, поэтому начнем от программы. Подробно про линковку переменных и прочие пошаговые прохождения квеста можно узнать из русскоязычной методички — Modbus_Step-by-step.pdf


Лицензии и библиотеки


Для TwinCAT 2 библиотека поставляется отдельно и за деньги: TS6255 | TwinCAT PLC Modbus RTU. Результатом будет библиотека TwinCAT — ModbusRTU.lib.

Библиотека для TwinCAT 3 TF6255 | TC3 Modbus RTU — "Already included in the basis setup", — то есть она уже включена в стандартную поставку, но потребует дальнейшего лицензирования при выводе проекта в "поле". Резюмирую: пока пишете проект или "щупаете" возможности библиотеки — можно не покупать и пользоваться возобновляемой семидневной лицензией. После готовности проекта, заказываете лицензию и активируете ее на постоянной основе.

Буферы данных и PDO


Первое, что необходимо сделать, это связать программу технологического процесса и "железо". Для этого объявляется ФБ типа:

VAR
    mb : ModbusRtuMasterV2_KL6x22B;
END_VAR

Тип ФБ выбирается, исходя из размера буфера данных модуля связи:
  • ModbusRtuMasterV2_KL6x22B — с буфером в 22 байта.
  • ModbusRtuMasterV2_KL6x5B — с буфером в 5 байт.
  • ModbusRtuMasterV2_PcCOM — с буфером в 64 байта, рассчитано на системный порт контроллера.
  • ModbusRtuMasterV2 — для использования только внутри библиотеки, но можно попробовать задействовать как универсальный ФБ для буферов произвольных размеров (буферы адресуются через указатели pComIn и pComOut).

Размер буфера данных можно изменять в разделе PDO, но не нужно — это востребовано только при портировании старых проектов. Поэтому часть наборов помечено как Legacy — это наследие старых систем, а часть как Standart — это нормальные, современные возможности по трансляции данных в реальном времени.

Для примера, возьмем EL6022 (EL6021). Справочная система говорит, что этот модуль содержит:

    Data buffer 864 bytes receive buffer, 128 bytes transmit buffer
    Bit width in the process image 22 x 8 bit input, 22 x 8 bit output, 16 bit control, 16 bit status

Это означает, что на борту модуля есть аппаратный буфер на прием и отправку данных (Data buffer 864 bytes...), часть аппаратного буфера отражается (или мапится) в PDO-образы TwinCAT (process image 22 x 8 bit input...).



В случае с так называемым системным портом, например, модули -N031 или порт панели P205|CP6606-..., с буферами немного сложнее: необходимо вручную добавить последовательный порт Miscellaneous → Serial Communication Port в устройства ввода-вывода I/O Devices. После этого, по умолчанию, будет включен режим совместимости с коплерами BK8xx0 Mode. Нам же необходим режим совместимости с KL6xx1 Mode (Emulation). KL-EL — без разницы: разная шина — одинаковый принцип работы.

В режиме совместимости с KL6xx1 мы работаем с системным портом, как с модулем расширения EL6022, где Data Bytes — это размер PDO области, а Buffer Size — как бы аппаратный буфер. но не обязательно по настоящему аппаратный — он может эмулироваться операционной системой. Размер в Data Bytes будет влиять на тип структуры данных для линковки с ПЛК-программой. Для стандартных 64-байт подойдет ModbusRtuMasterV2_PcCOM. Как такового, требования не существует, но пусть аппаратный буфер будет как минимум в два раза больше буфера PDO. Помните, что все это не точно и требует плотного тестирования на вашей конкретной системе.
Модули EL60xx умеют становиться виртуальными COM-портами операционной системы: соседняя вкладка EL60xx → Virtual Com Port. После установки драйвера и активирования конфигурации, Windows обнаружит новый последовательный порт, к которому можно будет подключить произвольное внешнее устройство, не имеющее никакого отношения к TwinCAT (сканер штрих кодов, например).
После линковки Input/Output (COM TxPDO-Map Inputs и COM RxPDO-Map Outputs) частей со структурами типа:

TYPE MB_KL6inData22B
STRUCT
    Status: WORD;
    D: ARRAY [0..21] OF BYTE;
END_STRUCT
END_TYPE

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


Экшены


ReadCoils — функция модбас #1, считать дискретный выход подчиненного (Read Coils), результат будет упакован (8 бит в байте).
ReadInputStatus — #2, прочитать дискретный вход подчиненного (Read Input Status), результат будет упакован (8 бит в байте).
ReadRegs — #3, прочитать регистр хранения (Read Holding Registers).
ReadInputRegs — #4, прочитать регистр ввода (Read Input Registers).
WriteSingleCoil — #5, записать (задать) состояние дискретного выхода подчиненного (Write Single Coil), данные должны быть упакованы (8 бит в байте).
WriteSingleRegister — #6, записать в регистр хранения (Write SingleRegister).
WriteMultipleCoils — #15, записать в несколько дискретных выходов подчиненного (Write Multiple Coils), данные должны быть упакованы (8 бит в байте).
WriteRegs — #16, записать в несколько регистров подчиненного (Preset Multiple Registers).
Diagnostics — #8, диагностика (Diagnostics).



Диагностика


Поле Error в ModbusRtuMasterV2_KL6x22B сигнализирует об ошибке, а код ошибки содержится в поле ErrorId. Заниматься диагностикой удобно где-нибудь за пределами приема-передачи данных, заодно подсчитывая статистику пакетов.

VAR
    LastError    : MODBUS_ERRORS;
    CountError   : DINT;
    CountSuccess : DINT;
    Error        : BOOL;
    trigBusy     : F_TRIG;
END_VAR

// обмен данными начинается
// [...]
// обмен данными заканчивается
END_CASE

trigBusy(CLK := mb.BUSY );
IF trigBusy.Q THEN
    IF mb.Error THEN
        Error := TRUE;
        LastError := mb.ErrorId;          // Запоминаем код последней ошибки
        CountError := CountError + 1;     // Подсчитываем количество ошибок
    ELSE
        Error := FALSE;
        CountSuccess := CountSuccess + 1; // Количество удачных пакетов
    END_IF
END_IF

Список всех ошибок есть в статье Modbus RTU Error Codes. Все названия констант "говорящие" и вполне понятные.


Практика


Для обмена данными понадобятся как минимум два буфера, которые могут быть как массивами, так и структурами. Можно читать пачки регистров в структуры, но не забывайте — Modbus оперирует регистрами размером в "слово" (WORD, uint, sint, int).

VAR
    ReadData  : ARRAY [1..10] OF WORD; // массив из данных десяти регистров
    WriteData : ARRAY [1..10] OF WORD; // массив данных для десяти регистров
END_VAR
VAR CONSTANT
    WORDS_TO_READ  : // [...] сколько слов (WORD) прочитать
    WORDS_TO_WRITE : // [...] сколько слов (WORD) отправить
END_VAR


Сбрасываем блоки перед применением, и после применения тоже сбрасываем:

CASE state OF
    INIT_STATE:
        mb.ReadRegs(Execute := FALSE);
        mb.WriteRegs(Execute := FALSE);


Читаем:

READ_STATE:
    mb.ReadRegs(
        UnitID      := 1,                 // адрес подчиненного, начинается с 1
        Quantity    := WORDS_TO_READ,     // сколько слов (WORD) прочитать
        MBAddr      := 0,                 // адрес модбас, может отсчитываться как от нуля,
                                          // так и от единицы, читайте документацию на подчиненного
        cbLength    := WORDS_TO_READ * 2, // сколько прочитать, но уже в байтах
        pMemoryAddr := ADR(ReadData),     // локальный буфер куда будут записаны прочитанные регистры
        Execute     := TRUE,
        Timeout     := T#5s               // таймаут на выполнение операции
    );

    IF NOT mb.BUSY THEN
        mb.ReadRegs(Execute := FALSE);
        IF mb.Error THEN
            state := INIT_STATE;      // обрабатываем ошибки
        ELSE
            state := // [...]         // продолжаем работу 
        END_IF
    END_IF


Пишем:

WRITE_STATE:
    mb.WriteRegs(
        UnitID      := 1,
        Quantity    := WORDS_TO_WRITE,     // сколько слов (WORD) записать
        MBAddr      := 0,
        cbLength    := WORDS_TO_WRITE * 2, // сколько записать, но уже в байтах
        pMemoryAddr := ADR(WriteData),     // локальный буфер данные которого
                                           // будут записаны в регистры подчиненного
        Execute     := TRUE,
        Timeout     := T#5s                // таймаут на выполнение операции
    );

    IF NOT mb.BUSY THEN
        mb.WriteRegs(Execute := FALSE);
        IF mb.Error THEN
            state := INIT_STATE;           // обрабатываем ошибки
        ELSE
            state := // [...]              // продолжаем работу 
        END_IF
    END_IF


И не забывайте про время обработки цикла ПЛК-задачи: его продолжительность должна быть достаточной для вычитывания буферов, иначе начнет происходить периодическое переполнение и вы будете терять актуальную информацию.