November 26, 2020

Компактные сервомодули ELM72xx

Линейка сервотерминалов расширилась до 16 ампер. ELM72xx предлагает прикоснуться к блестящему металическому корпусу компактного сервотерминала.

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

Сервотерминалы устанавливаются на дин-рейке вместе с другими EtherCAT терминалами в общей линейке. Металлический корпус лучше рассеивает тепло. Кабели подключаются через разъемы: должно быть удобнее.

  • ELM7211 — 1 двигатель до 4.5 A (Irms).
  • ELM7212 — 2 канала по 4.5 A (Irms).
  • ELM722— один на 8 A (Irms).
  • ELM722— два по 8 A (Irms).
  • ELM723— тот самый единственный на 16 A (Irms).

Модули расчитаны на двигатели AM8100. Питание 48 вольт; 24В на половине мощности. Питание и обратная связь в одном кабеле — однокабельная технология. Можно подключить внешний тормоз, обратную связь (энкодер или резольвер) и внешний тормозной резистор. Цифровые входа поддерживают функцию Probe Unit.

TwinSAFE логика обеспечивает безопасность через простые функции STO/SS1 (Safe Torque Off / Safe Stop 1) поверх EtherCAT (FSoE, Safety over EtherCAT) или в рамках комплекса безопасности движения Safe Motion (IEC 61800-5-2 / ГОСТ Р МЭК 61800-5-2-2015).

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

November 17, 2020

Переменная через указатель, через ADS

Значение переменной можно прочитать через указатель по ADS.

PROGRAM MAIN
VAR
    state:  UINT;
    pState: POINTER TO UINT;
END_VAR

pState := ADR(state);


Прочитаем значение переменной `state` через ее указатель `pState`. Нужно разыменовать указатель, добавив спец. символ `^` к имени указателя. Получим `pState^`. Программа на C# для текущей версии 4.4.10 библиотеки Beckhoff.TwinCAT.Ads:

ushort state = (ushort) tcAdsClient.ReadSymbol( "MAIN.pState^", typeof( ushort ), false );


Значение переменной читается. Теперь возьмем пробную версию новой библиотеки 5.0.1-preview.12 под .NET Core 3.1.0. Код поподробнее:


Программа читает переменную и в зависимости от ее значения рисует замысловатые узоры. Имея указатель можно вытягивать значение переменной. Это полезное свойство и дополнительные телодвижения здесь не нужны.


Для новой библиотеки под .NET Core требуется создать файл роутинга `StaticRoutes.xml`. В этом файле настраиваются соединения между целевым контроллером и ПК. Если контроллер  и ПК находятся на одной и той же машине, то настраивать этот файл не нужно. Можно просто удалить его.

November 13, 2020

Атрибут TcNcAxis

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


Массивы

Большое количество осей удобно объединять в массивы. Массив осей можно линковать одним атрибутом:

{attribute 'TcNcAxis' := '[1]:=Axis X; [2]:=Axis Y; [3]:=Axis Z' }
axes: ARRAY [1..3] OF AXIS_REF;


В имени оси можно использовать пробел. Имя оси в атрибуте тоже записывается с пробелами. Количество пробелов должно совпадать и между буквами в имени, и в атрибуте. Axis⎵X и Axis⎵⎵X — это разные оси.

Если имя оси указано в атрибуте, но оси с таким именем нет, то в конфигурации будет создана новая ось.

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


Автомапинг функциональных блоков

Если нет доступа к внутренностям функционального блока, можно воспользоваться… атрибутом:

{attribute 'TcNcAxis' := '.axisZ:=Axis Z'}
fbFoobar: FB_Foobar;

[...]

FUNCTION_BLOCK FB_Foobar
VAR
    axisZ: AXIS_REF;
END_VAR

[...]

В одном программном блоке может быть несколько экземпляров функционального блока. Но можно слинковать оси только одного экземпляра ФБ. Нельзя линковать несколько переменных AXIS_REF с одной и той же осью. При компиляции система выдаст ошибку: 
Mapping conflict! Same data of 'TINC^NC-Task 1 SAF^Axes^Axis Z^Inputs^FromPlc' is written from different sources


November 10, 2020

Секретный сервис 700

Не все сервисы TwinCAT описаны в документации. В старых исходниках библиотеки AdsClient, в файле AdsSpecial.cs, есть любопытная функция public string GetTargetDesc(). Описание функции гласит: "Get an xml description of the plc...". Посмотрим, какое именно описание отдаст нам контроллер.

Начнем с системного сервиса, порт номер R3_CTRLPROG = 10000. Официальное описание списка функций заканчивается номером 600 (см. таблицу System Service Index Groups). Мы же прочитаем индекс 700 (0x02BChex). Настраиваем роутинг и начинаем читать. Код C# программы:

 

