Внезапно, текущая версия библиотеки 0.5, т. е. родилась она не вчера и уже работает в некоторых проектах. Основные фишки AdsRemote — автоматический контроль канала связи на обрыв соединения и переподключения, а также простой способ работы с переменными ПЛК-программы и шины данных вообще. Кроме этого, библиотека умеет находить контроллеры в Ethernet-подсети и удаленно добавлять запись в AMS-роутер контроллера.
Библиотека пока не умеет работать со структурами и дает чуть большую нагрузку на контроллер, так как активно использует событийный механизм роутера, но универсальные механизмы всегда чуть менее производительны, чем узко заточенные. Удобство и скорость разработки просто так не даются.
Для работы понадобится установленный TwinCAT 2.11 или 3.1, иначе говоря — необходим работающий AMS-роутер. Еще проще говоря — Твинкат должен быть установлен и работать. Инженерной версии вполне достаточно. Не забудьте добавить записи в таблицы роутеров.
Работа с библиотекой начинается с экземпляра контроллера. Для этого передаем AmsNetId контроллера в конструктор класса PLC. Напоминаю, связь не начнет работать до тех пор, пока вы не добавите нужные записи в таблицы роутеров.
С момента инициализации экземпляра объекта, в фоне начинает работать поток автоматически контролирующий состояние связи с контроллером. Чтобы оперативно узнавать о проблемах со связью, необходимо подписаться на уведомления:
AdsDevice в данном случае — это ADS-устройство в составе контроллера. Именно они идентифицируются на шине по номеру порта. Если связь с контроллером прервется, мы получим столько уведомлений, сколько устройств зарегистрировано в объекте ПЛК. Соответственно, при отключении только одного устройства — придет только одно уведомление.
Создавать устройства AdsDevice мы не можем: при добавлении новой переменной, автоматически анализируется номер порта устройства и, при необходимости, добавляется новое устройство. В принципе, разработчику можно об устройствах и портах не задумываться, а работать исключительно с переменными:
С момента создания переменной, ее значение будет автоматически обновляться в соответствии с переменной на стороне контроллера. Переменные типа Var<T> могут спокойно участвовать в обычных арифметических операциях. За редким исключением их тип будет автоматически приведен к значимому или строковому:
Можно подписаться на уведомления об изменении значения переменной:
Можно использовать единый обработчик для нескольких переменных:
Для изменения значения переменной на стороне контроллера, необходимо обратиться к внутреннему свойству переменной — RemoteValue:
Неудобно связывать переменные по одной за раз. Проще дать описание всех сразу, а затем активировать одной строкой:
Более подробный вариант:
В любом случае, необходимо одним из двух способов указать тип переменной. В противном случае получится NULL, а не экземпляр переменной.
Для дальнейшего использования переменных в связке с WPF-контролами — необходимо объявить их как параметры:
После задания описания, объект с данными создается и активируется одной строкой:
Если требуется вызов сложного конструктора — можно воспользоваться следующим вариантом:
Все переменные, снабженные соответствующим атрибутом, будут связаны с переменными ПЛК, их значения будут обновляться автоматически.
Для работы понадобится установленный TwinCAT 2.11 или 3.1, иначе говоря — необходим работающий AMS-роутер. Еще проще говоря — Твинкат должен быть установлен и работать. Инженерной версии вполне достаточно. Не забудьте добавить записи в таблицы роутеров.
Подключение и отключение
Работа с библиотекой начинается с экземпляра контроллера. Для этого передаем AmsNetId контроллера в конструктор класса PLC. Напоминаю, связь не начнет работать до тех пор, пока вы не добавите нужные записи в таблицы роутеров.
PLC plc = new PLC("5.2.100.109.1.1");
С момента инициализации экземпляра объекта, в фоне начинает работать поток автоматически контролирующий состояние связи с контроллером. Чтобы оперативно узнавать о проблемах со связью, необходимо подписаться на уведомления:
plc.DeviceReady += Plc_DeviceReady; // когда связь установлена или восстановлена plc.DeviceLost += Plc_DeviceLost; // когда связь потеряна [...] private void Plc_DeviceReady(object sender, AdsDevice e) { Log("READY [" + e.Address.Port.ToString() + "]"); }
AdsDevice в данном случае — это ADS-устройство в составе контроллера. Именно они идентифицируются на шине по номеру порта. Если связь с контроллером прервется, мы получим столько уведомлений, сколько устройств зарегистрировано в объекте ПЛК. Соответственно, при отключении только одного устройства — придет только одно уведомление.
Работа с переменными
Создавать устройства AdsDevice мы не можем: при добавлении новой переменной, автоматически анализируется номер порта устройства и, при необходимости, добавляется новое устройство. В принципе, разработчику можно об устройствах и портах не задумываться, а работать исключительно с переменными:
Var<short> main_count = plc.Var<short>("MAIN.count"); Var<ushort> main_state = plc.Var<ushort>("MAIN.state"); Var<ushort> frm0 = plc.Var<ushort>("Inputs.Frm0InputToggle", 27907); Var<ushort> devState = plc.Var<ushort>(0xF030, 0x5FE, 27907); Var<short> g_Version = plc.Var<ushort>(".VERSION");
С момента создания переменной, ее значение будет автоматически обновляться в соответствии с переменной на стороне контроллера. Переменные типа Var<T> могут спокойно участвовать в обычных арифметических операциях. За редким исключением их тип будет автоматически приведен к значимому или строковому:
long countTotal += main_count; MessageBox.Show(main_count);
Можно подписаться на уведомления об изменении значения переменной:
main_count.ValueChanged +=
delegate
{
counterStatusLabel.Text = main_count;
};
Можно использовать единый обработчик для нескольких переменных:
main_count.ValueChanged += OnValueChanged; main_state.ValueChanged += OnValueChanged; protected void OnValueChanged (object src, Var v) { ushort val = (ushort)v.GetValue(); framesTotal += val / 2; label1.Text = val.ToString(); };
Для изменения значения переменной на стороне контроллера, необходимо обратиться к внутреннему свойству переменной — RemoteValue:
main_count.RemoteValue = 123;
Связывание группы переменных
Неудобно связывать переменные по одной за раз. Проще дать описание всех сразу, а затем активировать одной строкой:
public class PRG_Main { [LinkedTo("MAIN.count")] public Var<short> count; [LinkedTo("MAIN.state")] public Var<ushort> state; }
Более подробный вариант:
public class PRG_Main { [LinkedTo("MAIN.count", As: typeof(short), Port: (int)AmsPort3.PlcRuntime1)] public Var count; [LinkedTo("MAIN.state", Port: (int)AmsPort3.PlcRuntime1)] public Var<ushort> state; [LinkedTo("Inputs.Frm0InputToggle", Port: 27907)] public Var<ushort> frm0_1; [LinkedTo(IGrp: 0xF030, IOffs: 0x5F4, Port: 27907)] public Var<ushort> frm0; }
В любом случае, необходимо одним из двух способов указать тип переменной. В противном случае получится NULL, а не экземпляр переменной.
Для дальнейшего использования переменных в связке с WPF-контролами — необходимо объявить их как параметры:
public class PRG_Main { [LinkedTo("MAIN.count")] public Var<short> count { get; set; } [LinkedTo("MAIN.state")] public Var<ushort> state { get; set; } }
После задания описания, объект с данными создается и активируется одной строкой:
PRG_Main Main = plc.Class<PRG_Main>();
Если требуется вызов сложного конструктора — можно воспользоваться следующим вариантом:
Main = new PRG_Main(param1, param2, ...); plc.Class(Main);
Все переменные, снабженные соответствующим атрибутом, будут связаны с переменными ПЛК, их значения будут обновляться автоматически.
No comments
Post a Comment
Note: Only a member of this blog may post a comment.