Category Archives: Программы ПЛК

Стиральная машинка (SFC, задачи, типы данных)

Пожалуй, самый простой случай, когда многозадачность может быть полезна – это моделирование объекта управления. Классическая простейшая задача на применение языка SFC – это стиральная машина, основные этапы работы которой: контроль закрытия дверки, ожидание нажатия кнопки пуск, наполнение бака водой, нагрев, стирка, слив воды.

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

Для описания режима определим структуруWashPara:

TYPE WashPara :

STRUCT

WaterIn: TIME;

WashTime: TIME;

WashTemp: WORD;

WaterOut: TIME;

END_STRUCT

END_TYPE

Это ничто иное, как новый тип данных. Такие определения делаются в проекте централизованно на вкладке Data types (типы данных) менеджера проекта. Теперь мы можем объявлять в проекте переменные типа WashPara.

Создадим в проекте новый POU типа программа (PROGRAM), назовем его Wash и выберем упрощенный язык SFC. В разделе объявлений Wash объявим константу для числа режимов:

VAR CONSTANT

maxProgNr :BYTE:= 5;

END_VAR

Идея состоит в том, чтобы везде, где потребуется количество режимов, использовать maxProgNr, это позволит при необходимости легко менять их число в единственном месте программы. Для хранения режимов объявим массив структур:

MyWashPara: ARRAY [0..maxProgNr] OF WashPara;

Обращение к элементам структуры происходит через точку после указания элемента массива, например:

MyWashPara[i].WaterOut := T#5s;

Далее мы хотим связать длительность выполнения определенных шагов SFC со значениями элементов массива структур, так чтобы мы смогли динамически влиять на работу диаграммы, изменяя только значения переменных. Вероятно, понадобятся таймеры или даже массив таймеров. Все гораздо проще, используем уже знакомые нам атрибуты шагов, а именно минимальное время активности шага. Привязка элементов массива к

временам шага показана на рис. 1. Переходы после выполняемых по времени шагов всегда разрешены, то есть им присвоены константы TRUE. Этим собственно все программирование и исчерпывается.

Рис. 1. Временные атрибуты шагов SFC

 Для наглядной демонстрации работы нашей машины удобно использовать встроенную графическую визуализацию CoDeSys. Ее возможный вариант показан на рис. 2.

 

Рис. 2. Визуализация модели

Наша визуализация слишком уж статична, хотелось бы отобразить вращение барабана. Это можно сделать при помощи закрашенного сегмента. Напишем отдельную программу Motor, ее задача плавно циклически изменять переменную wAngle от 0 до 360 градусов, которую мы свяжем с углом сектора соответствующего элемента визуализации. Например, так:

IF xMotOn THEN

wAngle := wAngle + 5;

IF wAngle > 359 THEN

wAngle := 0;

END_IF

ELSE

wAngle := 180;

END_IF

Как видите, здесь нет таймеров, обеспечивающих достаточно медленную для зрительного восприятия скорость вращения барабана. Мы можем поступить проще, создадим для целей моделирования циклическую задачу с достаточно медленным циклом работы, который легко регулировать. После отладки эту задачу можно будет просто отключить, не изменяя ничего в основных программах. По умолчанию CoDeSys создает новый проект с единственной программой PLC_PRG, которая неявно включена в единственную циклическую задачу. Чтобы сделать многозадачный проект, необходимо использовать конфигуратор задач (Task configuration), расположенный на вкладке ‘Ресурсы’ менеджера проектов. Щелкните правой кнопкой мыши по элементу Task configuration и в появившемся контекстном меню выберете команду Append task. Сначала создадим главную задачу, она будет назваться Main, ее тип – циклический (cyclic) и интервал работы T#10ms. Аналогичным способом откройте контекстное меню для нашей новой задачи и добавьте в нее (Append program call) программу PLC_PRG();. Теперь создайте еще одну циклическую задачу MotorSim с интервалом T#100ms, в нее вставьте вызов программы Motor();. Теперь конфигурация задач должна выглядеть так, как показано на рис.3.

Рис.3. Конфигурация задачи

Настройка ПЛК для работы через GSM-модем по протоколу Modbus TCP в режиме Slave

Чтобы настроить работу ПЛК1хх по протоколу Modbus TCP в режиме Slave, необходимо:

1. Подключить модем ПМ01 к ПЛК по одному из последовательных портов, в соответствии с руководством по эксплуатации, установив необходимые перемычки на модеме (В случае RS-232 обязательно перемычка 6-9 на разъеме модема Х1). Схемы кабелей и рекомендации можно найти в разделе «часто задаваемые вопросы» для GSM/GPRS модема ПМ01: http://www.owen.ru/catalog/74944685

2. В среде программирования Codesys2.3,перейти в область PLC_Configuration(Конфигурация_ПЛК) и добавить там модуль Modbus(Slave)(рис.1).