Первый запрос отправляем с параметром typeof(int). Где-то внутри библиотеки это транслируется в параметр команды равный 4 — это длина типа данных int в байтах. В ответ, запрос вернет длину XML текста с описанием устройства. Зная размер, мы отправляем второй запрос в тот же порт-индекс-смещение, но в качестве параметра передаем длину описания, полученного на предыдущем шаге. Результат парсим. С помощью LINQ ищем и вытаскиваем интересующие нас поля описания.

Контроллер CX9020 вернул такой XML:

 

Сравним описания от CX9020 (Win CE) и ноутбука (Windows 10). Чтобы отследить различия, сохраним XML в отдельный файл: xdoc.Save( "cx9020.xml" ); и воспользуемся программой WinMerge:


TС/BSD

Новая, перспективная и все еще недоступная операционная система выдает следующее описание:

 

Пропали элементы `ImageDevice`, `ImageLevel`. Значение `CPUArchitecture` стало более осмысленным, но что такое 9 все еще непонятно.


Тоже сервисы

Можно найти еще несколько интересных сервисов, если копнуть глубже. Для раскопок пригодится какой-нибудь HEX-вьюер (VSCode hexdump) и следующая строка: File.WriteAllBytes( $"idx_{READDEVDESCRIPTION_IDX}.bin", adsStream.ToArray() ); // Начинайте копать.

Индекс 701 выдаст список всех сетевых интерфейсов доступных на устройстве. IP-адреса, маски подсети и что-то еще. Формат неизвестен, но можно разобраться самостоятельно. Копайте.

Из любопытного, для TC/BSD сервис возвращает название сетевого интерфейса в юникс стиле — `em0`.
А для Windows возвращает GUID: "{7D8FDCBA-6250-8DFF-4089-AB0845B12EDC} Qualcomm Atheros AR5BWB222 Wireless Network Adapter 192.168.2.177 255.255.255.0".

Индекс 702 отдает имя целевой машины: PC-8E5B1A, CX-3F5BC9... Строка заканчивается '\0', не забывайте про .TrimEnd('\0'); Продолжайте копать.


November 6, 2020

Агент данных OPC UA

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

ПКМ по пустому месту → Add Gate (OpcUaDevice). В окне `Properties` ввести в поле`Url` адрес своего OPC UA сервера: opc.tcp://192.168.1.100:4840. Добавьте канал подписчика: Add Channel (Subscriber), стрелка вниз 🡇.

Теперь открываем окно `Target Browser`, закладка `OpcUa`, добавляем OPC UA сервер контроллера, выбираем необходимые объекты-переменные и тащим их на "подписчика".

Возможно понадобится донастроить переменные подписчика. В моем случае Агент добавил мусор в имя переменной ns=4;s=MAIN.nCounter. Исправляется в окне `Properties`, поле `URN` и превращается в MAIN.nCounter. Ниже в примере исправлена только одна переменная-символ:

>>> {"Timestamp":"2020-11-06T11:48:08.151","GroupName":"_MQTT Broker_28","MAIN.nCounter":-1946,"ns=4;s=MAIN.rCounter":784486.0}
>>> {"Timestamp":"2020-11-06T11:48:09.150","GroupName":"_MQTT Broker_28","MAIN.nCounter":-1846,"ns=4;s=MAIN.rCounter":784586.0}
>>> {"Timestamp":"2020-11-06T11:48:10.150","GroupName":"_MQTT Broker_28","MAIN.nCounter":-1746,"ns=4;s=MAIN.rCounter":784686.0}

November 3, 2020

Начало работы с агентом данных

Агент позволяет передавать переменные программы и другие данные из одного места в другое. Например, есть группа контроллеров CX8090. На отдельном ПК устанавливается TC3 IoT Data Agent. Он настраивается на проброс данных через интернет на сервер-брокер MQTT. Из брокера данные забираются в базу данных. Позже аналитики анализируют, а сервисный отдел мониторит и бдит. Версия TwinCAT, разрядность и тип процессора, древность контроллеров — все это не важно. Переменные из контроллера можно передавать куда угодно, в обе стороны.

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

Современные протоколы типа MQTT–AMQTT–RabbitMQ не требуют входящего подключения. Агент и контроллеры могут находится за NAT, файерволом или другой сетевой инфраструктурой. IP-адрес может быть серым и динамическим, но подключение к брокеру всегда исходящее. Поэтому переменные контроллера легко отдавать и легко забирать. В обе стороны.


Лицензии

Для ПК, на котором установливается Агент, необходимы минимум две лицензии: TC1000 | TC3 ADS и TF6720 | TC3 IoT Data Agent. Доступна пробная лицензия на 7 дней.

