На протяжении нескольких месяцев я делюсь историей и подходами решению задач собственной разработки промышленного контроллера. Вернее - платформы для разработки ПЛК на подобии Codesys. Название моего проекта 3o|||sheet (читается как - Зошит).
Вот чтоб сразу было понятно - я не создаю физические ПЛК. Часто пишут про помехоустойчивость, Arduino/ STM32 не под 24V и прочее. Codesys - не продают ПЛК и не создают железо (насколько я знаю) это программная платформа которую устанавливают в - свое железо производители ПЛК. У меня тот же случай.
Моя разработка это: Среда IDE , с собственным графическим движком отрисовки схем. Cвой компилятор (самая сложная и умная часть). И среда выполнения на железе (самая примитивная часть - за нее все думает компилятор на этапе сборки.
Разрабатываю - программную часть, так как считаю что надежность и экосистема программной работы это 99% успешности проекта.
Работа до создания ПЛК и откуда истоки и идеи.
Лет 6 назад, когда работал инженером - системным программистом на крупном предприятии я и познакомился с большим производством. Большое количество угольных шахт раскиданных на многие километры. Десятки подземных комбайнов , тысячи гидравлических стоек, все это генерировало миллионы значений в сутки. Системным программистом я был плохим (вернее - системным администратором), другое дело - поиск и разработка алгоритмов по визуализации всех этих миллионов значений с OPC серверов на экране.
Gatherlog (Гезерлог)- моя SCADA и система диспетчеризации.
Стоит отметить, у меня два образования, это университет, инженерно-технический, приборостроения. И Художественный институт - живопись графика. Разработка графических визуализаций - моя естественная работа, которую я лучше знал со старта (минимум программного опыта), чем более опытные разработчики с десятками лет стажа. Все это и вылилось в в последствии разработку собственного графического движка для визуализации промышленности.
Мой проеккт Gatherlog (.Net Core) можно разделить на функционал:
1) набор абстракций и правил, по управлению графикой - данными с оборудования. подходит дл абсолютно любого оборудования и любой сложной анимации (кроме физики конечно). Есть примитивы движений (перемещение, вращение, моргание, изменение размера, смена кадров- ваританты), комбинируя эти примитивы (как матрешку, друг в друга) можно добиться любого сложного движения. Не только анимировать шкалу деления но и сложные манипулятор роботов с любым количество состявляющих.
2) Система отчетов по работе оборудования и общих отчетов (работа/простои / обычные графики)
3) интерпретатор работающий в SCADA позволяющий выполнять алгоритмы написанные пользователем (то есть, превращает SCADA в серверный ПЛК). В последствии эти практики я оптимизировал до уровня микроконтроллера.
4) Работа с базами данных
Если брать WEB разработку, то сам движок реализованный так же на Javascript занимает всего лишь 500 строк кода. Хотя как то встречал компанию, которая делала визуализации, применяя полноценный игровой Unity 3D ! для подобного.
В самой первой статье по разработке ПЛК я упоминал что являюсь ценителем оптимизации, всегда искал закономерности в процессах чтоб вывести общую формулу на подобии y=x+2(sqrt(Ad^2 ... А не использовать if/else на все варианты. Поэтому, что касается логики, у меня программа всегда занимаала меньше строк кода чем у других.
Все эти наработки и графическая библиотека в последствии перешла в нативную разработку среды программирования для ПЛК (LD FBD, схемы). А графический движок реализован на C# , Java, WinAPI, и подготавливаю его для Микроконтроллеров способного работать на небольших дисплеях.
В данном посте не все описано, но я периодически буду публиковать те или другие моменты по разработке.
И помни дорогой друг. Любая "поделка" становится "настоящей" если ее выпускает юридическое лицо. (с) Я.
Задавайте вопросы в комментариях и на почту: zoshytlogic@gmail.com
Будем считать, что у вас всё установлено. По установкам ПО можно найти документацию и мануалы.
Настройки в ПЛК с CODESYS 3.5
Суть следующая - нам нужно сделать ПЛК с Modbus TCP Slave. В моем случае ПЛК200 использует оба порта Ethernet. 1 опрашивает модуль - является мастером. 2 порт работает в режиме Slave. Для того чтобы работал 2 порт в режиме LAN нужто зайти в его веб-настройки и отконфигурировать.
Дальше добавляем модуль Ethernet.
Нужно связаться с ПЛК и выбрать по какому порту ему отдавать.
Выбираем преднастроенный порт.
Добавляем устройство.
Выбираем TCP Slave.
Далее залезаем в его настройки, вводим количество регистром и ставим галочку на запись, если нужно read\write.
Во вкладке соотнесение входов выходов вносим переменную. Переходим на следующий этап.
Настройки в SCADA SimpLight 5
Далее работаем со SCADA. Будем считать, что она скачана, установлена и запущена Среда разработки.
Список различных драйверов. Выбираем напрямую Modbus Драйвер, заходим в настройки.
Настраиваем Узел. В моем случае IP 192.168.1.10.
Вносим тег. У ПЛК 200 в режиме TCP Slave адресация начинается с 0.
Перетаскиваем теги в Проект.
Прежде чем запускать сервак. Нужно для него создать профиль и нажать птичку, что именно этот сервер мы используем.
После этого сохраняем проект и запускаем сервер.
Ставим маленькие галочки - чего опрашивать, зеленую стрелочку Пуск. И наблюдаем ТРИ топора, и что вообще чё то включено.
Летом 2025 Овен презентовал некую новинку, а именно "современный конфигурируемый контроллер с питанием 24 В для управления приточными и приточно-вытяжными вентиляционными установками любого типа", он же "АЙРА360 конфигурируемый контроллер вентиляции". В декабре 2025 это изделие попалось мне в ТЗ на разработку схемы щита управления довольно простой приточно-вытяжной вентиляционной установкой. Заказчик захотел что-то простое, понятное, наше. Ну а я отнесся с любопытством, как человек, применявший в свое время, Siemens ACX36 и перейдя на свои собственные программы для Carel в дальнейшем. В общем, как обычно - ничего не предвещало, да и конфиг устаноки весьма простой: приточная система с воздушной заслонкой с концевиками, ЕС-мотор, ЭК на 4 равные ступени мощности, вытяжная система с ЭД через ПЧ на фикс. скорости (ну, так надо им).
К оборудованию Овен я отношусь нормально, без неприязни, предвзятости и типичного "а, овно". Документация, чертежи внешнего вида, схемы подключения - все это привычная среда поддержки для их продукции. Описательная часть алгоритмов, особенно для ТРМ - отдельный вид искусства, древнее знание о нормальной работе технического писателя. И вот на фоне этого всего "привычного окружения" я не нахожу на сайте для этой "Айра360" ни dwg-чертежа прибора, ни нормальных схем подключения ко входам/выходам, ни хоть сколько нибудь внятного объяснения формирования конфигурации. Есть что-то типа руководства пользователя, ссылка на программу-конфигуратор и фотография внешнего вида прибора.
Ок, скачал РП, установил конфигуратор, выполнил в нем задание конфигурации прибора в соотв. с оборудованием вент. установки. Получил на выходе некую таблицу назначения вх/вых. На этом этапе у меня уже появились некоторые сомнения в адекватности конфигурации, но как гласит руководство пользователя "конфигурация вх/вых создается автоматически и не может быть изменена пользователем". Эх, ну нет так нет. Стал разбираться - что же там такого родилось, что мне предстоит включить в схему щита управления.
И, внезапно для меня, обнаружилась неприятная особенность аппаратной реализации прибора и заданной ему конфигурации - реле (DO) объединены в группы по 2шт. с общим выводом и на одно такое реле выведен сигнал неисправности, а на другой реле выведена команда управления воздушной заслонкой. Привод заслонки на 220В, принят проектом ОВ и ничего я не поменяю. А индикаторная лампа "Неисправность" автоматически становится 220В, ведь Com общий. Ладно, допустим, хоть я и не применяю 220В для вторичных цепей, стараюсь уйти на 24АС через трансформатор 380/24В. Но что у нас получается дальше ? А дальше предлагаю посмотреть в итоговую конфигурацию для начала
Конфигурация прибора, сформированная автоматически
Дискретные и аналоговые входы назначены как назначены, тут ничего не мешает. А вот с дискретными выходами что-то не то: не вижу команды Пуск ст.1 ЭК, команда Пуск ст.4 использует группу реле, общую с командой Пуск прит.вент. Помним, что у групп реле общий провод ? При этом в самом приборе имеется 4 группы реле по 2шт. в каждой, итого 8 DO, тогда как здесь задействованы только 6 DO/3 группы. Придется ставить лишнее по сути промежуточное реле для подачи команды Пуск либо управлять сетевым контактором мотора приточного вентилятора, а ЕС-моторы этого не любят. Ну, вроде бы решить можно, чего я тут докопался, да ? А вот чего докопался - группа реле 2 (DO 3 и DO 4) это команды Пуск для ст.2 и ст.3. , а вот реле DO 5, связанное с прит. вентилятором, это команда Пуск ст.4. Ну да, да, а проблема то в чем ? Ну, собственно, вот и проблема: было бы логично, наверное, поставить общую блокировку по термостату, датчику потока воздуха и прочие защиты в цепь подачи питания контакторов включения ступеней ЭК и при аварийной ситуации отключать их скопом. Да, я помню про суммарную мощность катушек и все такое - релейные контакты выдерживают, с этим все хорошо. Да и частого аварийного отключения не жду. Итого получаем - общий провод для ст. 2 и ст. 3 и отдельный провод для ст.4. В этот отдельный провод пришлось ставить полную цепь защит просто ...да просто потому что. Ну, ок, разобрались с контакторами, запустили вентилятор, вроде почти победа ? Ну, может и почти, но нет.
Есть же еще ст. 1 и она предполагает управление через ТТР и ШИМ сигналом 10В. Внимательный читатель задаст вопрос - а где же управление контактором ст.1, вы что, никогда не видели сквозного пробоя ключей ТТР (не на корпус, самих ключей) ? Я тоже задался этим вопросом, но так и не нашел никакого упоминания о возможности управления контактором ст.1. Ну, нет так нет - завязал контактор ст.1 на цепь защиты и поставил на дверцу переключатель Нагрев для отключения контактора ст.1 и всех прочих одновременно, если нет потребности греть приток.
Да, получается, что если пользователь НЕ выключит режим Нагрев и прибор перейдет в режим Лето, то контактор ст.1 будет все также постоянно включен, ШИМ управления ТТР не будет, соотв. ТТР будет закрыта и нагрева притока не будет, наверное. Ну, не важно уже, надоело.
Смотрим на АО и понимаем, что для них нам требуется....внешнее питание. Со слов техподдержки "выход прибора пассивный и требует внешнего источника". Ну бывает, что. Про этот момент в руководстве невнятно что-то написано и более менее понятно нарисовано. Правда, нарисовано 2 блока питания - один для прибора, второй для АО. По итогу можно применять общий БП....
На Carel, например, АО тоже по дефолту отвязан от основного линии питания PLC и может быть запитан внешним напряжением, отличным от питающего, например - АС. А здесь, на этом...приборе, так нельзя. Питание самого прибора АС/DC, а вот для AO будь любезен давай DC. Ненависть в этот момент достигла пика - либо вся вторичка на DC либо ставь трансформатор и отдельно БП 24В. Ну и да - помни при общий минус, он же равнопотенциальный. Ладно, пусть, переживем, сделаем вторичку DC в части индикации, а для контакторов пойдем на лютый зашквар и применим питание сетевым напряжением с использованием ...нуля. Да, мне стыдно, давно такого не лепил. Но сделал и сделал, иные вообще спросят чего это я парюсь по сетевому напряжению во вторичных то цепях. Много кто ставит "аффтоматик 2А" на цепи управления и все нормально работает, никаких трансформаторов, нафига. Ну, если вы дочитали до этого места, то вот вам причина почему сетевое напряжение во вторичной цепи это западло и зашквар (ну, кроме опасности поражения током): ГОСТ Р МЭК 60204-1-2007 9. Функции и цепи управления 9.1.1. Питание цепи управления: "Когда используется питание от сети переменного тока, обязательным является использование трансформаторов для питания цепей управления" Вообще, рекомендую к прочтению, изучению и применению : )
Ладно, снова ОК и применяем один общий БП, вроде все уже, хватит, но... но теперь мы берем РП, скачанное с сайта и смотрим как же нам подключить оборудование к АО1, АО2. А никак. На рисунке (не схеме) из РП показано условно, но не так, как на клеммах прибора. Эх, чего терять, идем гуглить, ведь в интернете не обманут, да... И нагугливаем раннюю версию РЭ (не РП), которая на сайте не представлена, но в ней, внезапно, показаны схемы подключения к прибору. Принимаем на веру представленную информацию, глядим на клеммы прибора, понимаем, что на первый взгляд все логично в этом левом РП и... вносим в схему показанное подключение. Забиваем на проект, сохраняем схему (или наоборот ? ), отвлекаемся на Овен-Конфигуратор. Надо же как-то отвлечься .... В общем, в попытках тыкнуть нужный мне конфиг я узнал, что:
Концевики заслонок могут либо быть на П и В либо нечего тут раздельный контроль Управление приводом заслонок при этом может быть и раздельное Аналоговый датчик dP вентилятора это жирно, куда оно вам (но вход есть свободный) Аналоговое dP фильтра это очень нужная нам функция и она предусмотрена Управление поддержанием давления на вентиляторе - а вот оно не предусмотрено Аналоговый выход упрвления вентилятором задается вручную либо 4 ступени
Учитывая опыт применения Siemens ACX, конфигурируемого как тебе надо, а не как мы смогли сделать, вариативность настройки этого "Овен-прибора" вызывает даже не уныние, а скорее недоумение. И не надо рассказывать про мало вх/вых. Оно, если требуется, может еще расширяться модулями, почитайте РП на сайте. Кстати, стоит оно 29тр. в розницу, что заставляет задуматься и сравнить хоть бы и с Зентек, если совсем никак самим программу.
Лично для меня непонятным остается только один момент и я не про "зачем и нафига". Кто этот абстрактный инсталлятор, согласившийся на применение этого...прибора в проекте ? Я плохой пример, поскольку во-первых у меня было пожелание заказчика на применение этого...прибора, а во-вторых шли бы теперь эти заказчики со своими сайрами сами внедрять.
Ну вот реально - функционал странный, большие системы требуют сразу модулей, а это деньги. Как будет работать этот комбайн софта непонятно, потому что даже ACX удавалось поймать на каких-то глюках от конфига до работы функций, а казалось бы немцы, сименс...
Ко всему прочему, если ставить это в щиты с перспективой развития проекта/установки, то внеззапно можно узнать о том, что конфигурация вх/вых сдвигается и при добавлении таки функций надо бы еще провода в щите переставить местами. Ну, зато "Один контроллер для большинства типовых систем вентиляции. Работа с водяными, электрическими и фреоновыми нагревателями и охладителями, а также модулями рекуперации, рециркуляции и увлажнения". И знаете, это очень хорошо, на мой взгляд. Пока такие приборы будут внедрять и пытаться запускать у нас всегда будет своя ниша кастомных решений, на чем бы вы не работали - от Logo (не к ночи помянут) до..да какая уже разница : )
PS. Общество с ограниченной ответственностью "Производственное Объединение ОВЕН", вы молодцы, на самом деле, допилите уже эту сайру360 и забудем : )
1/2
PSS. Чтоб не говорили, что это заказуха и вообще ты ничего не делал - чертеж вн. вида ЩУ
В Factory I/O построена линия сортировки и сборки с управлением от ПЛК. Изделия перемещаются по цепному конвейеру и проходят через видеодатчик, который выводит цифры от 0 до 9 для определения типа и цвета. Два привода распределяют детали: правый — для крышек, левый — для сырья. Сырье поступает в станок с ЧПУ, который изготавливает основание изделия и укладывает его на поворотный стол. На левых конвейерах крышки останавливаются, когда их определяет видеодатчик. Их цвет сохраняется. Сборочная станция соединяет каждую крышку с основанием только при совпадении цветов. Затем манипулятор поднимает и укладывает готовое изделие.
Интерфейс 3osheet , среда разработки программ на LD, FBD, частично ST, и на псевдо-ассемблере (инструкции виртуальной машины)
Все началось с работы, где я занимался системным администрированием в промышленности. После того как уволился, зная в чем нуждаются предприятия, разрабатывал собственную систему SCADA. Но решил пойти еще дальше в сторону разработки настоящего промышленного контроллера.
Цели которые поставил перед собой:
1) Среда разработки, отображающая в режиме реального времени значений переменных и место выполнения код .
2) Гибрид LD и FBD. Возможность создавать свои блоки (рисовать, и описывать на псевдо ассемблере для виртуальной машины).
3) Создание среды выполнения программ на стороне - микроконтроллера (или ПК если это SCADA).
4) Разработка изолированой среды выполнения (виртуальная ОЗУ) с заменой кода на лету. Например - отключить задачу, через MODBUS переписать или изменить ее программу, и запустить выполнение, и при этом не останавливать другие задачии и не перезагружая ПЛК физичесски.
Являюсь фанатом - оптимизации, восхищаюсь способностью выжать из минимум ресурсов - максимум эффективности. Потому выполнил важную цель - разработка и запуск виртуальной машины (собственной виртуальной машины, об этом в следующих статьях) выполняющий программу ПЛК на микроконтроллере с 8 KB ОЗУ!
Среда разработки. Написана на OpenJDK, Java весом 80мб с самыми примиитивными GUI. Легкая и работает даже на старых Raspberry PI. Если установить IDE(среду разработки с компилятором) и среду выполнения на CPU, получится самодостаточноый ПЛК Сервер, способен сам себя перепрограммировать(пользователем) без внешнего ПК.
LD программы не имеют ограничений по сложности, можно безконечно вставлять ветки друг в друга в любом месте, насколько хватит ОЗУ на стороне микроконтроллера. Мною придуман эффективный алгоритм отрисовки веток LD который не использует рекурсии или графы. Все элементы - линейны и последовательны , а двумерность программы в некоторым смысле илюзорна. Поэтому гарантировано - то что пользователь видит на экране , то видит виртуальная машина на выполнении. Новая ветка на отображении просто скачок координат на дисплее, а для виртуальной машины - скачок счетчика выполнения команд.
Трансляция LD\FBD\ST программ на язык инстукций виртуальной машины, а потом компилятором в байткод для машины
Компилятор. Программная архитектура
Несмотря на то что я пытался сделать инструкции для виртуальный машины, максимально соответствующие машинным, работу с переменными я реализовал - высокоуровневую. То есть, пользователь может создавать свои структуры любой сложности внутри, без ограничений. Типы могут в себе содержать внутри другие типы и массивы любой размерности, и эти массивы также могут внутри содержать сложные типы чередующиеся с массивами.
тут мне пришлось проделать огромную работу компиляторостроения - Memory Manager Layout.
types:
Sensor typedef {
id: word;
value: real;
is_ok: byte;
}
Status typedef {
is_running: byte;
error_code: word;
error_msg: byte[50];
}
ProductionLine typedef {
line_id: word;
sensors: Sensor[10];
production_rate: real[7][24];
status: Status;
};
Таким образом в данный момент, описание пользовательского LD FBD выглядит так:
Но уже сейчас работаю над транслятором ST, чтоб можно было создавать свои LD FBD с описанием их на ST.
То есть, самый низкий уровень VM это гибрид ассемблера с высокоуровневыми данными, поддержку этого я намеренно реализовал для возможности в будущем писать код на свою платформу не только на языке ST, да хоть на Java. При этом, напомню, я разрабатывал VM способную работать на микроконтроллерах с ОЗУ от 8Кб. Да возможно если писать на языке ST , то в такой МК влезет всего под сотню строк кода, но ничего не мешает подгружать инструкции с внешней карты (если пользователю не важна строгость выполнения по времени, будут небольшие задержки), ну или взять МК с ОЗУ побольше. VM имеет эфективное адресное пространство 1 мегабайт, то есть - прочитать переменную с адресом меньше <1МБ можно за один раз:
если работать адресами по выше, то тут нужно использовать две виртуальные иснтрукции - загрузить старшие биты адреса, а потом младшие.
Что можно выжать из МК с ОЗУ 8 килобайт
Инструкции VM - 4 байтные. Одна булевая LD инструкция занимает 8 - 12 байт:
// 8 Байт, Аналог XIC
LDB R15 Reset;
JFALSE R15 Start;
//12 байт если LD читает целое, но проверяет бит
LDB R15 MPPress;
MSK R15 #5
ISFALSE Branch 2;
таким образом, в однозадачном режиме, если создавать ПЛК на МК с ОЗУ 8КБ ( 4 КБ - виртуальная ОЗУ+4 КБ нативный код СИ - сама машина), на 4 КБ виртуальной ОЗУ можно загрузить 300-400 LD (при булевых переменных - 400 LD ) инструкций и около сотни переменных размером 1-4 байта.
Если режим многозадачный ( парралельные не связанные между собой задачи) то среда разработки допишет свой код, где будет дополнительно уходить 80 байт на каждую задачу для создания виртуального стека, и около 160 байт на простейший менеджер задач, который будет управлять выполнением.
В следующей статье напишиу - как это выглядит уже на микроконтроллере.
Мы занимаемся разработкой Scada-системы и для отладки коммуникации с Modbus-устройствами написали небольшую утилиту: PultModbusTester
Утилита бесплатная и без ограничений. Очень простой и удобный интерфейс. Поддержка Modbus TCP, Modbus RTU и Modbus RTU-Over-TCP. Интерпретация значений в форматах INT16, INT32 и Float (с любым порядком байтов). Утилита имеет подробный и наглядный лог, с подсветкой ошибочных байтов - здорово помогает в решении проблем с Modbus-устройствами.
Будем рады, если утилита окажется полезной коллегам-автоматчикам, также будем благодарны за обратную связь по функционалу.
1. Используйте только однобуквенные имена переменных
Например, вместо `ConveyorMotorSpeed` пишите `x`. Так никто не догадается, что переменная управляет скоростью конвейера, и проект превратится в головоломку для коллег.
2. Не комментируйте код вообще
Пусть все догадываются сами! Например, строчка `IF NOT NOT x THEN y := TRUE;` без пояснений станет загадкой на века. Это добавит проекту атмосферы таинственности.
3. Храните все данные в глобальных переменных
Зачем использовать локальные переменные или структуры? Пусть всё висит в `GVL`, чтобы изменения в одном месте ломали логику в десяти других. Это ускорит развитие хаоса.
4. Пишите всю логику в одном ПЛК-цикле
Забудьте о разделении на функциональные блоки или программы. Дайте все 10 000 строк кода в `PLC_PRG`. Это повысит производительность... ну, как минимум, нагрузку на мозг разработчика.
5. Используйте таймеры и счетчики без сброса
Например, вставьте один таймер `TON` в несколько условий одновременно. Пусть его состояние "плывет" между задачами — это добавит неожиданности в поведение системы!
6. Не тестируйте логику до загрузки на железо
Зачем использовать симуляцию? Лучше сразу запускайте код на реальном оборудовании. Внезапные сюрпризы вроде заклинившего сервопривода сделают рабочий день ярче.
7. Применяйте операции с плавающей точкой для таймеров
Например, умножьте `T#5s` на `1.0000001` и удивляйтесь, почему таймер срабатывает несвоевременно. Это идеальный способ запутать даже опытного инженера.
8. Игнорируйте резервное копирование
Делайте правки прямо на боевом контроллере, не сохраняя проект. Если всё сломается — просто начнёте всё с нуля. Это тренирует память и стрессоустойчивость!
9. Мешайте логику управления и визуализации
Пишите код для HMI прямо в ПЛК-программе через `IF HMI_Button THEN ... END_IF`. Так вы создадите идеальный микс между технологической логикой и интерфейсом.
10. Не используйте версионирование
Сохраняйте проект каждый раз под новым именем: `Project_v1`, `Project_v2_final`, `Project_v3_реально_последний`. Через месяц вы сами забудете, где какая версия.