3. Задать адрес в сети Modbus для ПЛК, параметр «Address» модуля «Modbus(slave)» вкладка «Module parameters» (рис.1).

Рис.1 Настройка адреса ПЛК в режиме Slave

4. К появившемуся подмодулю «Modbus[FIX]» добавить подмодуль «Modem» (выделить подмодуль «Modbus[FIX]», нажать правую клавишу мыши и через контекстное меню выделить «Append Subelement» и далее «Modem…») и настроить его на вкладке «Module parameters»1 как показано на рис.2. Подробнее о параметрах модуля Modem см. в документе «PLC_Configuration.pdf» на диске ПЛК в разделе Документация

Рис.2 Добавление и настройка подмодуля «Modem»

5. Выбрать интерфейс, через который GSM-модем подключен к ПЛК, заменив интерфейс, установленный по умолчанию, с помощью правой кнопки мыши.

6. Установить параметры выбранного интерфейса в соответствии с настройками модема, на вкладке «Module parameters»(рис.3).

Рис.3 Настройка интерфейса обмена ПЛК и модема (приведен для стандартных настроек GSM-модема ПМ01)

7. Добавить к подмодулю «Modem» подмодуль «PPP_Driver» (выделить подмодуль «Modem[VAR]», нажать правую клавишу мыши и через контекстное меню выбрать «Append PPP_Driver»), рис.4. Настроить его на вкладке «Module parameters» задав параметры «Login» и «Password», необходимые для дозвона до провайдера-поставщика Интернет услуг (предоставляются поставщиком GSM-услуг). Подробнее о параметрах подмодуля «PPP_Driver» см. в документе «OWEN_PLC_Configuration.pdf».

8. К подмодулю «Modbus(Slave)» добавить подмодуль «TCP[VAR]» (выделить подмодуль «Modbus[FIX]», нажать правую клавишу мыши и через контекстное меню выбрать «Append Subelement», а затем «TCP…»), рис.4, на вкладке «Module parameters» модуля «TCP[VAR]» параметр «RemotePort» должен быть равен 502.

9. Добавить к модулю «Modbus(slave)» необходимые переменные, например «2 byte» (выбрать модуль «ModBus (slave)», нажать правую клавишу мыши, через контекстное меню выбрать «Append Subelement», а потом «2 byte…»),рис.4.

Рис.4 Конфигурация ПЛК100 для обмена по GPRS, с подключенным модемом к порту Debug

После этого можно привязывать пользовательскую программу к объявленной в конфигурации переменной.

10.Установить связь с ПЛК командой Online|│Login, при этом программу в ПЛК можно не изменять.

11.В подключенном состоянии, перейти в область PLC_Browser (ПЛК-Браузер) и задать настройки TCP/IP подключения для контроллера, соответствующие настройкам используемой в GSM-модеме SIM-карты:

a. SetIP XXX.XXX.XXX.XXX

b. SetGATE XXX.XXX.XXX.XXX

c.SetMASK XXX.XXX.XXX.XXX

Рис.5 Сетевые настройки ПЛК, работа через ПЛК-Браузер

12.Создать файл инициализации модема с именем «extconf.cfg» с адресом «точки доступа» (даётся провайдером сотовой связи). Для этого можно воспользоваться стандартным текстовым редактором Windows – «Блокнот».

Пример файла инициализации для SIM-карты Beeline со статическим IP-адресом:

AT+CGATT=1

AT+CGDCONT=1,»IP»,»static.beeline.ru»

AT

Рекомендуем файл инициализации заканчивать командой «AT».

13. Перед загрузкой файла, проверить отсутствует ли старый файл инициализации в ПЛК, а так же файлы CoDeSys.cfg и modem.cfg (Последние задают настройки удаленного подключения Codesys к ПЛК и имеют приоритет над настройками в ПЛК_Конфигурации, что может мешать работе совпадающих последовательных портов).

Рис.6 Проверка отсутствия файлов модема

14.Загрузить созданный файл инициализации модема «extconf.cfg», Online|│Write file to PLC.

15.После Задания настроек TCP и загрузке файла инициализации, необходимо перезагрузить ПЛК нажав кнопку «Cброс».

16.Спустя 15 секунд, после перезагрузки, повторно установить связь с ПЛК командой Online|│Login и загрузить созданную программу в ПЛК

17.В области конфигурации, подключением к GPRS можно управлять и контролировать с помощью специальных байт (рис.7). Время подключения к серверу, интервалы между дозвонами и кол-во дозвонов до GSM-сервера задаётся на вкладке «Module parameters» подмодуля modem.

Рис.7 Байты управления модемом, статус: «подключен по GPRS»

18.Удаленно проверить подключение ПЛК к сети Интернет с помощью «ping» в командной строке Windows, подключенного к Интернет ПК.

Например, «ping 83.220.242.28 –t» результат на рис.8.