Лицензирование основано на группах порталов. Порталы объединяются в пакеты (Gate packs). Порталом называют одно подключение. Например, подключение к устройству через ADS или OPC UA. Лицензия TF6720 обеспечивает работу с четырьмя порталами. Большее количество порталов можно получить после покупки дополнительных лицензий (TF6721-TF6724). Количество порталов складываются: TF6720 + TF6721 = 8 порталов.


Принципы работы

Open local, Save local работают со схемой в локальной конфигурации Агента C:\TwinCAT\3.1\Boot\TcIotDataAgentConfig.xml. Эта схема будет использована при старте Агента на этом локальном ПК. Во время работы рядом будет лежать лог TcIotDataAgent.log. По нему можно проводить диагностику работы Агента.

Open file, Save file импорт/экспорт схемы из отдельного файла.

С помощью кнопки "активировать конфигурацию", можно активировать схему на удаленном контроллере. На кнопке изображена традиционная горка кубиков (Save to selected target and activate).

В окне `Topology` создаем схему передачи данных. Нужно запомнить два простых принципа: создаем правой кнопкой мыши (ПКМ), а затем соединяем элементы с помощью Ctrl + тащим и бросаем. Например:

  • ПКМ по пустому месту → Add Gate (ADS) → получился круг — это ADS-портал, ведущий к переменным контроллера.
  • Затем, ПКМ → Add Gate (MQTT) → появилось облако — это брокер MQTT, источник данных.
  • ПКМ ADS портал → Add Channel (Subscriber) → создается подписчик (subscriber) в виде прямоугольника. Стрелка вниз 🡇 указывает направление подключения.
  • ПКМ Подписчик → Add Symbol → добавляется новая переменная (symbol) для чтения из контроллера. Можно сделать проще: открыть окно `Target Browser`, перетащить и бросить переменную на "подписчика".
Схему можно создавать и редактировать через другие окна программы. Исследуйте их. Выберите удобный способ работы с программой.

Аналогично поступаем с порталом MQTT Broker, где вместо `Add Gate` доступен `Add Channel`. Брокер работает не с переменными, а с каналами. Через них идут потоки переменных.

Дальше тащим прямоугольник подписчика ADS: Ctrl + левая клавиша мыши (ЛКМ). Бросаем его на прямоугольник канала MQTT. Между элементами появляются связи.

Настройки всех элементов собраны в окне `Properties`.


Пример программы

Необходимо проработать четыре момента:

  • ПЛК программу как источник данных. Подойдет любая версия TwinCAT. Я брал как вторую, так и третью версию TwinCAT. Меняется номер порта ADS 801 → 851, но принципы создания схемы остается прежним.
  • Создать схему передачи данных для Агента.
  • Выбрать MQTT брокер данных.
  • Создать клиента для брокера MQTT. Я напишу простую программу на C#. Она будет читать данные из брокера. Здесь можно воспользоваться готовыми клиентами MQTT и запустить их на смартфоне.


ПЛК программа примитивная:

PROGRAM MAIN
VAR
    iCount: INT;
    rCount: REAL;
END_VAR

iCount := iCount + 1;
rCount := rCount + 0.1;


Схема Агента

Пора выбрать бесплатного брокера на тестирование. Мне понравился HiveMQ. Кроме него проверил Mosquitto. Он работал, но значительно медленнее.

Пришло время создать схему:


Разбивка по каналам позволяет устанавливать единые сетевые настройки для нескольких переменных сразу. Можно создать один единственный канал и транслировать в нем сразу несколько переменных. Чтобы было интереснее, я разбил трансляцию от брокера на два канала (см. картинку выше, правая часть):

  • Ads_Mqtt_11_19 — транслирует переменную MAIN.rCount;
  • Ads_Mqtt_11_17 — передает целое число из переменной MAIN.iCount.

Внутри канала данные брокера можно раскидать по темам (Topic). Это настраивается в окне `Properties`. Например, пусть `rCount` как бы передается из жилой комнаты GOT/TWINCAT/ROOM, а переменная `iCount` приходит из офиса GOT/TWINCAT/OFFICE. В клиенте брокера я смогу выбрать или одну конкретную, интересующую меня тему, или сразу несколько тем. Темы фильтруются с помощью спец. символов `*`, `?` или `#`. Например, я хочу в одном канале получать данные ROOM+OFFICE: GOT/TWINCAT/#.


Клиент брокера

Для C# я использовал библиотеку MQTTnet. Она легко устанавливается из NuGet. Раскомментируйте строку и подставьте название своего топика-комнаты в константу `MQTT_TOPIC`.

 

Результат работы клиента:


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