Приемы работы и примеры разработки пользовательских программ представлены
в документе «Первые шаги с CoDeSys V2.3» на сайте owen.ru.
Программные компоненты (POU)
Пользовательская программа создается в CODESYS на любом из доступных
языков программирования и может состоять из одного или нескольких
программных компонентов (POU).
К программным компонентам (POU) относятся:
-
программы;
-
функции;
-
функциональные блоки.
Отдельные POU могут включать действия (подпрограммы). Каждый программный
компонент состоит из раздела объявлений и кода. Для написания всего
кода POU используется только один язык программирования.
CODESYS поддерживает все описанные стандартом МЭК компоненты. Для
использования стандартных элементов достаточно включить в проект библиотеку standard.lib (подробнее о библиотеках см. раздел).
Программные компоненты могут вызывать другие программные компоненты,
но рекурсии недопустимы.
Главная программа, выполняемая циклически, должна называться PLC_PRG. В проекте могут быть определены несколько задач с различными
условиями выполнения. Работа с задачами описана в разделе «Конфигуратор
задач (Task Configuration)» документа «Руководство пользователя
по программированию ПЛК в CoDeSys V2.3».
Внимание
Если в окне «Конфигурация задач (Task Configuration)»
определена последовательность выполнения задач (см. раздел), то проект может не содержать PLC_PRG.
Нельзя удалять или переименовывать POU PLC_PRG в однозадачном проекте
– если не используется «Конфигурация задач (Task Configuration)».
В однозадачном проекте PLC_PRG является главной программой.
Программа
Программа – это программный компонент (POU), способный формировать
произвольное число значений во время вычислений. Значения всех переменных
программы сохраняются между вызовами. В отличие от функционального
блока, экземпляров программы не существует. Программа является глобальной
во всем проекте.
Программу нельзя вызывать из функции. Если вызвать программу, которая
изменит значения своих переменных, то при следующем вызове ее переменные
будут иметь те же значения, даже если она вызвана из другого POU,
что является главным различием между программой и функциональным блоком,
в котором изменяются только значения переменных данного экземпляра
функционального блока.
Список объявлений программы (в разделе объявлений окна редактирования)
начинается с ключевого слова PROGRAM и следующего за ним имени программы.
Функция
Функция – это программный компонент (POU), который возвращает только
единственное значение (которое может состоять из нескольких элементов,
если это битовое поле или структура). В текстовых языках функция вызывается
как оператор и может входить в выражения.
При объявлении функции следует указать тип возвращаемого значения
– после имени функции написать двоеточие и тип (см. рекомендации по
наименованию в приложении документа «Руководство пользователя по
программированию ПЛК в CoDeSys V2.3»). Правильно объявленная функция
выглядит следующим образом:
FUNCTION Fct: INT;
Имя функции используется как выходная переменная, которой присваивается
результат вычислений.
В функции, написанной на языке IL, используется три входных переменных
(par1–par3) целочисленного типа (INT, диапазон изменения
от –32768 до 32767) и возвращается результат деления произведения
первых двух на третью. Список объявлений функции в разделе объявлений
начинается с ключевого слова FUNCTION и следующего за ним имени функции,
за которым, отделенное двоеточием, указывается название типа возвращаемого
значения.
В языке ST вызов функции может присутствовать в выражениях как
операнд.
В языке SFC функция вызывается только из шага или перехода.
Примечание
Функция не имеет внутренней памяти, но CODESYS допускает
использование в функциях глобальных переменных, что является отклонением
от требований стандарта МЭК 61131-3, в соответствии с которыми выходное
значение функции должно зависеть исключительно от входных параметров.
Другими словами, функция с одними и теми же значениями входных параметров
всегда должна возвращать одно и то же значение.
Функциональный блок
Функциональный блок – это программный компонент (POU), который
принимает и возвращает произвольное число значений. В отличие от функции,
функциональный блок не формирует возвращаемое значение. Список всех
объявлений функционального блока в разделе объявлений начинается с
ключевого слова FUNCTION_BLOCK и следующего за ним имени блока.
Функциональный блок может имеет один или несколько экземпляров
(копий).
IL
В примере функциональный блок, написанный на языке
IL, имеет две входных и две выходных переменных. Значение выходной
переменной MULERG равно произведению значений двух входных переменных,
значение VERGL определяется в результате сравнения значений входных
переменных.
Переменные
Программные компоненты (POU) проекта обрабатывают переменные –
величины, значения которых могут меняться в ходе выполнения пользовательской
программы (в частных случаях переменные, обрабатываемые пользовательской
программой, могут быть и константами). Переменные могут использоваться
для хранения и передачи промежуточных результатов выполнения логических
операций, значений состояний входов или выходов функциональных блоков
программы, значений состояний входов или выходов ПЛК и др. Каждая
переменная имеет идентификатор.
Типы переменных
Переменные в CODESYS могут принадлежать к нескольким типам.
Переменные могут быть:
-
локальные – используются только в рамках текущего программного
компонента и задаются в разделе объявлений (см. раздел); -
глобальные – используются в рамках всего проекта (во
всех программных компонентах, входящих в его состав) и задаются в
разделе объявлений, вызываемом выбором объекта «Глобальные переменные»
(Global Variables) на вкладке «Ресурсы» организатора объектов.
Переменные также могут относиться к входным или выходным, а также одновременно к входным и выходным.
Если необходимо сохранять значения переменных, то их можно объявить
как перманентные переменные – такие переменные сохраняют свои
значения при определенных сбоях в системе. Перманентные переменные
бывают сохраняемые и постоянные.
Сохраняемые переменные обозначаются во время объявления ключевым
словом RETAIN. RETAIN-переменные сохраняют свои значения, даже если
произошла авария питания (выключение и включение) контроллера, что
равносильно команде «Сброс» (Онлайн → Сброс). Значения RETAIN-переменных
сохраняются в энергонезависимой памяти контроллера.
Примечание
Переменные, объявленные в окне «Конфигурация ПЛК»
в подэлементе «ModBus (slave)», являются сохраняемыми RETAIN-переменными.
Сохраняемая RETAIN-переменная
VAR RETAIN
rTemperature: REAL; (* Сохраняемая RETAIN-переменная *)
END_VAR
Контроллеры с версией ПО 1.0.х поддерживают следующие режимы работы
с энергонезависимой памятью:
-
запись по событию (используется по умолчанию) – RETAIN-переменные
записываются автоматически по сигналу об отключении питания контроллера.
Для записи используется накопленная энергия конденсаторов источника
питания ПЛК;Внимание
RETAIN-переменные не сохраняются
в следующих случаях:-
срабатывание сторожевого таймера (WatchDog);
-
перезагрузка контроллера по команде из пользовательской программы
или ПЛК браузера («PLC-Browser»).
В энергонезависимой памяти контроллера остаются значения,
записанные ранее. -
-
циклическая запись – RETAIN-переменные записываются
циклично. Период устанавливается пользователем в пределах от 1 до
1000 секунд. Для надежности запись ведется поочередно в две копии
RETAIN-переменных. В режиме циклической записи рекомендуется использовать
цикл ПЛК не менее 10 мс, так как запись RETAIN-переменных вызывает
дополнительную нагрузку на процессор контроллера.
Узнать или изменить активный режим работы с энергонезависимой памятью
можно в ПЛК-Браузере («PLC-Browser») с помощью специальных команд:
-
SetupRetainMode – просмотр активного режима работы с
RETAIN-переменными; -
SetCyclicMode XXX – выбор режима циклической записи,
где XXX – значение периода в секундах от 1 до 1000; -
SetCyclicMode 0 – отключение режима циклической записи
и переход к режиму записи по сигналу о пропадании питании контроллера.
Примечание
Для применения настроек режима работы с энергонезависимой
памятью следует перезагрузить ПЛК по питанию или командой rebooT.
Подробная информация и примеры проектов доступны в описании библиотеки
RetainControlLib в разделе CODESYS
V2 на сайте owen.ru.
Постоянные переменные обозначаются ключевым словом PERSISTENT.
В отличие от сохраняемых переменных постоянные переменные сохраняют
свои значения только в случае загрузки кода новой пользовательской
программы, но не в случае выключения питания или сброса. Значения
постоянных переменных размещаются вне энергонезависимого ОЗУ.
Подробнее о типах переменных см. Руководство пользователя по
программированию ПЛК в CoDeSys V2.3.
Объявление переменных
Для использования в POU переменная должна быть объявлена. Объявление переменных производится в разделе объявлений (см. раздел). Синтаксис, используемый при объявлении
переменных, соответствует стандарту МЭК 61131-3.
Раздел объявлений используется для объявления переменных POU, глобальных
переменных, описания типов данных.
В разделе объявлений зарезервированные слова, типы данных и сами
переменные автоматически подсвечиваются разными цветами.
Наиболее важные команды можно найти в контекстном меню, которое
появляется по щелчку ПКМ или по нажатию сочетания клавиш Ctrl +
F10.
Локальные переменные POU объявляются в разделе объявлений редактора
программного компонента. Локальными переменными могут быть входные
и выходные переменные, переменные, одновременно являющиеся входными
и выходными, локальные переменные, сохраняемые переменные и константы.
POU)
Методы объявления переменных
В CODESYS применяются следующие методы объявления переменных:
-
текстовый;
-
табличный;
-
автоматический.
Текстовый
Синтаксис объявления переменных
текстовым методом (наименования заключены в квадратные скобки):
<Идентификатор> {AT <Адрес>}:<Тип> {:=<начальное значение>};
Имена переменных не должны содержать пробелов и специальных символов,
должны объявляться только один раз и не должны совпадать с зарезервированными
словами. Регистр букв в имени переменной не имеет значения (т. е.
переменные Var1, VAR1 и var1 не различаются). В именах переменных
важен знак подчеркивания: переменные A_BCD и AB_CD считаются разными.
Идентификатор не должен содержать подряд более одного символа подчеркивания.
Длина идентификатора не ограничена, все символы являются значимыми.
Все переменные и типы данных можно инициализировать с помощью
оператора «=». Переменные простейших типов инициализируются константами.
По умолчанию все переменные инициализируются нулем.
iVar1:INT:=12; (*Переменная типа INT, инициализируемая числом 12*)
Если требуется поместить переменную по определенному адресу, то
следует объявить ее с ключевым словом AT.
Внимание
Не рекомендуется использовать прямую адресацию при помощи ключевого
слова АТ. Для прямой адресации компилятор не проверяет за пользователем
область памяти, на которую он ссылается при объявлении переменной.
Переменным, размещаемым в области конфигурации ПЛК, следует присваивать
имена непосредственно в области конфигурации. Дополнительное объявление
переменных, объявленных в области конфигурации, не требуется.
Табличное
Табличный способ объявления переменных
позволяет ускорить процедуру объявления переменных. Для вызова окна
табличного объявления следует выбрать команду Объявления в форме
таблицы контекстного меню окна раздела объявлений. На вкладках
окна редактора отображаются списки переменных различных типов. В ячейках
таблицы списки переменных могут быть дополнены новыми переменными.
Значения атрибутов переменных могут быть введены или отредактированы
также в ячейках таблицы. Кроме того, требуемые переменные могут быть
не только отредактированы, но и удалены из списков.
Автоматическое
Автоматическое объявление
переменных позволяет автоматизировать ввод значений ряда атрибутов
переменной, что позволяет ускорить и упростить процедуру ввода и одновременно
избежать ошибок, возможных при ручном вводе.
Для вызова окна
автоматического объявления переменных следует выбрать команду Авто
объявление… в контекстном меню окна раздела объявлений.
В открывшемся окне задается имя добавляемой переменной (в поле «Имя»).
В других полях окна значения задаются выбором из раскрывающегося списка
или списков, отображаемых в специальных окнах.
автоматического объявления переменной
Например, требуемый тип переменной можно выбрать в окне «Ассистент
ввода», которое открывается по нажатию кнопки с тремя точками, размещенной
у правого края поля «Тип».
переменной
Типы данных
Тип данных определяет род информации, методы ее обработки и хранения,
количество выделяемой памяти. Программист может непосредственно использовать
элементарные (базовые) типы данных или создавать собственные (пользовательские)
типы на их основе.
Базовые типы данных
Логический (BOOL)
BOOL – логический
тип данных, который может принимать два значения – ИСТИНА (TRUE) или
ЛОЖЬ (FALSE). Логический тип данных занимает 8 бит памяти (если не
задан прямой битовый адрес).
Целочисленный
BYTE, WORD, DWORD, SINT, USINT, INT, UINT, DINT и UDINT – целочисленные типы данных, которые отличаются
диапазонами сохраняемых данных и требованиями к памяти. Характеристики
целочисленных типов данных приведен в таблице ниже.
Характеристики целочисленных типов данных
Тип | Нижний предел | Верхний предел | Размер памяти |
---|---|---|---|
BYTE |
0 |
255 |
8 бит |
WORD |
0 |
65535 |
16 бит |
DWORD |
0 |
4294967295 |
32 бит |
SINT |
–128 |
127 |
8 бит |
USINT |
0 |
255 |
8 бит |
INT |
–32768 |
32767 |
16 бит |
UINT |
0 |
65535 |
16 бит |
DINT |
–2147483648 |
2147483647 |
32 бит |
UDINT |
0 |
4294967295 |
32 бит |
Рациональный
REAL – данные в формате
с плавающей запятой, используются для сохранения рациональных чисел.
Для рационального типа требуется 32 бита памяти.
Диапазон значений
рационального типа от [1.175494351e-38] до [3.402823466e+38].
Строки
Строковый тип STRING представляет
строки символов. Максимальный размер строки определяет количество
резервируемой памяти и указывается во время объявления переменной.
Размер задается в круглых или квадратных скобках. Если размер не указан,
принимается размер по умолчанию – 80 символов.
Длина строки
в CODESYS не ограничена, но строковые функции способны обращаться
со строками от 1 до 255 символов.
Объявление строки размером до 35 символов:str:STRING(35):='Просто строка';
Время и дата
Форматы данных времени и даты:
-
TIME – представляет длительность интервалов времени
в миллисекундах. Максимальное значение для типа TIME: 49d17h2m47s295ms
(4194967295 ms); -
TIME, TIME_OF_DAY (сокр. TOD) – содержит
время суток, начиная с 0 часов (с точностью до миллисекунд). Диапазон
значений TOD: от 00:00:00 до 23:59:59.999; -
DATE – содержит календарную дату, начиная с 1 января
1970 года. Диапазон значений от: 1970-00-00 до 2106-02-06; -
DATE_AND_TIME (сокр. DT) – содержит время в секундах,
начиная с 0 часов 1 января 1970 года. Диапазон значений от: 1970-00-00-00:00:00
до 2106-02-06-06:28:15.
Типы TIME, TOD, DATE и DATE_AND_TIME (сокр. DT) сохраняются физически как DWORD.
Пользовательские типы данных
Кроме стандартных типов данных в проекте можно использовать определяемые
пользователем сложные типы данных: массивы, перечисления, структуры
и некоторые другие (см. раздел).
Подключение дополнительных программных модулей
Дополнительные программные модули (библиотеки) подключаются в окне
«Менеджер библиотек» (см. рисунок).
Окно «Менеджер библиотек» вызывается командой Окно → Менеджер
библиотек или выбором пункта «Менеджер библиотек» в дереве на
вкладке «Ресурсы» организатора объектов.
Для подключения библиотеки следует:
-
Выбрать команду «Добавить библиотеку» (Add library) в контекстном
меню списка подключенных библиотек (отображаемого в верхней левой
области окна «Менеджер библиотек») или команду Вставка → Добавить
библиотеку… в главном меню. -
В открывшемся окне выбора файлов выбрать файл требуемой библиотеки
и нажать кнопку «Открыть». Выбранная библиотека будет подключена к
проекту. Ее наименование отобразится в списке установленных библиотек
(в верхней левой области окна «Менеджер библиотек»).
Для удаления подключенной библиотеки следует:
-
Выделить требуемую библиотеку в списке подключенных (отображается
в верхней левой области окна «Менеджер библиотек»). -
Вызвать команду «Удалить» контекстного меню списка. Выделенная
библиотека будет отключена от проекта.
Для включения в проект дополнительного программного модуля (то
есть модуля, который содержится в подключенной к проекту библиотеке)
следует:
-
Перейти на вкладку «POU» организатора объектов.
-
В дереве программных компонентов объекта выбрать требуемый
компонент. -
Вызвать команду Правка → Ассистент ввода в главном меню
или команду «Ассистент ввода» в контекстном меню раздела объявлений. -
В открывшемся окне «Ассистент ввода» (см. рисунок), в левой части, где отображается перечень доступных
типов добавляемых объектов, выделить требуемый тип (в данном случае
– «Стандартные функциональные блоки»). В правой части окна отобразится
перечень доступных объектов выбранного типа. Если флажок переключателя
«Структурно» в нижней части окна установлен, то перечень отображается
в виде иерархического структурированного списка. В противном случае
перечень отображается в виде отсортированного по алфавиту линейного
списка. -
В перечне доступных объектов (в правой части окна) выбрать
требуемый объект и нажать кнопку «ОК» окна. Выбранный объект (в данном
случае – стандартный функциональный блок) будет вставлен в редактируемый
программный компонент проекта. Для отказа от добавления блока нажать
кнопку «Отмена».
Доступные дополнительные программные модули
Описания системных библиотек CODESYS доступны на сайте компании
3S Software и на странице CODESYS
V2 на сайте owen.ru.
ПЛК110 поддерживают следующие библиотеки
программных компонентов:
-
OwenLibFileAsync.lib;
-
OwenLibUSBSerial.lib;
-
OwenLibNetControl.lib;
-
OwenLibFactorySetups.lib;
-
OwenLibHidEvent.lib;
-
OwenLibPing.lib;
-
Timer.lib;
-
RetainControlLib.lib.
Рекомендуемые библиотеки:
-
Standart.lib;
-
Util.lib;
-
SysLibTime.lib;
-
SysLibCom.lib;
-
SysLibProjectInfo.lib;
-
SysLibMem.lib;
-
SysLibSockets.lib;
-
SysLibFile.lib;
-
SysLibPorts.lib;
-
NetVarUdp_LIB_V23.lib;
-
ComService.lib;
-
ModBus.lib;
-
OwenNet.lib;
-
Mercury.lib;
-
UNM.lib;
-
PID_Regulators.lib;
-
SmsOwenLib.lib;
-
OwenModbusSlave.lib;
-
Oscat_basic_333.lib;
-
Oscat_building_100.lib.
Установщик библиотек и их описания доступны на странице CODESYS V2 на сайте owen.ru. Помимо вышеперечисленных библиотек
в состав установщика включены и некоторые сопутствующие библиотеки.
Модуль работы с файлами OwenLibFileAsync.lib
Модуль OwenLibFileAsync.lib поддерживает сохранение в файлы произвольных
данных, чтение, удаление, копирование, переименование файлов и др.
в асинхронном режиме, так как встроенное ПО контроллера в новой версии
предусматривает работу с файловыми системами.
Примечание
Библиотека OwenLibFileAsync.lib рекомендуется для
всех новых разработок.
Файлы можно сохранять на следующие устройства хранения:
-
внешний накопитель, подключенный к порту USB-Host (например,
Flash-память, или жесткий диск); -
внутренний Flash-накопитель;
-
внутренний виртуальный RAM диск (64 килобайт).
На носителях поддерживаются подкаталоги, а также доступны операции
с файлами в директориях и просмотр содержимого директорий.
Устройство, на которое файл будет записываться, задается с помощью
префикса к имени файла:
-
ffs: – для внутренней Flash-памяти;
-
ram: – для виртуального диска
-
usb: – для внешнего накопителя, подключенного к порту
USB-Host.
Чтобы записать файл с именем «file1.txt» на разные носители,
следует преобразовать его в «ffs:file1.txt» для записи во внутреннюю
flash-память, «ram:file1.txt» – для записи на виртуальный диск и «usb:file.txt»
– для записи на внешний накопитель.
На ПЛК запущен TFTP-сервер для передачи данных по протоколу TFTP
(см. RFC 1350 – THE TFTP PROTOCOL (REVISION 2) http://tools.ietf.org/html/rfc1350). Следует обратить внимание,
что только RAM-диск доступен для TFTP протокола, а также отсутствует
функция разграничения доступа. Сервер доступен на всех интерфейсах
ПЛК по соответствующим IP-адресам на порту 69. Подробный пример доступен
в документе «Руководство по работе с файлами на ПЛК по протоколу
TFTP», который находится на странице CODESYS
V2 на сайте owen.ru.
Внимание
Не рекомендуется использовать встроенную Flash-память
для записи часто переписываемых файлов, так как ее ресурс ограничен
(около 50 000 циклов записи). В создаваемых пользовательских программах
для контроллера рекомендуется программировать сохранение файла с предпочтением
внешнего накопителя при его наличии.
Внимание
Виртуальный диск расположен в ОЗУ контроллера,
поэтому все файлы, записанные под именами с префиксом «ram:», будут
храниться в контроллере до первого его выключения. Для сохранения
файлов следует их копировать на Flash-носители – внутренний или внешний.
Примечание
Пользовательская программа может работать одновременно
максимум с пятью файлами.
Во время работы с USB-Host следует учитывать:
-
Суммарное потребление тока хабом и подключенными устройствами
не должно превышать 0,5 А; -
USB-Host имеет функцию защиты от перегрузки и короткого замыкания.
Срабатывание защиты приводит к выключению питания на USB-Host с последующими
периодическими попытками восстановления питания; -
к ПЛК могут быть подключены USB MassStorage и USB HID устройства.
Общее число подключенных USB MassStorage и USB HID устройств не должно
превышать 1 для каждого типа. Остальные устройства игнорируются. Устройства
инициализируются в порядке подключения. Если два USB MassStorage устройства
уже подключены и подается питание на ПЛК, то порядок их инициализации
непредсказуем; -
стек USB-Host поддерживает опрос не менее 1 устройства класса
USB HID; -
с помощью библиотеки OwenLibHidEvent.lib можно получать сообщения
от HID устройства, например мыши и/или клавиатуры; -
в ПЛК поддерживается класс USB MassStorage с файловой системой
FAT (12, 16, 32). Ограничения на размер накопителя налагаются только
ограничениями файловой системы FAT.Примечание
Рекомендуется
использовать файловую систему FAT32.
Запись на USB MassStorage накопитель происходит без кэширования,
т. е. для безопасного отключения накопителя следует:
-
Завершить все процедуры записи (остановить запись из программы
через библиотеку OwenLibFileAsync и закрыть открытые файлы, дождаться
завершения всех системных загрузок файлов, остановить работу модуля(ей)
архивации, остановить опрос файлов через 0x20 функцию ModBus slave). -
Дождаться прекращения активности на накопителе (если индикация
активности присутствует) или выждать не менее 3 секунд. -
Отключить накопитель.
Не рекомендуется подключать USB MassStorage устройства на базе
жестких дисков и SDD без дополнительного внешнего питания, т. к. это
может привести к перегрузке по питанию и циклическому включению/выключению
внешнего диска.
Примечание
Не гарантируется корректная работа ПЛК с USB устройствами,
если последние обратно не совместимы с протоколом USB 1.1.
В контроллере реализован асинхронный механизм доступа к файлам
из пользовательской программы. Асинхронный доступ гарантирует отсутствие
задержек в выполнении пользовательской программы при доступе к файлам,
в том числе расположенным на внешних носителях. Основной особенностью
использования модуля OwenLibFileAsync.lib является выполнение
функций в два этапа:
-
Подача команду для работы с файлом.
-
Проверка завершенности выполнения указанной команды и разрешение
для подачи следующих команд для дальнейших операций с файлом.
Любая функция библиотеки OwenLibFileAsync.lib возвращает
2 значения:
-
Состояние запроса к асинхронной библиотеке:
-
ASYNC_PAUSED -1000 (*Система по своим внутренним причинам приостановила
обработку асинхронных запросов*); -
ASYNC_QUERY_FULL -1001 (*более 5 запросов в очереди*);
-
ASYNC_BLOCK_ACCESS -1002 (*Запрос к уже обрабатываемому объекту
с другой функцией*); -
ASYNC_GENERAL_ERROR -1003 (*фатальная ошибка*);
-
ASYNC_INVALID_HANDLE_ERROR -1004 (*Запрос к неоткрытому/открытому
не через асинхронную библиотеку файлу*); -
ASYNC_WORKING 32766 (*идет работа асинхронной библиотеки*);
-
ASYNC_DONE 32767 (* работа завершена -> смотрите значение return
value *).
-
-
При получении ASYNC_DONE требуется посмотреть второе возвращаемое
значение, уже самой функции файловой системы:returnvalue:POINTER TO DWORD;
В этой переменной лежит возвращаемое функцией значение, и расшифровку
значения следует смотреть в описании соответствующей функции обычной,
синхронной библиотеки SysLibFile.lib.
Функции работы с файлами в асинхронном режиме:
-
OwenFileOpenAsync – используется для открытия существующего
или создания нового файла. Выход hFile (DWORD) сообщает дескриптор
файла. Он используется другими функциональными блоками для работы
с данным файлом; -
OwenSysFileCloseAllOpenAsync – функциональный блок закрывает
все открытые файлы. Имена или дескрипторы файлов не нужно сообщать,
поскольку они все уже известны системе; -
OwenSysFileCloseAsync – используется для закрытия файла.
После закрытия файл освобождается для других процессов, дескриптор
более не имеет значения; -
OwenSysFileWriteAsync – используется для записи данных
в файл. Файл должен быть предварительно успешно открыт с помощью SysFileOpenAsync; -
OwenSysFileReadAsync – используется для чтения данных
из файла. Файл должен быть предварительно успешно открыт с помощью
SysFileOpenAsync; -
OwenSysFileDeleteAsync – удаление файла с заданным именем;
-
OwenSysFileGetPosAsync – возвращает позицию (смещение
от начала файла в байтах) записи и чтения в файл; -
OwenSysFileSetPosAsync – задает позицию записи и чтения
в файл; -
OwenSysFileEOFAsync – возвращает TRUE, если текущая
позиция чтения/записи находится в конце файла, иначе возвращает FALSE; -
OwenSysFileGetSizeAsync – возвращает размер файла с
заданным именем; -
OwenSysFileGetTimeAsync – возвращает время создания,
последнего доступа и последнего изменения файла с заданным именем; -
OwenSysFileCopyAsync – копирование файла с заданным
именем в файл с другим именем; -
OwenSysFileRenameAsync – переименование (перенос) файла
с заданным именем.
Функция OwenSysFileOpenAsync
Функция OwenSysFileOpenAsync
возвращает значение типа DWORD и используется для открытия существующего
или создания нового файла. Возвращаемое значение – дескриптор файла,
либо «0» в случае ошибки. Дескриптор файла используется для доступа
к открытому файлу другими функциями библиотеки. В некоторых случаях
сообщение об ошибке имеет вид «16#FFFFFFFF» (в десятичной системе
это число 4294967295 при интерпретации как беззнакового числа или
число –1 при интерпретации как числа со знаком).
Входные переменные:
-
FileName типа STRING – имя файла;
-
Mode типа STRING – режим работы с файлом, может имеет
следующие значения:-
w+ – если требуется открыть файл только для записи.
Если файл существовал до начала записи, то он будет стерт и создан
пустой файл с заданным именем; -
r – если требуется открыть файл только для чтения;
-
a – аналогично w+, но если файл существовал до
начала операции, данные будут дописываться в конец файла.
-
Открытие файла в режиме «а» и разрешение на переход к
дальнейшим операциям с файлом на языке ST:
0:
res:=OwenFileOpenAsync(filename,'a',ADR(handle));
IF res=ASYNC_WORKING THEN
state:=1;
END_IF
1:
res:=OwenFileOpenAsync(filename,'a',ADR(handle));
IF res=ASYNC_DONE THEN
IF handle<>0 THEN
state:=2;
ELSE
state:=0;
END_IF
ELSIF res<0 THEN
state:=0;
END_IF
Функция OwenSysFileCloseAsync
Функция OwenSysFileCloseAsync
закрывает файл, открытый ранее функцией OwenSysFileOpenAsync, и возвращает
значение типа BOOL, которое равно TRUE при успешном закрытии файла,
иначе (например, если файл не был открыт) FALSE. Входным параметром
является дескриптор закрываемого файла.
Входные переменные:
-
hFile типа DWORD – дескриптор файла, число, которое
возвратила функция OwenSysFileOpenAsync.
Закрытие файла в режиме «а» и разрешение на переход к
дальнейшим операциям с файлом на языке ST:
res:=OwenFileCloseAsync(handle,ADR(result));
IF res=ASYNC_WORKING THEN
state:=7;
ELSE
state:=0;
END_IF
7:
res:=OwenFileCloseAsync(handle,ADR(result));
IF res=ASYNC_DONE THEN
IF result=0 THEN
state:=8;
ELSE
state:=8;
END_IF
ELSIF res<0 THEN
state:=8;
END_IF
Функция OwenSysFileWriteAsync
Функция OwenSysFileWriteAsync
записывает данные в файл, открытый с помощью OwenSysFileOpenAsync,
и возвращает значение типа DWORD – количество записанных байт данных.
Входные переменные:
-
File типа DWORD – дескриптор файла, число, которое возвратила
функция OwenSysFileOpenAsync; -
Buffer – адрес буфера, содержащего данные, которые необходимо
записать в файл, число, которое возвратила функция ADR с аргументом
– именем переменной-буфера, тип – массив, например, массив байт, или
строка; -
Size типа DWORD – размер буфера в байтах, может использоваться
функция SIZEOF с аргументом (именем переменной-буфера).
Запись значения «buffout» в файл в режиме «а» на языке
ST:
2:
res:=OwenFileWriteAsync(handle,ADR(bufout),14,ADR(result));
IF res=ASYNC_WORKING THEN
state:=3;
ELSE
state:=6;
END_IF
3:
res:=OwenFileWriteAsync(handle,ADR(bufout),14,ADR(result));
IF res=ASYNC_DONE THEN
IF result=14 THEN
state:=4;
ELSE
state:=6;
END_IF
ELSIF res<0 THEN
state:=6;
END_IF
Функция OwenSysFileReadAsync
Функция OwenSysFileReadAsync
считывает данные из файла, открытого с помощью функции OwenSysFileOpenAsync,
и возвращает значение типа DWORD – количество считанных байт данных.
Входные переменные:
-
File типа DWORD – дескриптор файла, число, которое возвратила
функция OwenSysFileOpenAsync; -
Buffer – адрес буфера, содержащего данные, которые необходимо
записать в файл. Число, которое возвратила функция ADR с аргументом
– именем переменной-буфера. Тип – массив, например, массив байт или
строка; -
Size типа DWORD – размер буфера в байтах, может использоваться
функция SIZEOF с аргументом – именем переменной-буфера.
Пример функции аналогичен функции OwenSysFileWriteAsync.
Функция OwenSysFileDeleteAsync
Функция OwenSysFileDeleteAsync
удаляет файл и возвращает значение типа BOOL: TRUE в случае успешного
удаления или FALSE в случае ошибки.
Входная переменная FileName типа STRING – имя удаляемого файла.
Функция OwenSysFileGetPosAsync
Функция OwenSysFileGetPosAsync
возвращает число типа DWORD – фактическое смещение в байтах от начала
до текущей позиции в открытом файле с заданным дескриптором. Число
определяет «место» в файле, откуда будет считана или куда будет записана
информация, если операция чтения или записи будет произведена без
дополнительного предварительного смещения позиции (см. функцию OwenSysFileSetPosAsync).
Входная переменная File типа DWORD – дескриптор открытого
файла.
Функция OwenSysFileSetPosAsync
Функция OwenSysFileSetPosAsync
устанавливает для открытого файла с заданным дескриптором позицию
чтения (записи) с помощью заданного смещения и возвращает значение
типа BOOL. Если позиция была установлена, то возвращается значение
TRUE, иначе возвращается FALSE.
Входные переменные:
-
File типа DWORD – дескриптор открытого файла, в котором
необходимо задать текущую позицию чтения (записи); -
Pos типа DWORD – позиция чтения (записи), заданная смещением
в байтах от начала файла.
Функция OwenSysFileEOFAsync
Функция OwenSysFileEOFAsync
определяет, достигнут ли конец файла, и возвращает значение типа BOOL,
равное TRUE, если текущим положением позиции чтения (записи) является
конец файла, иначе FALSE.
Входная переменная File типа
DWORD – дескриптор открытого файла, в котором проверяется достижение
текущей позицией конца.
Функция OwenSysFileGetSizeAsync
Функция
OwenSysFileGetSizeAsync возвращает размер файла в байтах в виде значения
типа DWORD.
Входная переменная FileName типа STRING –
имя файла.
Функция OwenSysFileGetTimeAsync
Функция
OwenSysFileGetTimeAsync определяет значения даты и времени создания,
последнего изменения и последнего доступа к файлу, и возвращает значение
типа BOOL: TRUE в случае успешного завершения выполнения функции и
FALSE в случае любой ошибки (например, доступа к файлу). Для хранения
трех значений времени в одной переменной используется структура FileTime,
приведенная ниже.
TYPE FILETIME
STRUCT
dtCreation:DT; (* Дата и время создания файла *)
dtLastAccess:DT; (* Дата и время последнего доступа *)
dtLastModification:DT; (* Дата и время последнего изменения файла *)
END_STRUCT
END_TYPE
Входные переменные:
-
FileName типа STRING – имя файла;
-
ftFileTime типа POINTER TO FILE TIME – адрес структуры,
в которую будут сохраняться считанные данные о времени создания файла,
последнего доступа к нему и его последней модификации. Извлекается
с помощью функции ADR.
Программа на языке ST, считывающая структуру со значениями
времени создания файла:
VAR
file_time:POINTER TO FILETIME;
returnvalue:POINTER TO DWORD;
w: FILETIME;
END_VAR
8:
OwenFileGetTimeAsync(filename, file_time, returnvalue);
w:=file_time;
ELSE
state:=0;
END_CASE
Функция OwenSysFileCopyAsync
Функция OwenSysFileCopyAsync
копирует один файл в другой (файлы задаются именами) и возвращает
значение типа UDINT, в котором содержится количество действительно
скопированных байт.
Входные переменные:
-
FileDest типа STRING – имя копии файла (файл-приемник);
-
FileSource типа STRING – имя копируемого файла (файл-источник).
Функция OwenSysFileRenameAsync
Функция OwenSysFileRenameAsync
переименовывает файл и возвращает значение типа BOOL: TRUE в случае
успешного переименования или FALSE в случае ошибки. Ошибка может возникать,
например, если попытаться переименовать открытый файл.
Входные
переменные:
-
FileOldName типа STRING – текущее имя файла;
-
FileNewName типа STRING – новое имя файла.
Модуль контроля выхода в интернет OwenLibNetControl.lib
Модуль-библиотека OwenLibNetControl.lib предназначена для
управления сетевыми устройствами в ПЛК. Библиотека позволяет включать/выключать
интерфейсы (если это разрешено), получать статус интерфейса, его тип,
атрибуты и адреса интерфейса (MAC, IP, APN, телефонный номер и т.
п.). Библиотека подключается аналогично стандартным библиотекам CODESYS.
В ПЛК интерфейсы Ethernet и PPP имеют, соответственно, номера 0
и 1.
Функция START_IFACE
отображение функции START_IFACE
Входная
переменная IFACE типа DWORD – номер запускаемого интерфейса.
Выходная переменная START_IFACE типа BOOL – значение, указывающее
на успешность выполнения команды. Если возвращается значение «0»,
запуск произошел успешно.
Функция STOP_IFACE
отображение функции STOP_IFACE
Входная
переменная IFACE типа DWORD – номер закрываемого интерфейса.
Выходные переменные STOP_IFACE типа BOOL – значение, указывающие
на успешность закрытия интерфейса. Если возвращается значение «0»,
интерфейс закрыт успешно.
Функция GET_IFACE_INFO
отображение функции GET_IFACE_INFO
Входная
переменная IFACE типа DWORD – номер интерфейса.
Выходная
переменная GET_IFACE_INFO типа POINTER TO IFACE_INFO возвращает
указатель на структуру, содержащую информацию об интерфейсе:
TYPE IFACE_INFO:
STRUCT
name: STRING(79); (* Имя интерфейса *)
itype: IFACE_TYPES; (* Тип интерфейса *)
addreses: ARRAY[0..9] OF ARRAY[0..31] OF BYTE; (* Все адреса интерфейса
(МАС, IP, имя порта) список зависит от типа *)
atributes: IFACE_ATRIBUTES; (* Атрибуты интерфейса *)
END_STRUCT
END_TYPE
Поля структуры параметра GET_IFACE_INFO:
-
IFACE_TYPES – типы интерфейсов, поле может принимать
следующие значения:-
NO_IFACE 0 – нет интерфейса;
-
ETHERNET_IFACE 1 – интерфейс Ethernet;
-
PPP_IFACE 2 – использование модема.
-
-
IFACE_ATRIBUTES – атрибуты интерфейса, поле может принимать
следующие значения:-
HAVE_STATUS 1 – возвращает статус;
-
AUTOSTART 2 – запускается автоматически;
-
USE_DHCP 4 – настроен в режиме DHCP.
-
-
IFACE_ADDRESS_TYPES – массив из 10 полей типа Array
[0..31] of BYTES, каждый элемент массива содержит информацию об определенных
адресах интерфейса:-
IFACE_MAC_ADDRESS 0 – массив, содержащий МАС-адрес;
-
IFACE_IP_ADDRESS 1 – массив, содержащий IP-адрес;
-
IFACE_IP_MASK 2 – массив, содержащий маску сети;
-
IFACE_IP_GATE 3 – массив, содержащий шлюз сети;
-
IFACE_TEL_NUMBER 4 – массив, содержащий телефонный номер
текущего дозвона; -
IFACE_APN_NAME 5 – массив, содержащий адрес APN-оператора.
-
Функция GET_IFACE_STATUS
отображение функции GET_IFACE_STATUS
Входная
переменная IFACE типа DWORD – номер интерфейса.
Выходная
переменная GET_IFACE_STATUS типа IFACE_STATUS возвращает статус
модема, битовые поля которого имеют следующие значения, по битам:
-
IFACE_NOT_PRESENT – если возвращается 0, то интерфейс
не запущен; -
IFACE_PRESENT – 0 – интерфейс запущен;
-
IFACE_CONFIGURED – 1 – интерфейс настроен (есть настройки);
-
IFACE_CONNECTED – 2 – есть физическое соединение;
-
IFACE_WORKING – 3 – есть логическое соединение;
-
IFACE_SEND_DATA – 4 – в течение 5 секунд была отправлена
посылка; -
IFACE_READ_DATA – 5 – в течение 5 секунд была получена
посылка; -
IFACE_HAVE_ERROR – 6 – есть ошибки;
-
IFACE_NO_IFACE – если возвращается 16#FFFF, то такого
интерфейса нет.
Модуль получения серийного номера USB-устройства OwenLibUSBSerial.lib
Модуль OwenLibUSBSerial.lib предназначен для получения статуса
подключенных к USB-Host устройств и доступа к их серийному номеру.
Модуль содержит только одну функцию – GETUSBSERIAL.
Входные переменные:
-
Unit типа DINT – номер устройства, обычно 0;
-
Buffer типа POINTER TO BYTE – указатель на массив размером
24 байт, куда будет записан серийный номер.
Выходной параметр GetUSBSerial типа DINT возвращает значения:
-
0 – чтение серийного номера прошло успешно;
-
(–1) – устройство USB не подключено;
-
(–2) – серийный номер прочитан с ошибкой.
Расшифровка массива, содержащего серийный номер USB:
Значения массива
Offset | Field | Size | Value | Description |
---|---|---|---|---|
0 |
bLength |
1 |
N+2 |
Size of this descriptor in bytes |
1 |
bDescriptorType |
1 |
Constant |
STRING Descriptor Type |
2 |
wLANGID[0] |
2 |
Number |
LANGID code zero |
… | ||||
N |
wLANGID[x] |
2 |
Number |
LANGID code x |
Расшифровка строки (вместо серийного номера):
Значения строки
Offset | Field | Size | Value | Description |
---|---|---|---|---|
0 | bLength | 1 | Number | Size of this descriptor in bytes |
1 | bDescriptorType | 1 | Constant | STRING Descriptor Type |
2 | bString | N | Number | UNICODE encoded string |
Модуль работы с HID-устройствами OwenLibHidEvent.lib
Модуль OwenLibHidEvent.lib предназначен для получения статуса подключенных
к USB-Host HID-устройств. Общее число Mass Storage Device и HID-устройств
не должно превышать 1 для каждого типа. Остальные устройства игнорируются.
Инициализация устройств в порядке подключения.
Модуль содержит только одну функцию – GETHIDEVENT.
Входная переменная pHIDEv типа POINTER TO BYTE – указатель
на массив, в котором будут храниться данные. Размер массива должен
быть равен 17 байтам.
Выходная переменная GetUSBSerial типа DINT возвращает указатель
на массив, где хранятся данные:
-
Code:DINT; (*или xChange для мыши*) (*Для клавиатуры Code
трактовать как DWORD*); -
Value:DINT; (*или yChange для мыши*) (*Для клавиатуры Value
трактовать как DWORD. Индицирует нажата/отпущена*); -
WheelChange:DINT; (*как и x(y)Change относительное перемещение*);
-
ButtonState:DINT; (*биты нажатых кнопок*);
-
Event_type:BYTE; (*==1 — мышь ==2 — клавиатура*).
Модуль PING OwenLibPing.lib
Модуль OwenLibPing.lib предназначен для посылки команды «ping»
по указанному адресу. Ответ ожидается в течение заранее установленного
тайм-аута.
Функция SENDPING
функции SENDPING
Входные переменные:
-
IFace типа DWORD – тип используемого интерфейса (0 –
Ethernet, 1 – PPP); -
IP_addr типа DWORD – IP-адрес устройства, которое требуется
пинговать (например, 16#0A020B32 – устройство с IP-адресом
10.02.11.50); -
timeout – предустановленный тайм-аут пинга в мс (минимум
50 мс, максимум 25000 мс).
Выходная переменная SendPing типа DINT возвращает статус
пинга:
-
PING_SERVICE_READY:=1(*?*);
-
PING_SERVICE_IFACE_NOT_READY:=-1 (*интерфейс не поднят*);
-
PING_SERVICE_SENDING:=2 (*?*);
-
PING_SERVICE_TIMEOUT:=-2 (*таймаут ответа*);
-
PING_SERVICE_ANSV_RECEIVED:=3 (*?*);
-
PING_SERVICE_BUSY:=-3 (*запрос был послан,интерфейс занят*);
-
PING_SERVICE_DEST_UNREACHABLE:=-4 (*?*).
Функция GETPINGSTATUS
представление функции GETPINGSTATUS
Функция
не имеет входных переменных.
Выходная переменная GetPingStatus типа DINT возвращает статус. Если ошибка или PING_SERVICE_ANSV_RECEIVED, то после чтения статус сбрасывается в PING_SERVICE_READY.
Модуль таймера Timer.lib
Модуль Timer.lib используется для работы со встроенным таймером,
по прерыванию которого может быть вызван отдельный программный элемент
(POU), не связанный с выполнением основной программы ПЛК.
Подробное описание модуля находится в разделе и на странице CODESYS
V2 на сайте owen.ru.
Модуль RetainControlLib.lib
Модуль RetainControlLib.lib используется для принудительной записи
RETAIN по команде из пользовательской программы.
Примечание
Использование модуля RetainControlLib.lib возможно
только в режиме записи по событию (SetCyclicMode установлен в значение
«0»).
Модуль имеет одну функцию SAVENOW, которая служит для принудительной
записи RETAIN-переменных.
Функция не имеет входных переменных.
Выходная переменная SAVENOW типа BOOL – флаг, возвращаемый
функцией по завершению записи.
Внимание
Использование функции приостанавливает выполнение
программы ПЛК до завершения полной записи RETAIN-переменных. Запись
длится около 30 мс, поэтому рекомендуется вызывать функцию SAVENOW
только когда значения RETAIN-переменных были изменены.
PROGRAM PLC_PRG
VAR
xSaveRetain: BOOL; (* Переменная управления сохранением RETAIN.
Запись происходит по переднему фронту *)
xDone: BOOL; (* Флаг завершения записи *)
END_VAR
VAR RETAIN
rSetPoint: REAL; (* RETAIN переменная, которую хотим принудительно
сохранить *)
END_VAR
IF xSaveRetain = TRUE THEN
xDone := SaveNow();
IF xDone = TRUE THEN
xSaveRetain := FALSE;
END_IF
END_IF
Создание и использование дополнительных программных модулей
Пользователь может разрабатывать и применять дополнительные программные
модули. Такая необходимость может возникнуть в том случае, если применяемая
программа должна содержать алгоритмы, которые не могут быть написаны
с использованием готовых программных модулей.
Для создания пользовательского программного модуля следует:
-
Создать новый проект (см. раздел).
-
В проекта создать объект типа «Функциональный блок» (см. рисунок).
Создание нового
функционального блока -
Написать программу функционального блока, которую предполагается
использовать в качестве пользовательского программного модуля.Пример кода нового программного компонента -
Удалить из проекта программный компонент PLC_PRG (команда «Удалить
объект» контекстного меню объекта в дереве объектов), оставив в нем
только созданный функциональный блок. -
Сохранить функциональный блок командой Файл → Сохранить
как, задав в открывшемся окне в поле «Тип файла» тип файла – «Внешняя
библиотека (*.lib)» и нажав кнопку «Сохранить». -
Сохраненный функциональный блок подключить к разрабатываемому
проекту аналогично тому, как подключаются готовые программные модули
(см. раздел). -
Новый функциональный блок отобразится в перечне доступных стандартных
функциональных блоков окна «Ассистент ввода» и может быть добавлен
в текущий проект аналогично тому, как это выполняется для функциональных
блоков из состава поставляемых библиотек (см. раздел).
Многозадачность
По умолчанию в проекте всегда создается единственная «главная»
программа PLC_PRG, выполняемая циклически (см. раздел). В проекте можно явно определить несколько задач с различными условиями выполнения. Задача – это единица обработки
программы.
Каждая задача имеет:
-
Название – служит идентификатором задачи;
-
Тип – определяет условие вызова задачи. Условием может
служить время (циклическое или свободное freewheeling выполнение),
внутреннее или внешнее событие (например, превышение заданного порога
глобальной переменной или прерывание в контроллере); -
Приоритет – задается числом (от 1 до 15) и в сочетании
заданными условиями вызова задачи определяет хронологический порядок
выполнения задач.
Для каждой задачи назначается ряд программ, которые будут в ней
выполняться. Если задача выполняется в текущем цикле, то выполняются
все включенные в нее программы (по одному циклу каждая). Порядок выполнения
задач определяется комбинацией приоритетов и условий вызова задач.
Для каждой задачи можно задать контроль времени выполнения («сторожевой
таймер»). Возможности его использования и настройки определяются целевой
платформой.
Выполнение каждой задачи можно разрешить или запретить независимо
от других.
Конфигурирование задач
Задачи определяются в окне «Конфигурация задач», которое открывается
на вкладке «Ресурсы» организатора объектов.
задач»
В левой части окна отображается перечень задач текущего проекта
в виде дерева конфигурации. В корневой позиции обязательно присутствует
элемент «Конфигурация задач», под ним раскрывается список задач, представленных
по именам.
Для добавления в проект новой задачи следует выбрать команду Вставка → Вставить задачу главного меню или команду «Вставить
задачу» контекстного меню дерева задач.
После добавления задачи в проект она включается в дерево задач
и снабжается пиктограммой, отображающей тип задачи:
-
– выполняемые по системным событиям (Старт, Стоп, Сброс);
-
– циклически выполняемые задачи;
-
– выполняемые по времени (свободному);
-
– выполняемые по событию (связанному с глобальными переменными
проекта); -
– выполняемые по внешнему событию.
В правой части окна отображаются поля задания атрибутов текущей
(выбранной в дереве задач) задачи. Набор полей соответствует атрибутам
задачи выбранного типа.
Задавая значения атрибутов, можно конфигурировать свойства задач
(Task properties), вызова программ (Program call), задавать связи
с системными событиями (System events). Эта возможность зависит от
выбора целевой платформы. Она должна быть поддержана в системе исполнения
и разрешена в опциях целевой системы. Если стандартный набор настроек
расширен специфическими параметрами, они будут представлены на отдельной
вкладке «Parameter» в правой части окна.
Внимание
Если в окне «Конфигурация задач» определена последовательность
выполнения задач, то проект может не содержать PLC_PRG. В противном
случае удалять или переименовывать программный компонент PLC_PRG нельзя.
PLC_PRG является главной программой в однозадачном проекте.
Конфигурирование задач типа «Системные события», то есть выполняемых
по одному из возможных системных событий включает:
-
Указание требуемого события – установкой флажка в поле
переключателя в требуемой строке списка системных событий; -
Указание имени программного компонента (POU), который
должен выполняться по наступлению события (ввод с клавиатуры в столбце
«Вызываемый POU» в требуемой строке списка системных событий). Если
POU с указанным именем не существует в текущем проекте, то активируется
кнопка «Создать POU <Имя POU>». По нажатию этой кнопки автоматически
формируется программный компонент проекта, имеющий указанное имя.
Он может редактироваться так же, как другие POU.
Конфигурирование задач других типов включает:
-
указание типа задачи – «Циклическая/Свободная/По событию/По
внешнему событию; -
для задачи циклического типа – указание интервала выполнения;
Указание интервала выполнения для задачи циклического
типа -
для задачи, выполняемой по событию – указание события, по нажатию
кнопки у правого края поля открывается окно «Ассистент ввода», в котором
можно выбрать требуемую переменную;Указание переменной
для задачи, выполняемой по событию -
для задачи, выполняемой по внешнему событию – указание события,
по нажатию кнопки у правого края поля открывается список задач, в
котором можно выбрать требуемую задачу;Указание переменной
для задачи, выполняемой по внешнему событию -
для задач любого типа задание параметров контроля времени выполнения
(«сторожевого таймера»), если эта опция доступна в используемом ПЛК.Указание параметров сторожевого таймера
Примечание
Не следует использовать одни и те же строковые функции
в разных задачах, что может привести к ошибкам перезаписи данных.
В режиме «Online» выполнение задач можно наблюдать в виде графической
диаграммы.
Обработка событий
Системные события, которые контроллер способен обрабатывать (см. рисунок):
-
start – вызов функции, если программа начала выполняться
(после загрузки в ОЗУ автоматически,либо по команде пользователя).
Функция выполняется до начала выполнения первого цикла программы; -
stop – вызов функции, если программа была остановлена.
Функция выполняется сразу после получения системой команды остановки
программы (из отладочной среды или с помощью управляющего тумблера
на передней панели); -
before_reset – вызов функции, если был произведен горячий
рестарт системы с помощью трехпозиционного переключателя (переключатель
удерживался пять и более секунд в положении «Сброс»). Функция выполняется
до перезагрузки контроллера; -
after_reset – вызов функции, если был произведен горячий
рестарт системы с помощью трехпозиционного переключателя (переключатель
удерживался пять и более секунд в положении «Сброс»). Функция выполняется
после перезагрузки контроллера. -
debug_loop – вызов функции, если включен режим отладки
и выполнение программы дошло до отладочной точки останова. -
Timer – вызов функции каждые 20 микросекунд.
Функции обработки событий должны иметь параметры, указанные во
вкладке «Системные события» окна «Конфигурация задач». В случае с
контроллером ПЛК110 функции обработки событий имеют одинаковый набор
параметров: входными параметрами являются dwEvent, dwFilter и dwOwner
типа INT, функция выдает значение типа WORD (см. Помощь по CODESYS
– «Система программирования CODESYS» – «Ресурсы» – «Конфигуратор задач»
– «Системные события»).
Отладка
Опция отладки заставляет компилятор формировать дополнительный
код, упрощающий поиск ошибок. Опция «Отладочный код» включается установкой
флажка переключателя «Отладочный код» в окне «Опции (Options)», вызываемом
командой Проект → Опции главного меню на вкладке Генератор
кода.
Точки останова
Точки останова – это места, в которых выполнение программы будет
приостанавливаться, что позволяет просмотреть значения переменных
на определенном этапе работы программы. Точки останова можно задавать
во всех редакторах. В текстовом редакторе точка останова устанавливается
на номер строки, в языках FBD и LD – на графический элемент, в языке
SFC – на шаг.
Внимание
Система исполнения CODESYS SP32 Bit Full автоматически
деактивирует сторожевой таймер задачи, если она выходит на точку останова.
Пошаговое выполнение
Примечание
Подробнее о пошаговом выполнении можно узнать
из встроенной помощи CODESYS:
-
Вызвать справку (F1 или в главном меню → Справка → Содержание…).
-
Выбрать в содержании Система программирования CODESYS →
Что есть что в CODESYS → Отладка и Online-функции.
Пошаговое выполнение позволяет проверить логическую правильность
программы. Под шагом подразумевается:
-
в языке IL – выполнить программу до следующего оператора
CALL, LD или JMP; -
в языке ST – выполнить следующую инструкцию;
-
в языках FBD, LD – выполнить следующую цепь;
-
в языке SFC – продолжить действие до следующего шага.
Выполнение по циклам
Команда Онлайн → Один цикл выполняет один рабочий цикл и
останавливает контроллер после выполнения.
Эмуляция
Режим эмуляции последовательно включается и отключается выбором
команды Онлайн → Режим эмуляции главного меню. Включенный режим
маркируется установленным флажком в строке главного меню и записью
«Эмул.» в строке состояния главного окна.
Во время эмуляции созданная программа выполняется не в ПЛК, а в
ПК, на котором запущено ПО CODESYS. В режиме эмуляции доступны все
функции онлайн, что позволяет проверить логическую правильность программ,
не используя контроллер.
Внимание
В режиме эмуляции функции внешних библиотек не
выполняются.
Бортжурнал (Log)
«Бортжурнал (Log)» хронологически записывает действия пользователя,
внутренние сообщения системы исполнения, изменения состояния и исключения
в режиме «Online», что позволяет анализировать условия возникновения
ошибки во время отладки программы.
Записи «Бортжурнала (Log)» можно просмотреть в режиме, вызываемом
командой «Бортжурнал (Log)» дерева ресурсов проекта на вкладке «Ресурсы»
организатора объектов.
Тестовый стенд для ОВЕН ПЛК 110
Ну что? Я продолжаю рассказывать базовые понятия ПЛК и то, как их программировать. Сегодня я расскажу про свои дальнейшние приключения с ОВЕНом и тем, как я его программировал. Как я уже говорил, программирование ПЛК — это совсем другая религия! Это вам не схемки или кубики в логическом реле двигать! Тут всё значительно мудрее и очень важен грамотный выбор железа, грамотное физическое подключение линий IO и внешних модулей.
Для ПЛК обычно есть два варианта сред разработки: CodeSys и собственные. CodeSys — это бесплатная среда разработки, которая делится на компилятор и ядро. Ядро CodeSys производители ПЛК загружают в него при производстве. И всё, что надо для программирования такого ПЛК — скачать CodeSys и специальные файлы, которые описывают конкретную модель ПЛК.
Второй вариант — это собственное ядро и собственная среда разработки. Тут уже каждый производитель извращается как нравится. Я вот хотел повозиться с Сименсами, но мне рассказали, что их среда разработки требует очень мощный комп и жрёт много ресурсов. Мне это не нравится, и я лучше подберу что-нибудь такое что работает с CodeSys, потому что мне проще поставить один раз хорошую среду, вылизать её настройки и заниматься только программированием.
ПЛК, который заказчик купил под свой щит работает на ядре CodeSys v2. Сейчас везде используется ядро CodeSys v3, а вторая версия ядра является устаревшей. Но так как принципы программирования всё равно одинаковые, то этот пост будет полезен всем начинающим. Да и мне охота поделиться информацией, которую я собирал по крупицам, неделю обложившись документацией. Блин! Мне кажется, что мне уже надо или учебные курсы вести, или посты продавать, гыгы =)
Содержание
- Настройка внешних модулей и ModBus
- Изучаем CodeSys
- Распределяем ресурсы ПЛК
- Назначение переменных в ПЛК
- Программируем
- Задачи
- Связь с ПЛК и заливка программы
- Библиотеки
Первое, с чего начинается работа по программированию — это создание тестового стенда. У меня валялись кнопки на DIN-рейку от ABB, и я собрал из них четыре линии ввода: три на бортовом IO ПЛК, а одну — на внешнем модуле для того, чтобы проверить как работает опрос модулей по ModBus.
Кнопки для подачи сигналов на входы ПЛК
Настройка внешних модулей и ModBus
Первое, с чего начинается наше программирование — это с конфигурации железа. Любой внешний модуль имеет на шине RS-485 свой адрес. А ещё модулю надо указать правильные настройки обмена: скорость, чётность и тип протокола обмена.
Каждый модуль или внешнее устройство настраивается по своему. У кого-то надо будет зайти в меню и поменять там цифирки. У кого-то поставить перемычки. А у других устройств для их настройки предусмотрена специальная программа-конфигуратор. У ОВЕНа сделано именно так.
Их модули подключаются штатно под RS-485 к компьютеру и настраиваются при помощи программы. Для того, чтобы подключить RS-485 к компьютеру, понадобится любой преобразователь интерфейсов. Их на рынке навалом и можно использовать любой. Если хочется — можно RS-485 завернуть даже в обычный Ethernet и общаться с модулями или нашей системой по сетке.
Так как вокруг меня был ОВЕН, то я для личных целей купил преобразователь ОВЕН АС-4. Он у них сделан в корпусе на DIN-рейку, питается от самого же порта USB. Из фич — то, что перемычками можно подключать и изменять сопротивление резисторов-терминаторов шины RS-485.
Мы подаём на модуль питание и подключаем его к преобразователю:
Преобразователь ОВЕН АС-4 и настройка модуля IO
Дальше запускаем программу «Конфигуратор М110». Первым делом программа предложит нам задать настройки для подключения к модулю. Если мы только что купили модуль — то можно смело тыкать кнопку «Заводские сетевые настройки». А если модуль уже настроен на какой-то адрес и другие параметры протокола, то нам надо их знать заранее и ввести в программу:
Подключение к модулю IO в программе
Если по какой-то причине мы забыли все настройки модуля (например нам подарили БУшный модуль), то можно запустить сканирование сети. Программа найдёт всё, что может и предложит подключиться к указанному модулю. Ну а если мы совсем ничего не можем — то сам модуль ввода-вывода можно жёстко сброить на заводские установки, если установить одну из перемычек, которые находятся на нём под крышкой. Это описано в инструкции на модуль.
После того, как мы подключились к модулю, программа выдаёт нам все его настройки, которые можно прочитать и записать в модуль. Нас интересуют настройки сети: скорость обмена, сетевой адрес и всякие таймауты. Напоминаю, что у модулей есть фишка: если его не опрашивали по RS-485 указанное время, то он считает что связь оборвалась и выставляет на выходах аварийные значения, чтобы оборудование не натворило дел (сам не поехал лифт или не включились насосы и прочее). В нашем случае модуль управляет лампочками, поэтому мы выставляем все аварийные значения на ноль.
Настройки модуля релейных выходов МУ110-16Р
А некоторые модули ввода-вывода ещё и могут общаться по разным протоколам. Да и даже у самого ModBus есть парочка модификаций: RTU (устройства обмениваются двоичными даными) и ASCII (все данные гоняются в текстовом виде). Мы будем использовать более быстрый протокол ModBus-RTU.
Настройки модуля входов МВ110-16Д
Обратите внимание, что для модулей ввода есть программный фильтр дребезга контактов. Его мы тоже включаем.
Ещё у этой программы есть возможность контролировать состояние входов-выходов. С помощью этого можно отдельно протестировать каждый модуль на работоспособность.
Изучаем CodeSys
Итак, с помощью программы мы настроили все модули на одинаковые параметры связи и дали им адреса. Теперь их можно физически подключить к ПЛК, а сам ПЛК воткнуть в сетку. ПЛК ОВЕН 110 можно программировать тремя способами: через USB, через RS-232 и по сетке. Самый лучший способ из этого — программировать ПЛК по сетке, потому что в этом случае он не перезапускается, а программа заливается туда в горячем режиме. То-есть написали, загрузили, проверили. Что-то исправили? Сразу же загрузили и проверили. Если же программировать ПЛК по USB — то там надо вынимать USB-кабель после заливки программы, что адски неудобно.
Связь с ПЛК 110 по Ethernet
И теперь начинаем разбираться с CodeSys. Я скачал её прямо с сайта ОВЕНа, где она есть в русском варианте. Вообще я не люблю русские переводы специального софта, потому что переводят его те, кто ни фига не понимает в технике. Например, самый адский перевод был у AutoCad: «Вырезать, Обрезать, Растянуть, Расчленить, Взорвать». Или у P-CAD, где Net (соединение) перевели как «Сеть». Но в случае с CodeSys русский перевод мне помог разобраться в терминологии и в том, где что находится. После этого русский перевод мне уже не нужен, и я могу ориентироваться в английской среде свободно.
Сама среда состоит из дерева проекта, где несколько вкладок и элементов дерева. В них отображается как структура программы, так и всякие злобные параметры ПЛК и его внешние ресурсы. Все элементы дерева открываются кучей дочерних окон со своими настройками.
Среда разработки CodeSys v2 для ПЛК 110
Сама CodeSys поддерживает много языков программирования. В том числе и тех, на которых удобно программировать логические реле.
Пример проекта на CodeSys на нескольких языках одновременно
Например, можно программировать при помощи блок-схем (CFC). Это как нам в школе алгоритмы учили рисовать в стиле «Начало => Ввод данных => Если .. то => иначе => Конец». Тут это рисуется при помощи блоков:
Пример последовательных логических схем (CFC)
А можно програмировать функциональными блоками (FBD), как на логических реле. В этом случае схема исполняется не последовательно как в CFC, а по сигналам, как в обычной цифровой логике на микросхемах:
Пример разработки на функциональных блоках (FBD)
Для тех, кто переходит с обычных релюшек и автоматики есть возможность писать всё в релейной логике LD, LAD. Тогда всякие сигналы описываются контактами, которые включают или выключают реле:
Пример разработки на релейно-контактной схеме (LD)
А ещё есть язык инструкций IL. Он подойдёт тем, кто любит суровый ассемблер. Смотрите, как он похож на него же:
Пример разработки на языке инструкций (IL)
А на мой взгляд самый удобный язык для сложных задач — это обычный текст ST, который похож на смесь СИ и Pascal одновременно:
Пример разработки на редакторе кода (ST)
Тут тебе есть и комментарии, и возможность написать любые условия.
Внутри CodeSys можно совмещать все эти языки и создавать свои функциональные блоки. Например, вы можете на ST написать сложный блок, который чего-нибудь вычисляет и выдаёт на выходе логическое значение 1 или 0. А потом взять язык FBD и из этих блоков составить «простую» логическую схемку.
Распределяем ресурсы ПЛК
Наше программирование, конечно же, тесно связано с железом. И наша среда CodeSys должна знать то, какие железо мы сейчас используем. Это конечно же понятно: в разных ПЛК есть разное количество памяти, портов ввода-вывода и прочих штуковин.
Поэтому новый проект всегда начинается с выбора платформы. На английском это называется Target. Сама среда никогда не будет знать о всяких ОВЕНах и других ПЛК. Изначально она знает только о некоем абстрактном ядре «3S CodeSys». Чтобы она узнала про наши ПЛК, нам надо пойти на сайт разработчика и скачать оттуда Target-файлы для наших ПЛК.
После этого Target’ы загружаются в CodeSys (на версии 2 этот процесс адски мутный, неочевидный и противный), и мы наконец-то можем творить. Выбираем нужный вариант нашего ПЛК:
Выбор железа для разработки программы под ПЛК
Теперь мы сразу вспоминаем то, что ПЛК — это многозадачная система, внутри которой крутятся задачи — программы, которые что-нибудь делают. Задач может быть несколько, но для работы ПЛК нужна хотя бы одна. В CodeSys она обязана называться «PLC_PRG», и именно её нам сразу предлагают создать после выбора платформы ПЛК.
ОШИБКА: Правильно она должна называться PLC_PRG — только тогда не надо создавать задачи, и программа будет работать сразу! Позже я исправлю этот пост (дурак был в 2016)!!
Сразу же при её создании надо выбрать язык, на котором вы будете писать код. Если вы вдруг ошиблись с названием языка (я постоянно путаю IL и ST), то можно просто удалить эту задачу и создать новую с тем же именем.
Создание основной программы по умолчанию
После этого наш проект создан и среда от нас отстала. Если мы пишем на ST, то в коде PLC_PRG достаточно поставить «;» и программа откомпилируется. Но работать ничего не будет. Почему? А потому что ПЛК не знает, как к его ресурсам обращаться и чего у него вообще есть.
И вот чтобы его этому научить — надо аккуратно и внимательно разобраться с его ресурсами и с тем, как туда прописывать внешние модули ввода-вывода. Всё это кажется лёгким только тогда, когда сам всё понял. А когда смотришь на конфигурацию ПЛК в самый первый раз, то от неё взрывается голова. Я разбирался с этим дней пять, потому что ещё и инструкция по работе с CodeSys на сайте ОВЕНа говорит «Сделайте это и то», но не говорит ПОЧЕМУ так надо делать. Я этот недостаток хочу исправить и потом пошлю ОВЕНу ссылку на эти посты.
Для того, чтобы CodeSys знала про все-все ресурсы и ввод-вывод всей системы на базе ПЛК, это всё надо прописать руками. То-есть, вся конфигурация системы прописывается в том же программном коде жёстко. И поэтому когда вы выбираете всякие модули ввода-вывода, назначаете им параметры связи и адреса, вы должны понимать, что это останется навсегда. А если надо будет поменять адрес устройства — то вам надо будет перекомпилировать проект.
Общий концепт ресурсов и обращения к ним сделан при помощи неких адресов. Адреса эти вычисляет сама среда по нашей конфигурации ПЛК. На скриншоте ниже эти адреса начинаются со знаков «AT %». Чтобы программист не мучился с этими адресами, он может создать обычные программные переменные, которые будут использовать вместо адресов понятные имена типа «WaterPump», которая на самом деле будет говорить о внешнем выходе по адресу типа «%QW6.3.0.0».
Поэтому первой нашей задачей будет изучить окошко «Конфигурация ПЛК» и то, что там можно делать. Давайте на него посмотрим:
Конфигурация ПЛК и его ресурсов
Слева у нас есть дерево, в котором будет показываться вся-вся конфигурация нашей системы. А справа от дерева появляются разные параметры, которые можно настраивать. Там же можно задать для самих себя понятные имена и названия всех объектов системы, чтобы не путаться.
Слева у меня сейчас развёрнута конфигурация самого ПЛК. Чего у нас тут есть? Есть два быстрых входа, 16 обычных входов (в сумме — 18). Так же есть четыре быстрых выхода и 10 обычных — в сумме 14. Это соотвествует тому, что у этого ПЛК действительно есть. Дополнительно есть Special Input — это кнопка «F1» на самом ПЛК и Special Output — это пищалка ПЛК. Если туда записать «1», то пищалка будет пищать и привлекать наше внимание к системе.
Около этих ресурсов есть обозначение «[FIX]» или «[SLOT]». Если написано «SLOT», то это означает что программно можно заставить среду воспринимать эти входы или выходы не как дискретные 1..0, а например как энкодер или ШИМ-регулятор. Это сделано для того, чтобы облегчить программирование с заставить ПЛК максимально автоматически обрабатывать данные с IO, не нагружая этим программиста. Соотвественно те ресурсы, которые «FIX» изменять нельзя и они всегда будут теми, какие они и есть.
Около каждого ресурса как раз и указан его адрес, по которому к нему можно обращаться. Вот если мы хотим программно включить быстрый выход 2, то нам нужен адрес «%QX2.0». Про то, как назначать адреса переменным, я расскажу позже.
Для каждого ресурса есть свой набор настроек. Вот например для выходов можно точно так же настроить безопасные значения, как и для внешних модулей ввода-вывода:
Настройка безопасных значений выходов ПЛК
Идём дальше! Это-то мы изучали внутренние ресурсы, которые есть на борту ПЛК. А как же нам добраться до внешних ресурсов? Вот у нас есть аж три модуля ввода-вывода. Но где же они?
А нигде! Их надо добавить ручками. Логика тут простая и технарская: то, что у тебя есть физически, должно быть и в программе. Давайте вспомним, чего у нас есть физически? Модули? Неа! У нас есть протокол ModBus!
Поэтому мы кликаем на самом ПЛК и выбираем из меню этот самый ModBus (Master) вот так, как показано ниже. Master — потому что главный у нас в сети ПЛК, и именно он будет управлять всеми другими модулями. Так же там есть ещё и другие протоколы обмена для разных вариантов сети. Например можно было вообще взять собственный протокол «ОВЕН» и построить сетку на нём.
Добавляем внешний интерфейс связи
Обратите внимание, что этот протокол сейчас не привязан к физическим проводам ПЛК! После того, как мы добавим наш ModBus, система просто будет знать что есть некий абстрактный протокол, по которому гоняются байтики. Но через какой порт ПЛК это будет работать — она пока ещё не знает!
Что же делать? Придётся научить нашу систему нужному порту. Для этого мы разворачиваем дерево под нашим ModBus’ом и видим искомое. По умолчанию система подставила самый первый попавшийся интерфейс ПЛК — «Debug RS-232». Мы видим около него волшебную надпись «SLOT». Кликаем по ней правой кнопкой мыши и — вуаля! Мы можем заменить его на нужный на RS-485.
Выбираем тип интерфейса RS-485
Причём список замены будет только из тех вариантов, которые действительно есть в именно этом ПЛК. Например в некоторых ПЛК бывает аж два интерфейса RS-485, на которых можно построить две разные сетки ModBus.
И вот только теперь мы дошли до физического уровня: собственно самого RS-485. Для него у нас есть настройки протокола обмена и параметров связи. Если вы помните, то мы все модули конфигурировали на ModBus RTU и скорость обмена 9600. Теперь вставим эти же настройки в нашем ПЛК:
Настраиваем параметры протокола интерфейса
ПЛК сам следит за работой этого протокола и этого интерфейса. Нам не надо программно включать или отключать опрос модулей: он будет делаться автоматически, если есть хоть один внешний модуль, который надо опрашивать.
Вот сейчас мы как раз и добавим наши внешние модули. Сам ОВЕН рекомендует добавлять свои модули как «Unversal ModBus Device» — некое абстрактное устройство. Сделаем так:
Добавляем устройство ModBus
Теперь у нас появился некий внешний модуль, который подключен на нашу шину RS-485 и будет работать по ModBus. Но напоминаю вам то, что протокол ModBus — это просто способ читать и записывать байты в и из устройств. И более ничего. А вот что значит каждый байт и та область памяти, куда его надо записать/прочитать — знает разработчик модуля и разработчик системы на базе ПЛК.
Для каждого модуля надо будет задать параметры связи. Для нас это адрес модуля (ModuleSlaveAddress) и время опроса его контроллером. Контроллер будет автоматически общаться с модулем раз в столько миллисекунд, сколько мы укажем.
Настраиваем параметры устройства
Время опроса позволяет снизить нагрузку на шину связи. Например если модуль управляет лампочками освещения, то его можно опрашивать реже, отдавая время шины каким-нибудь более быстрым модулям аналогового регулирования или кнопкам для управления этим светом (чтобы быстрее их опрашивать).
Ну добавили мы модуль, и чего? А как система узнает как рулить его входами или выходами? Вообще, откуда она узнает, где они у него находятся? А узнает она это через человека, который достанет и прочитает инструкцию на модуль. Для любого устройства с протоколом ModBus производитель даёт таблицу, в которой указаны все адреса его регистров. Выглядит эта таблица вот таким образом, например:
Пример регистров устройства из документации
Тут нас интересует два момента. Так как это модуль ввода, то нам надо получать значения его входов. Производитель, чтобы не гонять по сети тьму байтов, упаковал все 16 входов в 16 бит — в два байта, в тип WORD. Значит, нас интересует регистр номер 51, который надо будет читать из модуля. Следующий момент, который нам важен — это проверить команду, которая используется для записи-чтения данных в этот модуль. Иногда они могут отличаться от стандартных.
Отлично! Вот теперь мы всё знаем, чтобы добавить это в наш ПЛК. Тыкаем менюшкой на нашем модуле и выбираем, что добавить. типы в CodeSys называются так:
- 8 Bit — BYTE, байт
- Register — INT, WORD — два байта
- 32 Bit — DWORD, четыре байта
Так как в документации видно что мы читаем двухбайтовое слово — то нам нужен тип «Register input»:
Добавляем регистр устройства в конфигурацию
Теперь задаём параметры именно для этого кусочка: адрес регистра, который читаем и команду, которой читаем.
Настраиваем адрес регистра и способ его опроса
Вот теперь (см. скриншот сверху) ПЛК знает что у нас есть протокол MoBus-RTU на основе интерфейса RS-485, на котором висит устройство с адресом «1», из которого мы читаем два байта из ячейки «51».
А вот как выглядит конфигурация ПЛК для моей системы. У меня стоит один модуль ввода на 16 входов и модуль вывода на 16 выходов. И на будущее для диммирования света стоит модуль аналогого вывода.
Полный список внешних устройств и внешних регистров
Назначение переменных в ПЛК
Вот теперь у нас есть все-все адреса наших ресурсов. Чтобы нам было удобно ими пользоваться, мы заведём для них программные переменные. Это тоже ручная работа, в которой требуется внимательность. А ещё её в CodeSys v2 делать не очень удобно, потому что в табличке для ввода переменных не меняется ширина колонок.
Использовать в программах прямые адреса — ПЛОХО, потому что программа будет зависеть от них. А адреса могут меняться, если вы добавите в дерево новое устройство или что-то поменяете! Ниже будет показан способ, как присвоить переменные объектам в дереве напрямую.
Посмотрим на конфигурацию ПЛК и выцепим оттуда адреса всех наших входов и выходов. Я их подчеркнул красным:
Адреса переменных внутреннего ввода-вывода
А теперь создадим переменные для них. Для этого мы идём в раздел «Глобальные переменные» и начинаем заполнять табличку примерно так:
Создаём переменные внутреннего ввода-вывода
Видите? Мы указываем название переменной и прописываем её адрес и тип. И теперь чтобы включить внутренний выход 1, нам надо написать «MOuts0_1 := TRUE;».
Проделаем то же самое с внешними устройствами. Тут адреса становятся длиннее:
Адреса переменных внешнего ввода-вывода
И редактировать их не совсем удобно. Заполняем переменные:
Создаём переменные внешнего ввода-вывода
Кроме переменных, которые красиво связывают адреса ресурсов и код, можно насоздавать своих собственных переменных для любых задач. Всё эти переменные будут глобальными: они будут доступны из любого места любой программы.
Ну и если теперь залить эту пустую программу (в коде мы ничего не написали) в ПЛК, то он сразу же примется опрашивать наши модули. На фотке ниже я случайно заснял момент, когда ПЛК опрашивает один из модулей.
После запуска ПЛК начинает опрашивать все внешние устройства
Программируем
А дальше начинается колдунство. Мне надо было на тот момент вообще научиться работать с CodeSys. Я тогда не разобратся, можно ли адресовать отдельные биты переменных и написал простые участки кода, которые приводили все переменные внешних ресурсов в удобоваримый для меня код.
Видите, я просто беру значение бита нужной мне переменной (от входа) и заношу его в глобальную переменную, которая уже обозначает конкретную кнопку управления светом.
Код преобразования входных переменных к типу BOOL
То же самое я проделал с выходами:
Код преобразования выходных переменных из типа BOOL
Теперь можно кодить. Для теста я сделал самое простое: нажимаем кнопку — срабатывает выход. То-есть мы просто присваиваем выход входу и наслаждаемся работой мощного ПЛК
Кусочек прошивки для управления освещением на ПЛК
Ещё я нашёл в Сети пример того, как сделать на CodeSys импульсное реле и тоже его протестировал. Кстати, пример лежит на форуме ОВЕНа.
На форуме у них не совсем приятно. Там тусуются ушлые товарищи (не из ОВЕНа), которые в личке каждому новому пользователю сразу предлагают услуги по разработке и поддержке решений на ПЛК. Мне один такой тоже написал. Я ради прикола послал его нафиг и расспросил, почему он это сделал. Ответ был типично маркетологовский: «Ну так если ты тут зарегался, значит ты можешь быть моим клиентом».
В итоге товарищ был послан далеко и надолго. Особенно после того, как стал угрожать мне завалить мой блог за посыл нахуй. М-да. Страшно, в общем, на форуме ОВЕНа.
Задачи
Кратко покажу, чего есть из задач и чего с ними можно делать. Напоминаю: задача — это кусок программы, который ПЛК будет выполнять через указанное время. Есть системные события, которые показаны ниже (запуск ПЛК, остановка ПЛК, перед и после сброса):
Настройка задач в ПЛК
А мы хотим навесить на ПЛК свои собственные задачи. Вот у меня их получилось две штуки. Одна считает импульсы со счётчиков воды, а другая обслуживает управление освещением.
Для каждой задачи задаётся время её исполнения. Оно может измеряться в миллисекундах, часах и даже днях.
Конфигурация задачи в ПЛК
Ну а для самой задачи задаётся то, что будет выполняться:
Настройка вызова подпрограммы в задаче
Связь с ПЛК и заливка программы
Ну и теперь нам осталось только залить нашу программу в ПЛК. Для этого мы идём в меню «Онлайн -> Параметры связи» и создаём там подключение по сетке через протокол TCP.
Настройка связи с ПЛК по протоколу IP
После этого достаточно выбрать команду подключения к ПЛК:
Начинаем подключение к ПЛК
CodeSys устанавливает связь с ПЛК и спрашивает нас о том, что нам надо сделать с программой. Если ПЛК только с завода и там нет никакой программы — то CodeSys предложит загрузить новую программу в ПЛК. А если программа в ПЛК уже была, то система предложит загрузить новую или перезаписать программу полностью:
Запрос среды разработки о загрузке программы в ПЛК
У ПЛК и здесь всё отличается от логических реле. В логическом реле программа загружается навсегда и будет работать после выключения и включения питания реле. А у ПЛК программа загружается просто в память и работает только для момента выключения питания ПЛК. Это сделано специально, чтобы можно было отлаживать программу и не испортить рабочую систему и программу. Скажем, можно поиграться с другой версией программы, а потом передёрнуть питание — и ПЛК будет работать по старому.
Если же мы хотим записать нашу программу в ПЛК навсегда (чтобы она работала при следующих включениях питания), то нам надо выбрать пункт «Создание загрузочного проекта». В этом случае программа без запросов записывается в ПЛК и будет выполняться при следующем включении его питания.
Создание загрузочного проекта в ПЛК
Из дополнительных возможностей можно загрузить в ПЛК исходники проекта или любой файл (размером несколько мегабайт). Это полезно, если мы хотим оставить внутри ПЛК архив документации по всему проекту.
При подключенной связи с ПЛК можно наблюдать как и чего работает и производить отладку программы. Вот как выглядит это на нашей:
Работа среды CodeSys в режиме отладки программы
Собственно по программированию всё. Если сказать всё сжато, то для того чтобы начать работать с ПЛК, надо занести в него все его ресурсы и внешние модули. После этого можно назначить переменные по адресам и писать обычный программный код.
Библиотеки
А ещё под CodeSys есть много библиотек с готовыми функцями. Самая известная среди них — библиотека OSCAT. Я её скачал и нашёл там много интересного. Например вот модуль CLICK, который может определять одинарное, двойное и тройное нажатие на кнопку. При помощи него можно делать например так, чтобы если мы погасили весь свет одной кнопкой, то при двойном нажатии на неё весь свет включился там же, где и был включен.
Пример из библиотеки OSCAT: Определение количества нажатий
А вот навороченный диммер с кучей предустановок и возможностей. Сигнал с диммера можно направить на модуль аналогового вывода или на диммер, который управляется по Modbus напрямую и управлять освещением.
Пример из библиотеки OSCAT: Многофункциональный диммер
Ну а я же сделал для заказчика простую программу включения и выключения света и реализацию функции защиты от протечек. Про это я расскажу позже в третьей части статьи.
ОВЕН ПЛК110 – линейка программируемых моноблочных контроллеров с дискретными входами/выходами на борту для автоматизации средних систем.
Оптимальны для построения систем автоматизации среднего уровня и распределенных систем управления.
Рекомендуется к использованию
- В системах HVAC
- В сфере ЖКХ (ИТП, ЦТП)
- В АСУ водоканалов (водоподготовка, насосные станции)
- Для управления малыми станками и механизмами
- Для управления пищеперерабатывающими и упаковочными аппаратами
- Для управления климатическим оборудованием
- Для автоматизации торгового оборудования
- В сфере производства строительных материалов
Отличительные особенности линейки
- Мощные вычислительные ресурсы и большой объем памяти.
- Наличие дискретных входов/выходов на борту контроллера.
- Наличие последовательных портов (RS-232, RS-485) на борту контроллера.
- Наличие порта Ethernet для включения в локальные или глобальные сети верхнего уровня.
- Поддержка протоколов обмена Modbus (RTU, ASCII), ОВЕН, DCON.
- Возможность работы напрямую с портами контроллера, что позволяет подключать внешние устройства с нестандартными протоколами.
- Контроллер имеет встроенные часы, что позволяет создавать системы управления с учетом реального времени.
- Встроенный аккумулятор, позволяющий организовать ряд дополнительных сервисных функций: возможность кратковременного пережидания пропадания питания, перевод выходных элементов в безопасное состояние.
Обозначения при заказе |
Линейка контроллеров ОВЕН ПЛК110
Параметр |
ПЛК110-30 |
ПЛК110-32 |
ПЛК110-60 |
Количество входов |
18 |
18 |
36 |
Быстрых входов |
2 |
2 |
4 |
Быстрых счетчиков |
2 |
2 |
4 |
Энкодеров |
1 AB |
1 AB |
1 ABZ или 2 AB |
Количество выходов |
12 |
14 |
24 |
Быстрых выходов (для ПЛК110 с транзисторными выходами) |
4 |
4 |
4 |
Количество портов RS-485 |
2 |
1 |
2 |
Поддерживаемые интерфейсы и протоколы
Протокол | Интерфейс | Применение |
ОВЕН | RS-232
RS-485 |
Поддержка модулей ввода/вывода ОВЕН Мх110
Работа в сетях ОВЕН совместно с ТРМ2хх |
Modbus RTU
Modbus ASCII |
RS-232
RS-485 |
Поддержка модулей ввода/вывода и операторских панелей (например, ОВЕН СП3хх), связь со SCADA-системами |
Modbus TCP | Ethernet 10/100 Mbps | Связь со SCADA-системами |
DCON | RS-232
RS-485 |
Поддержка модулей ввода/вывода ICP DAS I-7xxx, АDAM-4xxx, операторских панелей |
GateWay (протокол CODESYS) | RS-232
Ethernet 10/100 Mbps USB-Device |
Программирование контроллера, отладка пользовательской программы
Связь с контроллерами других производителей на базе CODESYS. Работа с OPC-сервером CODESYS |
Mass Storage Device | USB-Device | Работа с файлами архивов данных и файлами проекта |
Контроллеры данной линейки также поддерживают работу с нестандартными протоколами по любому из портов, что позволяет подключать такие устройства, как электро-, газо-, водосчетчики, считыватели штрих-кодов и т.п.
Программирование
Программирование контроллеров осуществляется в профессиональной распространенной среде CODESYS v.2.3.x, максимально соответствующей стандарту МЭК 61131:
- поддержка 5 языков программирования, для специалистов любой отрасли;
- мощное средство разработки и отладки комплексных проектов автоматизации на базе контроллеров;
- функции документирования проектов;
- количество логических операций ограничивается только количеством свободной памяти контроллера;
- практически неограниченное количество используемых в проекте счетчиков, триггеров, генераторов.
Интерфейсы для программирования и отладки: Ethernet, USB, RS-232 (Debug).
При покупке программируемого контроллера ОВЕН ПЛК предоставляются БЕСПЛАТНО
- Среда программирования CODESYS
- Готовые библиотеки программных блоков
- Специальные сервисные утилиты для работы с ОВЕН ПЛК
- Руководство пользователя и обучающие видеокурсы
- Для организации обмена с верхним уровнем предоставляются бесплатные OPC-драйверы, OPC-драйвер Gateway (от CODESYS) и OPC-драйвер Modbus (от ОВЕН)
|
|
Документация
Если вы нашли ошибку, пожалуйста, выделите фрагмент текста и нажмите Ctrl+Enter.
Контроллер / Характеристика |
ПЛК110-30 |
ПЛК110-32 |
ПЛК110-60 |
ОБЩИЕ СВЕДЕНИЯ |
|||
Габаритные размеры |
140х110х73 мм |
208х110х73 мм |
|
Степень защиты корпуса |
IP20 со стороны передней панели, IP00 со стороны клемм |
||
Температура эксплуатации |
от минус 10 до + 55 °С |
||
Светодиодная индикация на передней панели |
Состояние входов, состояние выходов, режим работы, наличие связи, заряд встроенной батареи |
||
Масса, не более |
0,6 кг |
1 кг |
|
ПИТАНИЕ |
|||
Напряжение питания: | |||
ПЛК110-24.Х.Х-Х |
От 18 до 28 В постоянного тока (номинальное 12 В или 24 В) |
||
ПЛК110-220.Х.Х-Х |
От 100 до 240 В переменного тока (номинальное 220 В) |
||
Потребляемая мощность: | |||
ПЛК110-24.Х.Х-Х, не более |
25 ВА |
35 ВА |
|
ПЛК110-220.Х.Х-Х, не более |
30 ВА |
40 ВА |
|
Параметры встроенного источника питания: |
Выходное напряжение 24±3 В, ток не более 620 мА |
||
ВЫЧИСЛИТЕЛЬНЫЕ РЕСУРСЫ И ДОПОЛНИТЕЛЬНОЕ ОБОРУДОВАНИЕ |
|||
Центральный процессор |
RISC-процессор, 32 разряда, 200 МГц |
||
Объем и тип оперативной памяти |
8 МБ, из них 1МБ для кода пользовательской программы, 128кБ для переменных пользовательской программы |
||
Объем и тип энергонезависимой памяти |
4 МБ, из них 3МБ доступно для хранения файлов и архивов |
||
Размер и тип Retain-памяти |
не более 16 кБ (по умолчанию задано значение 4 кБ) |
||
Время выполнения одного цикла программы |
Установленное по умолчанию (стабилизированное) – 1000 мкс* Возможность организации вызова подпрограмм по прерыванию – от 50 мкс |
||
Дополнительное периферийное оборудование |
Часы реального времени с собственным источником питания |
||
* Время выполнения одного цикла программы настраивается в окне PLC Configuration в среде CODESYS. Подробнее см. п.1.1 документа «PLC_Configuration_OWEN» на компакт-диске, входящем в комплект поставки. |
|||
ЦИФРОВЫЕ (ДИСКРЕТНЫЕ) ВХОДЫ |
|||
Количество дискретных входов |
18 |
36 |
|
– из них быстродействующих |
2 |
4 |
|
Тип подключаемых устройств |
коммутационные устройства (контакты кнопок, выключателей, герконов, реле и т.п.); датчики, имеющие на выходе транзистор n-p-n или p-n-p-типа с открытым коллектором; дискретные сигналы 24±3 В |
||
Гальваническая развязка дискретных входов |
Групповая |
||
Электрическая прочность изоляции дискретных входов |
1500 В |
||
МИНИМАЛЬНАЯ ДЛИТЕЛЬНОСТЬ ИМПУЛЬСА, ВОСПРИНИМАЕМОГО ДИСКРЕТНЫМИ ВХОДАМИ |
|||
Быстродействующие
DI1-DI2 – для ПЛК110-30, ПЛК110-32 DI1-DI4 – для ПЛК110-60 |
– 50 мкс в режиме счетчик импульсов |
||
Обычные
DI3-DI18 – для ПЛК110-30, ПЛК110-32 DI5-DI36 – для ПЛК110-60 |
3,3 мс (300 Гц) |
||
Напряжение питания дискретных входов |
24 ± 3 В |
||
Напряжение «логического нуля» |
минус 3…5 В |
||
Максимальный ток «логического нуля» |
1,5 мА |
||
Напряжение «логической единицы» |
15…30 В |
||
Максимальный ток «логической единицы» |
4…9 мА |
||
ЦИФРОВЫЕ (ДИСКРЕТНЫЕ) ВЫХОДЫ |
|||
Количество и тип дискретных выходов: | |||
– Для модификации с релейными выходами |
12 |
14 |
24 |
– Для модификации с транзисторными выходами |
12, из них 4 быстродействующих |
14, из них 4 быстродействующих |
24, из них 4 быстродействующих |
Гальваническая развязка дискретных выходов |
Индивидуальная или групповая (часть выходов собраны в группы по 2 или 4 шт. и имеют общую клемму) |
||
Электрическая прочность изоляции дискретных выходов |
1500 В от схемы прибора; 500 В между выходами (или группами выходов) |
||
ПАРАМЕТРЫ РЕЛЕЙНЫХ ВЫХОДОВ |
|||
Время переключения выходов |
50 мс |
||
Максимальный ток коммутации |
не более 3 А (при напряжении не более 250 В переменного тока и cos j > 0,4); не более 3 А (при напряжении не более 30 В постоянного тока) |
||
Механический ресурс реле |
не менее 300 000 циклов переключений при максимальной коммутируемой нагрузке; не менее 500 000 циклов переключений при коммутации нагрузки менее половины от максимальной |
||
ПАРАМЕТРЫ ТРАНЗИСТОРНЫХ ВЫХОДОВ |
|||
Время переключения выходов
– быстрые (DO1-DO4) – обычные |
20 мкс 20000 мкс |
||
Максимальный ток транзисторного выхода |
не более 400 мА (при напряжении не более 30 В) |
||
Напряжение питания дискретных выходов DO1…DO4 |
от 12 до 30 В |
||
Ток, потребляемый дискретными выходами DO1…DO4 |
не более 10 мА на все входы |
||
ПОДДЕРЖИВАЕМЫЕ ИНТЕРФЕЙСЫ И ПРОТОКОЛЫ |
|||
Интерфейсы связи | Количество | Протоколы (тип связи и особенности работы) | Скорости передачи |
RS-485 |
2 (1 – для ПЛК110-32) |
Modbus-RTU, Modbus-ASCII, DCON, ОВЕН | 2400, 4800, 9600, 14400, 19200, 28800, 38400, 57600, 115200 бит/с |
RS-232 |
1 |
Modbus-RTU, Modbus-ASCII, DCON, ОВЕН | 1200, 2400, 4800, 9600, 14400, 19200, 28800, 38400, 57600, 115200 бит/с |
RS-232 Debug |
1 |
Modbus-RTU (только slave),
Modbus-ASCII, DCON, ОВЕН, GateWay |
1200, 2400, 4800, 9600, 14400, 19200, 28800, 38400, 57600, 115200 бит/с |
Ethernet 100 Base-T |
1 |
Modbus-TCP, TCP-IP, UDP-IP,
CODESYS Network Variables (over UDP), Gateway |
10, 100 Мбит/с |
USB Device |
1 |
CDC |
|
ПРОГРАММИРОВАНИЕ КОНТРОЛЛЕРА |
|||
Среда программирования |
CODESYS v2.3 |
||
Интерфейсы для связи со средой программирования CODESYS |
RS-232 Debug; USB Device; Ethernet |
Схемы подключения ОВЕН ПЛК110-30
Схемы подключения ОВЕН ПЛК110-32
Схемы подключения ОВЕН ПЛК110-60
Подключение входных устройств и схемы входных элементов контроллера ПЛК110
Схема подключения контактных датчиков (Sl-Sn) к входам ПЛК110 |
Обе схемы равнозначны, может использоваться любая. При применении контактных датчиков совместно с датчиками, имеющими на выходе транзисторный ключ, схема подключения должна определяться типом транзисторных датчиков.
Суммарный ток потребления всех внешних датчиков и всех подключенных дискретных входов (7 мА на вход) не должен превышать 620 мА. Если потребление датчиков и входов больше указанного, то для питания датчиков следует использовать внешний блок питания требуемой мощности.
Кабели
Наименование |
Изображение |
Комментарии |
Длина, м |
КС1 | Применяется для прошивки и программирования контроллеров:
– ПЛК110 (порт RS-232 DEBUG) |
1,5 2,7 |
|
КС2 | Применяется для соединения контроллеров ПЛК110 (порты RS-232 DEBUG и RS-232) с панелями оператора ИП320 (порт RS-232), СП270, СП307, СП310 (порт PLC, RS-232) |
1,5 2,7 |
|
КС3 | Применяется для соединения контроллеров ПЛК110 (порты RS-232 DEBUG и RS-232) с модемом ПМ01[M02] (порт RS-232, соединитель Х2) |
1,5 |
Комплектность поставки ПЛК110
- Прибор ПЛК110
- Диск с ПО
- Кабель для программирования КС1
- Паспорт и руководство по эксплуатации
- Гарантийный талон