Рис.8 Проверка подключения ПЛК к сети интернет через GPRS

Мой блог находят по следующим фразам

Аппаратные часы времени в CoDeSys

Пример работы с аппаратными часами реального времени с помощью библиотеки syslibtime. Получение данных о текущем времени и изменение времени из программы.

 

PROGRAM PLC_PRG                      (*PLC100 RL core 2-07-2 target 2-05-7*)

VAR

GetTime: CurTimeEx;

TimeAndDate: SystemTimeDate;

Sys_Time: SysTime64;

set_time: BOOL;

END_VAR

 

IF set_time THEN

 

TimeAndDate.Minute;

TimeAndDate.Second;

TimeAndDate.Hour;

GetTime (SystemTime:=Sys_Time , TimeDate:= TimeAndDate);

ELSE

 

TimeAndDate.Day :=0;

TimeAndDate.DayOfWeek :=0;

TimeAndDate.dwHighMsec :=0;

TimeAndDate.dwLowMSecs :=0;

TimeAndDate.Milliseconds :=0;

TimeAndDate.Minute :=0;

TimeAndDate.Second :=0;

TimeAndDate.Hour :=0;

TimeAndDate.Year :=0;

TimeAndDate.Month :=0;

Sys_time.ulHigh :=0;

Sys_time.ulLow :=0;

GetTime (SystemTime:=Sys_Time , TimeDate:= TimeAndDate);

END_IF

 

Мой блог находят по следующим фразам

Эмулятор ОВЕН ТРМ1

ПЛК100 (Master) + ИП320 (Slave) + МВА8 (Slave)

Эмулятор ТРМ1

 

 

Задача:

1)      Эмуляция работы ТРМ1

2)      Опрос входа МВА (получение температуры)

3)      Обработка в контроллере данных, полученных с МВА

4)      Передача данных на панель для отображения температуры

5)      Установка уставки, гистерезиса и режима работы с панели

6)      Контроллер работает в качестве мастера

Решение задачи

1)     Сетевые параметры

— Контроллер  — Мастер

— Адрес Панели Оператора ИП320 – 1

— Адрес Модуля Ввода  МВА8 – 16

 

2)     Регистры для обмена данными в сети

 

Имя переменной Адрес Регистра Назначение
Параметры для обмена с МВА8
T_MVA 1 Опрос температуры с МВА в целочисленном формате со сдвигом 2 знака
Параметры для обмена с ИП320
T_IP_TX 5 Передача в панель температуры в целочисленном формате со сдвигом 2 знака для отображении в численном виде
T_IP_GR 6 Передача в панель температуры в целочисленном формате без сдвига для вывода на график
Ust 7 Регистр для вывода уставки в панель в целочисленном формате, со сдвигом 2 знака
Ust_inp 8 Регистр для получения нового значения уставки с панели в целочисленном формате, со сдвигом 2 знака
Gist 9 Регистр для вывода гистерезиса в панель в целочисленном формате, со сдвигом 2 знака
Gist_inp 10 Регистр для получения нового значения гистерезиса с панели в целочисленном формате, со сдвигом 2 знака
Rejim 11 Регистр для вывода режима работы котроллера (нагреватель — холодильник)
Rejim_inp 12 Регистр для получения нового режима работы котроллера (нагреватель — холодильник)
Rele_b 13 Регистр для чтения статуса индикатора выходного реле
screen 15 Регистр для получения текущего номера экрана панели
Screen_in 16 Регистр для сметы текущего экрана панели
auto 17 Регистр разрешения автоматического переключения экранов панели
Параметры для обмена с ИП320 (для инициализации панели)
U_ret 8 Запись в панель уставки из энергонезависимой памяти
G_ret 10 Запись в панель гистерезиса из энергонезависимой памяти
R_ret 12 Запись в панель режима работы из энергонезависимой памяти

 

3)     Описание Экранов и назначения клавиш панели ИП320

Основное назначение панели – это вывод температуры на экран и установка параметров работы эмулятора ТРМ1. В качестве примера была взята упрощенная модель работы ТРМ1. Модель предполагает, что ТРМ1 работает в двух режимах – прямой гистерезис и обратный. Для реализации этих двух режимов необходимо задавать уставку, гистерезис и сам режим работы ТРМ1.

При подачи питания на контроллер, в контроллере ПЛК запускается алгоритм инициализации панели, данные для которой хранятся в энергонезависимой памяти контроллера.

В панели ИП 320 реализованы 4 экрана:

Базовый — для вывода основных параметров работы прибора

Установка параметров — для задания уставки и гистерезиса

Установка режима работы — для выбора режима работы ТРМ1

График — для вывода температуры в виде графика

 

Подробное описание экранов и работы с ними:

Рис.1 Базовый экран

 

Базовый:

 

