Найти тему
Максим Бузаев

Создание динамических окон в панелях Weintek

В последнее время большое распространение в АСУТП получили HMI панели Weintek. Я хочу рассказать о создании динамических окон в программных проектах для этих панелей.

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

Предположим, у вас на установке 10 одинаковых насосов и вам нужно вызывать для работы с ними окно с кнопками и индикаторами.

Можно сделать 10 одинаковых окон.

Но если потребуется что-то в них изменить (и не один раз), то время работы над проектом возрастает.

На помощь приходят динамические окна - Indirect (косвенные) window, как они называются в панелях Weintek.

Способ их создания следующий.

Начальные условия:

Вы умеете работать с программой EasyBuilder Pro (в дальнейшем для краткости – EB), умеете добавлять окна, располагать на них компоненты и менять свойства у этих компонентов.

Вы знаете, что такое MODBUS TCP и как с ним бороться.

Установлена программа EasyBuilder Pro v6.06.01.446 Build 2021.10.07.

Создан проект EasyBuilder для панели типа XE Series – MT8121XE/ MT8150XE.

Предполагается, что панель соединена с ПЛК по MODBUS TCP (в дальнейшем для краткости – МТСР), а ПЛК, в свою очередь управляет двумя насосами – Р-1 и Р-2, и считывает их состояния. Управление производится одним битом – 1-включить, 0 отключить.

В проекте Weintek в ЕВ создано устройство (Local Device) MODBUS TCP/IP.

Регистры MTCP в ПЛК:

Управление Р-1 – 0х1 (Coil)

Состояние Р-1 – 0х2

Управление Р-2 – 0х3

Состояние Р-2 – 0х4.

Принцип работы с динамическим окном следующий.

Создаётся одно окно с элементами индикации и управления. В этом окне запускается макрос, который выполняет обмен между элементами индикации и управления и ПЛК по MTCP.

Но адреса, откуда читать и куда писать по MTCP, в это окно передаются разные при разных вызовах этого окна.

Передача адресов осуществляется через слова LW10 и LW11.

Теперь займёмся этим практически.

При создании нового проекта в ЕВ создаётся окно WINDOW_010. В нём и будем вызывать динамическое окно.

Одно окно у нас уже есть - WINDOW_010. Создадим ещё одно окно – PUMP_CONTROL (название значения не имеет, просто для ясности), размером 300х200. Запоминаем номер окна PUMP_CONTROL (допустим, 11).

Добавим в окно WINDOW_010 компонент «Indirect window».

1 Компонент Indirect window на панели инструментов.
1 Компонент Indirect window на панели инструментов.

Indirect window – это по сути рамка для другого существующего в проекте окна, которое будет в нём отображаться. Содержимое слова LW0 «Address» в свойствах – это номер окна. Окно с этим номером вызывается при изменении LW0.

Свойства добавляемого компонента Indirect Window
Свойства добавляемого компонента Indirect Window

Добавим компонент-кнопку Combo Button, для вызова окна управления насосом Р-1.

Это кнопка, которая выполняет сразу несколько функций.

В открывшемся окне свойств Combo Button добавляем 3 функции Set Word:

Local HMI LW0 = 11 (это номер окна PUMP_CONTROL),

Local HMI LW10 = 1 (адрес регистра MTCP для управления Р-1),

Local HMI LW11 = 2 (адрес регистра MTCP состояния Р-1).

Добавляем ещё одну кнопку Combo Button, для вызова окна управления насосом Р-2. Значения будут немного другими:

Local HMI LW0 = 11 (это номер всё того же окна PUMP_CONTROL),

Local HMI LW10 = 3 (адрес регистра MTCP для управления Р-2),

Local HMI LW11 = 4 (адрес регистра MTCP состояния Р-2).

Окно с многофункциональными кнопками (Combo Button) и компонентом Indirect window.
Окно с многофункциональными кнопками (Combo Button) и компонентом Indirect window.

Создаём в проекте макросы.

Макрос macro_LW_reset – для сброса LW0 при закрытии окна PUMP_CONTROL, чтобы его можно было открыть ещё раз.

//Сброс слова LW0 при закрытии окна "Включение/отключение блокировки"

macro_command main()

int Tag_0 = 0

SetData(Tag_0, "Local HMI", LW, 0, 1)

end macro_command

Макрос macro_MODBUS – читает и пишет по MTCP биты управления и состояния.

//Чтение состояния и управление насосом

macro_command main()

bool Lamp = 0

bool Button = 0

int Control_reg_addr = 0 //АДРЕС регистра для управления насосом

int State_reg_addr = 0 //АДРЕС регистра состояния насоса

//Управление

//Читаем АДРЕС регистра для управления насосом

GetData(Control_reg_addr, "Local HMI", LW, 10, 1)

//Считываем нажатие кнопки ПУСК или СТОП в переменную Button

GetData(Button, "Local HMI", LB, 0, 1)

//Записываем значение переменной Button в бит управления по адресу, прочитанному из LW10

SetData(Button, "MODBUS TCP/IP", 0x_single_Bit, Control_reg_addr, 1)

//Состояние

//Читаем АДРЕС регистра состояния насоса

GetData(State_reg_addr, "Local HMI", LW, 11, 1)

//Читаем в переменную Lamp бит состояния насоса по адресу, прочитанному из LW11

GetData(Lamp, "MODBUS TCP/IP", 0x_single_Bit, State_reg_addr, 1)

//Записываем значение переменной Lamp в LB1

SetData(Lamp, "Local HMI", LB, 1, 1)

end macro_command

Теперь займёмся тем окном, которое будем вызывать – PUMP_CONTROL.

Добавим кнопки ПУСК и СТОП, лампочку, показывающую состояние насоса и функциональную кнопку (Function key) для закрытия окна.

У кнопок ПУСК и СТОП один и тот же адрес – Local HMI LB0, но разные функции:

ПУСК – Set ON, СТОП – Set OFF.

У лампочки адрес Local HMI LB1.

У функциональной кнопки выберем функцию работы с окнами – Close window.

Окно управления насосом.
Окно управления насосом.

В свойствах окна назначим макросы –

Cycle – macro_MODBUS – циклическое выполнение, пока окно открыто,

Close – macro_LW_reset – выполняется при закрытии окна.

Вот, собственно, и всё.

Для проверки запускаем Online Simulation (нужно иметь какой-нибудь Modbus Slave) и проверяем, как работает.