Данные железа связываются с переменными программной части через конфигурацию контроллера. Иногда это не удобно и хочется идти не от конфигурации, а от кода (Code First). Как пример, я взял линковку переменных, связанных с управлением движением сервоосей NC PTP. И еще, верните, пожалуйста, карту мапинга — она была бессмысленной, но красивой ↘
Атрибуты
Переменной можно дописать атрибут — это специальная строка, которая говорит системе, что с переменно нужно сделать дополнительные телодвижения. Атрибутов было мало — сейчас стало много. В случае сервоосей нас интересует атрибут
TcNcAxis:
{attribute 'TcNcAxis' := 'Axis 3'}
axMaster : AXIS_REF;
Здесь атрибут (ключевое слово
attribute) заключен в фигурные скобки. Строка атрибута должна идти перед объявлением переменной или экземпляром функционального блока. Далее в кавычках следует одно или несколько(!) имен переменных или ФБ, символ присваивания
:= , и наконец значение атрибута. В данном случае значением служит имя NC оси взятое из конфигурации
'Axis 3' . Записывается прямо с пробелами и другими символами, для этого и нужны кавычки.
Добавив атрибут и пересобрав проект, я автоматически получу слинкованную с сервоосью переменную типа AXIS_REF. Остается только реактивировать конфигурацию в ПЛК и все готово. Еще раз:
- Добавить строку атрибута или заменить имя оси в значении атрибута на другое.
- Пере/собрать проект (Build → Rebuild Solution).
- Активировать конфигурацию. Внимание! Активировать конфигурацию!
После активации, слинкованные через атрибут переменные будут подсвечены синим значком линковки (см. FromPlc и ToPlc):
Когда системе не удается слинковать данные, она сообщает об этом большим и внезапным сообщением поперек экрана. Проект в итоге соберется, но данные бегать не будут. Если же все прошло удачно, то после пересборки проекта система сообщит:
Message 06.01.2019 21:56:05 729 ms | 'TwinCAT XAE': Existing NC axis 'Axis 3' linked to instance 'MAIN.axMaster'
Очень удобно, так как теперь можно еще больше сконцентрироваться на коде. Главное не забывать пересобирать проект, а затем активировать конфигурацию. Аналогично можно работать с функциональными блоками.
Ввод/вывод
Переменные ввода/вывода также удобно линковать со стороны кода. Причем, здесь мы как раз увидим тот самый обещанный символьный маппинг во всей красе, так как будем использовать сложный символьный путь к данным.
На этот раз воспользуемся атрибутом
TcLinkTo. Вообще, он простой, поэтому я возьму что-нибудь посложнее
TcLinkToOSO. Атрибут c -OSO на конце позволяет не просто связать переменную типа
AT %IQ* с данными, но также задать количество разрядов тут и там, а также их битовое смещение.
Немногим ранее, я проверял
как работает функция быстрого останова в NC. Пришлось сплясать с бубном, чтобы прикрепить булевый флаг к биту частично занятой переменной. Надеюсь, что с атрибутами получится в разы проще.
Напомню задачу: в настройках NC оси, в ветке конфигурации
Axis X → Drive → Inputs →... есть поле
nState4. Седьмой бит этого поля отвечает за быстрый останов данной сервооси. Пара битов этого поля уже автоматически слинкована с какими-то данными, поэтому действовать нужно аккуратно.
Быстрый стоп не работает на виртуальных осях! Необходимо серво-железо.
Для начала сходим в конфигурацию и посмотрим, где расположены требуемые данные в конфигурации со стороны железа, то есть смотрим во вкладку
Variable, текстовое поле
Full Name:
TINC^NC-Task 1 SAF^Axes^Axis 3^Drive^Inputs^In^nState4. Это полный путь к данным переменной
nState4 в конфигурации:
Копируем и вставляем его в код программы как значение атрибута
{attribute 'TcLinkToOSO' := '<0,1,7>TINC^NC-Task 1 SAF^Axes^Axis 3^Drive^Inputs^In^nState4'}
cmd_FastStop AT %Q* : BOOL;
Мне нужен всего-лишь один бит, поэтому я расширил путь специальным суффиксом -OSO:
<0,1,7>. Последовательно слева-направо:
- 0 — битовое смещение в переменной ПЛК, то есть с какого бита ПЛК переменной начинать связывать. Можно связать не всю переменную, а только ее часть и не обязательно с начала и до конца: с помощью -OSO можно выхватить кусочек из середины.
- 1 — количество связываемых бит.
- 7 — битовое смещение в переменной на стороне железа (в моем случае в переменной nState4). Мне нужен бит номер 7, поэтому смещение = 7.
После сборки проекта система сообщает:
Message 06.01.2019 22:11:15 930 ms | 'TwinCAT XAE': Variable 'MAIN.cmd_FastStop' (Offs: 0) linked with 'TINC^NC-Task 1 SAF^Axes^Axis 3^Drive^Inputs^In^nState4' (Offs: 7, Size: 1)
Разбавлю полным листингом программы:
PROGRAM MAIN
VAR
{attribute 'TcNcAxis' := 'Axis 3'}
axMaster : AXIS_REF;
McPower : MC_Power;
McVelocity : MC_MoveVelocity;
cmd_PowerOn : BOOL;
cmd_Velocity : BOOL;
{attribute 'TcLinkToOSO' := '<0,1,7>TINC^NC-Task 1 SAF^Axes^Axis 3^Drive^Inputs^In^nState4'}
cmd_FastStop AT %Q* : BOOL;
actVelo : LREAL;
state : INT;
END_VAR
[...]
axMaster.ReadStatus();
actVelo := axMaster.NcToPlc.ActVelo;
CASE state OF
0:
IF McPower.Status THEN
cmd_Velocity := TRUE;
state := 100;
END_IF
100:
IF McVelocity.InVelocity THEN
cmd_Velocity := FALSE;
state := 200;
END_IF
200:
IF actVelo < 0.1 OR NOT McPower.Status THEN
cmd_PowerOn := FALSE;
state := 300;
END_IF
300:
IF NOT McPower.Status THEN
cmd_FastStop := FALSE;
state := 0;
END_IF
END_CASE
McPower(
Axis := axMaster,
Enable := cmd_PowerOn,
Enable_Positive := TRUE,
Enable_Negative := TRUE
);
McVelocity(
Axis := axMaster,
Execute := cmd_Velocity,
Velocity := 200
);
Теперь если во время работы программы дернуть за булевый флаг
cmd_FastStop и установить его в
TRUE, мы незамедлительно получим быструю остановку сервооси, а система подскажет нам, что:
Message 06.01.2019 22:23:25 772 ms | 'TCNC' (500): 'Axis 3' (Axis ID: 3) <NOTE>: 'Fast axis stop' triggered by IO interrupt 'Drive->Status4->Bit7' (SignalType=1 (SignalType_RisingEdge), FastDec=0.000000, FastJerk=0.000000, IoState=1, OldIoState=0)!
Мышой проще
А еще есть кнопка
Link To PLC... которая никакого отношения к символьной линковке не имеет, зато позволяет присобачить одним кликом мыши переменную AXIS_REF к NC оси, и безо всяких там NcToPlc, PlcToNc, ...