Данный экран предназначен для просмотра измеряемой температуры, вывода графика и вывода текущих значений уставки и гистерезиса. Также индикатор отображает состояние выходного реле. Данный экран не позволяет менять параметры.

Все параметры читаются из регистров указанных на рисунке 1. Индикатор соответствует логическому состоянию регистра 13 бита 0 (соответствует биту 208). Динамический текст выводится в соответствии с содержимым регистра 13, в данном регистре используется только 0-й бит, который может находиться в 2-х состояниях TRUE и False – что будет соответствовать числам 1 и 0 в десятичной системе счисления (в зависимости от этого значения в панели задается выводимый текст).

С помощью кнопки  8 можно перейти в режим автоматического переключения экранов панели. Экраны переключаются ПЛК циклически, в том случае если в регистре 17 бит 0 (соответствует буту 272) равен 1. Кнопка 8 работает в реверсивном режиме, то есть при каждом нажатии заданный бит меняется на противоположное состояние (0 либо 1).

При нажатии на кнопку 9 происходит переход на экран дата-время, выход с этого экрана осуществляется нажатием кнопки ESC.

Установка параметров:

 

 

Рис. 2 Экран установки параметров

Экран установки параметров предназначен для задания значений уставки и гистерезиса. На экране отображаются четыре числовых значения. Значения, которые находятся напротив “OLD” являются текущими, и отображают реальные значения уставки и гистерезиса. Значения, которые стоят напротив “NEW” предназначены для ввода новых значений уставки и гистерезиса. Редактируемые значения защищены паролем, и их редактирование запрещено.

Для разрешения записи новых значений необходимо перейти на экран пароля и выбрать меню “Открыть доступ”. Далее откроется экран ввода пароля, в котором необходимо будет ввести пароль с помощью стрелок на панели (пароль 11).

После открытия доступа кнопкой SET можно выбрать редактируемый параметр (из группы NEW) и ввести его новое значение, после чего нажать кнопку ENT, чтобы его записать. Через небольшой промежуток времени в группе NEW отобразится новое введенное значение.

Запись новых значений реализуется путем записи нового значения из регистров Input  в регистры Output.

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

Как и в базовом экране, кнопка 8 включает, или выключает автопрокрутку экранов.

Установка режима работы:

Рис. 3 Экран установки режима работы

Данный экран позволяет установить режим работы ТРМ1 нажатием кнопок 0 или 1 на панели оператора. Режим работы при нажатии на данные клавиши будет меняться в том случае, если на экране пароля был открыт доступ, в противном случае кнопки будут не функциональны. После Выбора режима путем нажатия соответствующей кнопки на экран будет выведен номер текущего режима.

Переход на экран пароля осуществляется при помощи кнопки +/-.

Кнопка 8 включает или отключает автопрокрутку экранов.

Рис. 4 Экран график

График:

Экран графика представляет, выводит график температуры, но в более крупном масштабе, чем на экране 1 (Базовый).

Кнопкой 8 включается автоматическая прокрутка экранов.

Параметры настройки панели:

 

Рис. 5 Настройки панели

В настройках проекта конфигуратора ИП320 необходимо задать пароль для ввода его на экране пароля. Также указывается номер регистра для работы с экранами панели.

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

Список тревог

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Рис. 6 Список тревог

 

Температурный график с заданием от панели

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

Функциональный блок экспортирован, для вставки в проект необходимо сделать импорт.

FUNCTION_BLOCK Graph_Temp

VAR_INPUT

Temp_in:REAL;    (*Температура наружнего воздуха*)

Temp_NV_A:WORD;         (*температура воздуха первой точки графика (с панели)*)

Temp_NV_B:WORD;         (*температура воздуха второй точки графика (с панели)*)

Temp_otopl_A:WORD;         (*температура отопления , первая точка графика (с панели)*)

Temp_otopl_B:WORD;         (*температура отопления , вторая точка графика (с панели)*)

tmp_N: WORD;  (*снижение температуры ночью на Х градусов (с панели)*)

In_night_on: BOOL; (*разрешение включения ночного режима*)

time_night_in: BOOL; (*время включения ночного режима настало*)

END_VAR

VAR_OUTPUT

Zad: REAL;           (*вычисленное по графику задание температуры отопления*)

END_VAR

VAR

koef1:REAL;          (*коэффициент уравнения прямой*)

Temp_otopl_B_: REAL;

Temp_otopl_A_: REAL;

Temp_NV_A_: REAL;

Temp_NV_B_: REAL;

tmp_N_: REAL;

zad_N: REAL; (*снижение задания на ночное время*)

zad_G: REAL; (*задание по графику*)

END_VAR

Temp_otopl_B_:=WORD_TO_REAL(Temp_otopl_B)/10; (*преобразование форматов данных полученных с ИП320*)

Temp_otopl_A_:=WORD_TO_REAL(Temp_otopl_A)/10;

Temp_NV_A_:=WORD_TO_REAL(Temp_NV_A)/10;

Temp_NV_B_:=WORD_TO_REAL(Temp_NV_B)/10;

tmp_N_:=WORD_TO_REAL(tmp_N)/10;

koef1 :=  (Temp_otopl_B_ — Temp_otopl_A_)/(Temp_NV_B — Temp_NV_A_)  ; (*коэфициенты уравнения*)

(*формирование графика*)

IF (Temp_in >= Temp_NV_A_) THEN

zad_G := Temp_otopl_A_;

END_IF

IF ((Temp_in <Temp_NV_A_) AND (Temp_in >=Temp_NV_B)) THEN

zad_G := Temp_otopl_A_ + koef1 * (Temp_in — Temp_NV_A_);

END_IF

IF (Temp_in <Temp_NV_B) THEN

zad_G := Temp_otopl_B;

END_IF
(*формирование ночного графика*)

IF (In_night_on=TRUE AND time_night_in=TRUE AND (zad_G- tmp_N_<= zad_G-zad_N) ) THEN

zad_N:= zad_N +0.00001;

END_IF

(*снижение и увеличение температуры происходит со скоростью 0.2-0.3 градуса в минуту и зависит от цикла ПЛК, кому не нравиться переписывайте на внешнее время*)

IF (In_night_on=TRUE AND time_night_in=FALSE AND zad<=zad_G  ) THEN

zad_N:= zad_N -0.000001;

END_IF
(*общее формирование задания*)

IF In_night_on=TRUE THEN

zad:=zad_G-zad_N;

ELSE

zad:=zad_G;

zad_N:=0;

END_IF

END_FUNCTION_BLOCK

Управление 3 насосами

Алгоритм предназначен для управления 3-мя насосами (или другими обьектами требующими чредование времени работы,например тремя водогрейными котлами),  каждый из которых снабжен своим датчиком   (или иным сигналом обратной связи). Одновременно работают два объекта из трех. По истечении  заданного времени  происходит переключение работающих  насосов.

Листинг

VAR_INPUT

Run: BOOL; (*сигнал начала работы программы ротации*)

Time_Rotat_in:WORD; (*время работы насосов, в часах*)

Time_zad_on_in: WORD; (*время задержки перед началом работы алгоритма , в секундах*)

Time_Nech_in: WORD; (*время, в течение которого при запуске двигателя насоса  не анализируются показания датчика давления, в секундах*)

Time_Nech_on_work_in: WORD; (*время, в течение которого при работе двигателя насоса допускаются «провалы» показаний датчика давления, в секундах*)

Time_Zad_in: WORD; (*время задержки между отключением одного насоса и включением другого, в секундах*)

p1_on: BOOL; (*сигнал обратной связи (датчик давления, контакт пускателя итд.) насоса №1*)

p2_on: BOOL; (*сигнал обратной связи (датчик давления, контакт пускателя итд.) насоса №2*)

p3_on: BOOL; (*сигнал обратной связи (датчик давления, контакт пускателя итд.) насоса №3*)
END_VAR

VAR_OUTPUT

p1_out: BOOL; (*сигнал включения насоса №1*)

p2_out: BOOL; (*сигнал включения насоса №2*)

p3_out: BOOL; (*сигнал включения насоса №3*)

err_p1: BOOL; (*авария насоса №1*)

err_p2: BOOL; (*авария насоса №2*)

err_p3: BOOL; (*авария насоса №3*)

END_VAR

VAR

i: WORD; (*переменная которая определяет запуск насосов*)

Time_zad_on: TIME; (*время задержки перед началом работы алгоритма*)

Time_Nech: TIME; (*время, в течение которого при запуске двигателя насоса  не анализируются показания датчика давления;*)

Time_Nech_on_work: TIME; (*время, в течение которого при работе двигателя насоса допускаются «провалы» показаний датчика давления*)

Time_Zad: TIME; (*время задержки между отключением одного насоса и включением другого*)

Time_rotat: TIME;  (*время работы насосов*)

Tim_off: BOOL;

Trig1: R_TRIG;

C_Tim: TON; (*таймер чредования насосов*)

Time_Rotat_DW: DWORD;

p1_out_: BOOL;

p2_out_: BOOL;

p3_out_: BOOL;

TON_Zad_Pump1: TON;

TON_Pump1_Nech: TON;

Run_Pump: BOOL;

Run_Trig: R_TRIG;

Sbros_Trig: F_TRIG;

TOF_Pump1_Nech: TOF;

TON_Zad_Pump2: TON;

TON_Pump2_Nech: TON;

TOF_Pump2_Nech: TOF;

TON_Zad_Pump3: TON;

TON_Pump3_Nech: TON;

TOF_Pump3_Nech: TOF;

T_zad2: TIME; (*задержка включения второго насоса при холодном старте*)

END_VAR

(*преобразование переменных времени полученых с панели *)

Time_Rotat_DW:=WORD_TO_DWORD(Time_Rotat_in);(*перевод в часы*)

Time_rotat:=DWORD_TO_TIME((Time_Rotat_DW*3600000)/2);

Time_zad_on:=WORD_TO_TIME(Time_zad_on_in*1000); (*перевод в секунды*)

Time_Nech:=WORD_TO_TIME(Time_Nech_in*1000);

Time_Nech_on_work:= WORD_TO_TIME(Time_Nech_on_work_in*1000);

Time_Zad:=WORD_TO_TIME(Time_Zad_in*1000);(*инициализация и востановление начальных условий*)

IF Run=TRUE THEN

Run_Trig(CLK:=TRUE);

Sbros_Trig(CLK:=TRUE) ;

ELSE

Run_Trig(CLK:=FALSE);

Sbros_Trig(CLK:=FALSE);

END_IF

IF Run_Trig.Q=TRUE THEN

Run_Pump:=TRUE;

T_zad2:=T#5s;

END_IF

IF  Trig1.Q=TRUE THEN

T_zad2:=T#0s ;

END_IF

IF Sbros_Trig.Q= TRUE THEN

err_p1:=FALSE;

err_p2:=FALSE;

err_p3:=FALSE;

END_IF

(*запуск таймера ротации насосов*)

IF Run_Pump=TRUE  THEN

C_Tim(IN:=TRUE , PT:=T#1m );

END_IF

(*сброс таймера ротации насосов*)

IF Run_Pump =FALSE THEN

C_Tim(IN:=FALSE , PT:=T#0s );

END_IF

(*детектирование импульса перехода с насоса на насос*)

Trig1(CLK:= C_Tim.Q );

Tim_off:=Trig1.Q;

(*востановление начальных установок, если идет холодный старт в автомате*)

IF (Run_Pump=FALSE AND (p3_on= FALSE  AND p1_on=FALSE AND p2_on=FALSE)) THEN

i:=0;

END_IF

IF Run=FALSE THEN

p1_out_:= FALSE;

p2_out_:=FALSE;

p3_out_:=FALSE;

Run_Pump:=FALSE;

END_IF

(*подхват насосов на «лету»*)

IF (Run_Pump=FALSE AND (p1_on= TRUE AND p2_on=TRUE)) THEN

i:=0;

END_IF

IF (Run_Pump=FALSE AND (p2_on= TRUE AND p3_on=TRUE)) THEN

i:=2;

END_IF

IF (Run_Pump=FALSE AND (p3_on= TRUE AND p1_on=TRUE)) THEN

i:=1;

END_IF

(*счетчик*)

IF (Tim_off=TRUE AND Run_Pump=TRUE ) THEN

i:=i+1;

END_IF

IF i>=3 THEN

i:=0;

END_IF

(*включение насосов*)

IF (Run_Pump=TRUE AND i=0) THEN

p1_out_:= TRUE;

p2_out_:=TRUE;

p3_out_:=FALSE;

END_IF

IF (Run_Pump=TRUE AND i=1) THEN

p1_out_:= TRUE;

p2_out_:=FALSE;

p3_out_:=TRUE;

END_IF

IF (Run_Pump=TRUE AND i=2) THEN

p1_out_:= FALSE;

p2_out_:=TRUE;

p3_out_:=TRUE;

END_IF

(*перезапуск таймера*)

IF (Run_Pump=TRUE AND Tim_off=TRUE) THEN

C_Tim(IN:=FALSE , PT:=T#1m );

END_IF

(*управление насосами*)

(*насос №1*)

IF p1_out_=TRUE THEN

TON_Zad_Pump1(IN:=TRUE , PT:=Time_Zad );

ELSE

TON_Zad_Pump1(IN:=FALSE , PT:=Time_Zad );

END_IF

IF (TON_Zad_Pump1.Q=TRUE AND err_p1=FALSE) THEN

p1_out:=TRUE;

END_IF (*формирование задержки включения и защиты от ошибочного включения*)

IF (p1_out_=TRUE AND p1_out=TRUE) THEN

TON_Pump1_Nech(IN:=TRUE , PT:=Time_Nech );

ELSE

TON_Pump1_Nech(IN:=FALSE , PT:=Time_Nech );

END_IF

(*задержка контроля обратной связи после пуска насоса*)

IF  (p1_out=TRUE AND p1_on=FALSE) THEN

TOF_Pump1_Nech(IN:=FALSE, PT:=Time_Nech_on_work);

ELSE

TOF_Pump1_Nech(IN:=TRUE, PT:=Time_Nech_on_work);

END_IF

(*задержка при пропадании сигнала обратной связи при работе насоса*)

IF (Run=TRUE AND p1_out_=TRUE AND  TON_Pump1_Nech.Q=TRUE AND p1_on=FALSE AND TOF_Pump1_Nech.Q=FALSE) THEN

err_p1:=TRUE ;

Run_Pump:=FALSE ;

p1_out:=FALSE;

p2_out_:=TRUE;

p3_out_:=TRUE;

END_IF

(*определение аварии насоса, производиться остановка ротации и принудительное включение оставшихся насосов*)

IF p1_out_=FALSE THEN

p1_out:=FALSE;

END_IF

(*остановка насоса по истесению времени или аварии*)

(*насос №2*)

IF p2_out_=TRUE THEN

TON_Zad_Pump2(IN:=TRUE , PT:=Time_Zad+T_zad2 );

ELSE

TON_Zad_Pump2(IN:=FALSE , PT:=Time_Zad );

END_IF

(*здесь все тоже самое*)

IF (TON_Zad_Pump2.Q=TRUE AND err_p2=FALSE) THEN

p2_out:=TRUE;

END_IF

IF (p2_out_=TRUE AND p2_out=TRUE) THEN

TON_Pump2_Nech(IN:=TRUE , PT:=Time_Nech );

ELSE

TON_Pump2_Nech(IN:=FALSE , PT:=Time_Nech );

END_IF

IF  (p2_out=TRUE AND p2_on=FALSE) THEN

TOF_Pump2_Nech(IN:=FALSE, PT:=Time_Nech_on_work);

ELSE

TOF_Pump2_Nech(IN:=TRUE, PT:=Time_Nech_on_work);

END_IF

IF (Run=TRUE AND p2_out_=TRUE AND  TON_Pump2_Nech.Q=TRUE AND p2_on=FALSE AND TOF_Pump2_Nech.Q=FALSE) THEN

err_p2:=TRUE ;

Run_Pump:=FALSE ;

p2_out:=FALSE;

p1_out_:=TRUE;

p3_out_:=TRUE;

END_IF

IF p2_out_=FALSE THEN

p2_out:=FALSE;

END_IF

(*насос №3*)

IF p3_out_=TRUE THEN

TON_Zad_Pump3(IN:=TRUE , PT:=Time_Zad );

ELSE

TON_Zad_Pump3(IN:=FALSE , PT:=Time_Zad );

END_IF

IF (TON_Zad_Pump3.Q=TRUE AND err_p3=FALSE) THEN

p3_out:=TRUE;

END_IF

IF (p3_out_=TRUE AND p3_out=TRUE) THEN

TON_Pump3_Nech(IN:=TRUE , PT:=Time_Nech );

ELSE

TON_Pump3_Nech(IN:=FALSE , PT:=Time_Nech );

END_IF

IF  (p3_out=TRUE AND p3_on=FALSE) THEN

TOF_Pump3_Nech(IN:=FALSE, PT:=Time_Nech_on_work);

ELSE

TOF_Pump3_Nech(IN:=TRUE, PT:=Time_Nech_on_work);

END_IF

IF (Run=TRUE AND p3_out_=TRUE AND  TON_Pump3_Nech.Q=TRUE AND p3_on=FALSE AND TOF_Pump3_Nech.Q=FALSE) THEN

err_p3:=TRUE ;

Run_Pump:=FALSE ;

p3_out:=FALSE;

p2_out_:=TRUE;

p1_out_:=TRUE;

END_IF

IF p3_out_=FALSE THEN

p3_out:=FALSE;

END_IF

END_PROGRAM

Пожелания к работе программы и описание найденных ошибок можно направлять по адресу a_vit76@mail.ru Автор — Виктор Алексеев

График с заданием точек элементами массива

Пример: график уставки по пяти точкам. Каждая из координат задается массивом из 5 элементов, которые сначала сортируются по возрастанию, а затем по ним определяется уставка регулирования.

При выходе за пределы линейной зависимости выходная переменная принимает значение  крайних точек зависимости.

Листинг

FUNCTION_BLOCK obr_gr (*сортировка элементов массивов по возрастанию*)

VAR_INPUT

x,y:ARRAY[1..5] OF REAL;

END_VAR

VAR_OUTPUT

x1,y1:ARRAY[1..5] OF REAL;

END_VAR

VAR i: INT;

xp,yp: REAL;

END_VAR

FOR i:=1 TO 4 DO

IF x[i+1]<x[i] THEN

xp:=x[i];

x[i]:=x[i+1];

x[i+1]:=xp;
yp:=y[i];

y[i]:=y[i+1];

y[i+1]:=yp;
END_IF;

END_FOR;
FOR i:=1 TO 5 DO

x1[i]:=x[i];

y1[i]:=y[i];

END_FOR;

FUNCTION_BLOCK opr_ust

VAR_INPUT

x,y:ARRAY[1..5] OF REAL; (*массивы входных значений*)

vh_znach:REAL; (*сигнал с датчика*)

END_VAR

VAR_OUTPUT

ust:REAL; (*требуемая уставка регулирования*)

END_VAR

VAR

i: INT;

k: REAL;

END_VAR

FOR i:=1 TO 4 DO;

IF (x[i+1]>vh_znach) AND (x[i]<vh_znach) THEN

k:=(y[i+1]-y[i])/(x[i+1]-x[i]);

ust:=y[i]+k*(vh_znach-x[i]);

END_IF;

END_FOR;

Простой график в CoDeSys

Простейший пример: график уставки по двум точкам. При желании по аналогии можете сделать столько точек, сколько вам нужно.

x1, y1 — координаты первой точки

x2, y2 — координаты второй точки
При выходе за пределы линейной зависимости выходная переменная принимает значение или y1, или y2.

Листинг:

FUNCTION_BLOCK graph

VAR_INPUT

par:REAL;            (*входной параметр*)

x1, y1:REAL;         (*координаты первой точки*)

x2, y2:REAL;         (*координаты второй точки*)

END_VAR

VAR_OUTPUT

zad: REAL;           (*задание, определенное по графику*)

END_VAR

VAR

koef1:REAL;          (*коэффициент уравнения прямой*)
END_VAR

koef1 := (y2 — y1) / (x2 — x1);
IF (par <= x1) THEN

zad := y1;

END_IF;
IF ((par > x1) AND (par < x2)) THEN

zad := y1 + koef1 * (par — x1);

END_IF;
IF (par >= x2) THEN

zad := y2;

END_IF;

Работа с таймерами на языке ST

Пример работы с дискретными входами и выходами ПЛК, а также с таймерами ton и tof. Пример на языке ST.

При замыкании первого входа замыкается первый выход.

При замыкании первого и второго входа замыкается второй выход.

Через 5 секунд после замыкания третьего входа замыкается третий выход.

Через 10 секунд после размыкания четвертого входа размыкается четвертый выход.

Листинг:

PROGRAM PLC_PRG

VAR

tim1:TON;

tim2:TOF;

END_VAR

(*plc100-24.K-L core 2-03 target 2-02-4*)

out1:=in1;

Out2:=in1 AND in2;

(*задержка включения*)

tim1(IN := in3, PT := T#5s);

out3:=tim1.Q;

(*задержка выключения*)

tim2(IN := in4, PT := T#10s);

out4:=tim2.Q;

Сетевые переменные в CoDeSys.

Данная операция имеет смысл, когда у Вас на одном объекте стоит несколько контроллеров, и необходимо обмениваться данными между этими контроллерами без создания дополнительного межсетевого обмена.

Необходимо помнить, что данная опция необходима, когда у нас на одном объекте как минимум 2 контроллера.

Обмен переменными может вестись только по интерфейсу Ethernet. (На данном этапе).

Пример создан на базе контроллера ПЛК150-220.И-L

Target 2-02.3

Переходим на вкладку Resources

Выбираем папку «Target settings», вкладку «Network functionality»

В строчке «Name of supported network interfaces» задаем в ручную – UDP

Во вкладке Resources выбираем вкладку «Library Manager» и добавляем библиотеку (правой кнопкой мыши в поле библиотек) – Additional Library.

Необходимо подключить следующие библиотеки:

SysLibCallback.lib

SysLibSockets.lib

NetVarUdp_LIB_V23.lib

Библиотеки вложены в архиве, либо на диске с ПЛК, либо на сайте ОВЕН.

Рекомендуется перед подключением перенести библиотеки в директорию, созданную CoDeSys, по умолчанию: c:Program Files3S SoftwareCoDeSys V2.3Library

Выбираем папку «Global variables»

Выбираем команду Add Object

Всплывает следующее окно.

В строчке «Name of the global list» задаем имя, например PRIMER.

!Важно:

  1. В обоих (нескольких) контроллерах имя данной папки должно быть идентичным.
  2. Регистр (большие или маленькие буквы) важен.

Далее в этом окне нажимаем на кнопку «Add network» — окно видоизменяется следующим образом:

Значение параметра «Network type» — необходимо выставить UDP. Вкладку Settings не редактируем.

Значение параметра  «List identifier (COB-ID)» так же должно быть общим для всех контроллеров, участвующих в обмене. Значение выставляется произвольно. Для примера – 1.

Далее ставим галочку у необходимого параметра.

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

Если выбраны Write – становятся доступными три последующие строчки, которые описывают по какому принципу необходимо передавать значение: «Циклически», «по изменению значения», «по команде».

!Важно: Рекомендуется не ставить галочки чтение и запись для одной и той же группы «PRIMER» в одном контроллере. То есть только в одном контроллере переменные одной папки должны быть Write, в остальных контроллерах типа Read.

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

После этого добавляем (объявляем) непосредственно во вновь созданной папке переменные, которые нам необходимы.

И уже в программе работаем с ними, как со стандартными глобальными переменными.