Просмотр полной версии : Первый проект на ST
Здравствуйте. В процессе изучения АСУ ТП, впервые ко мне попало реальное техническое задание. Ранее никогда ничего не писал в Codesys, единственное был опыт написания программы в Owen Logic на FBD(сигнализация для танков с молоком).
Задание как мне сказали самое то для обучения, попробуй написать его на LD, FBD и потом на ST. Я начал его активно писать на LD, но в конце концов застрял в одном месте и не мог найти в этом языке подходящего блока. В итоге решил, что на ST возможности шире. Просмотрел полутора часовой вебинар от Овен и принялся писать. И действительно зашел дальше, чем ранее на LD, но в итоге стал путаться в записях, так как страниц с кодом перевалило за сотню.
Я не прошу решить задачу за меня, просто посоветуйте, как можно лучше оформить программу, как все разделить для наглядности, что лишнее и чего наоборот недостает. Может можно и лучше в данном случае комбинировать все на разных языках, что-то на LD, а какую то часть на ST(если возможно)? Планирую учесть ошибки и начать писать программу заново, может все-таки получится самому закончить.
Видео демонстрация: https://disk.yandex.ru/i/AXCRWndOEL8iRA (качество видео лучше, если скачать его на ПК)
Программа в Codesys: 72819
Техническое задание: 72820
kondor3000
08.01.2024, 17:08
Пишите на ST, если надо, можно конвертировать в LD и посмотреть.
А вопросы задавайте конкретные на куске кода, разбираться в программе целиком никто не будет.
А вопросы задавайте конкретные на куске кода, разбираться в программе целиком никто не будет.
Если конкретно, то программа на ST примерно так и должна выглядеть как у меня или ее как то можно разбить на разные разделы или упростить? Я не прошу весь код разбирать, а глянуть беглым опытным взглядом в общем
kondor3000
08.01.2024, 17:30
Если конкретно, то программа на ST примерно так и должна выглядеть как у меня или ее как то можно разбить на разные разделы или упростить? Я не прошу весь код разбирать, а глянуть беглым опытным взглядом в общем
В общем это полный кирдык, перед написанием надо продумать алгоритм, а не как у вас 1500 таймеров, программу надо разделить на блоки ФБ ( или программы), каждая делает свою работу, если блоков несколько (похожих) пишите ФБ для одного, и делаете несколько экземпляров ( добавляя 1,2,3,4 и т. д.)
Конвертировать из ST, можно в FBD, IL, LD 72822
В общем это полный кирдык
Я в принципе так и думал). Поэтому и решил написать на форуме
перед написанием надо продумать алгоритм, а не как у вас 1500 таймеров
А как изначально составляют алгоритм, на листе бумаги?
kondor3000
08.01.2024, 18:32
А как изначально составляют алгоритм, на листе бумаги?
Да на листе, желательно предусмотреть все аварии, ручной., автоматич. режим, что откуда и чем включается.
Вот пример Шагового автомата на 12 шагов и 12 разных выходов и всё на 1 таймере. Упрощённый вариант, для наглядности работы.
А вообще тут на ОЛ выложены более совершенные варианты все на ST. https://owen.ru/forum/showthread.php?t=38239&page=11#105
МихаилГл
08.01.2024, 18:51
Вот, ваш ответ "Да, на листе..." это прям то, что я всегда искал! Сам так делаю.
А ТС советую делать универсальную программу, сначала для одного механизма, со всеми авариями, задержками, автоматами и концевыми, а потом в этот модуль тупо копировать входные данные каждого механизма, а на выхода физические соответственно копировать выходные данные модуля.
У меня есть такая штука, но я писал её целый год... Вас обманули, что это самый простой алгоритм. Это самый сложный алгоритм, применяемый на всех производственных поточных линиях.
А вот автоматический последовательный пуск/останов, это уже будет навесок к разработанному....
Для подобных программ существует язык SFC, который позволяет буквально "рисовать" алгоритм в программе и в дальнейшем удобен при отладке и её модификации.
Таймеры, состояния - всё уже есть внутри. Вариант упрощённого SFC с вставками на ST открывает очень широкие возможности.
Конечно, требуется некоторое время на изучение и "вхождение", но я считаю, оно того стоит.
Если интересно - посмотрите например
EVGEN_, осваивайте ST. Как освоите, все остальные языки Вам не нужны (не интересны) станут. Можете ещё на CFC внимание обратить...
Sergey666
10.01.2024, 08:34
ТЗ конечно очень простое, но для реального применения должно быть доработано.
Напр: что если какой-нибудь бородатый хрен во время работы переключит режим в ручной? Что если оператор во время процедуры запуска нажмет "Стоп"?
А так реально на час работка, дерзайте.
Sergey666
10.01.2024, 09:39
Так в том и вопрос: ПЛК в режиме АВТО работает, комплекс запущен и тут появляется некий "хрен", переключающий режим. Это весело... я бы переключение режимов учитывал только в состоянии "Стоп", но в данном случае, не видя схемы, предполагаю что переключатель "Ручн/Авто" переключает "Фазу управления" с выходов ПЛК на релейку, поэтому будет "Полный ооочень мана резкий стоп с засыпкой всех транспортеров и всего прочего, лааапата тэйк плиз энд сыктым-сыктым.
МихаилГл
10.01.2024, 13:32
Так в том и вопрос: ПЛК в режиме АВТО работает, комплекс запущен и тут появляется некий "хрен", переключающий режим. Это весело... я бы переключение режимов учитывал только в состоянии "Стоп", но в данном случае, не видя схемы, предполагаю что переключатель "Ручн/Авто" переключает "Фазу управления" с выходов ПЛК на релейку, поэтому будет "Полный ооочень мана резкий стоп с засыпкой всех транспортеров и всего прочего, лааапата тэйк плиз энд сыктым-сыктым.
Не знаю, наши проектировщики по такому же принципу нарисовали. У меня все работает. Главное при переключении на местный режим все остановить типа по кнопке "Стоп".
Так в том и вопрос: ПЛК в режиме АВТО работает, комплекс запущен и тут появляется некий "хрен", переключающий режим. Это весело... я бы переключение режимов учитывал только в состоянии "Стоп", но в данном случае, не видя схемы, предполагаю что переключатель "Ручн/Авто" переключает "Фазу управления" с выходов ПЛК на релейку, поэтому будет "Полный ооочень мана резкий стоп с засыпкой всех транспортеров и всего прочего, лааапата тэйк плиз энд сыктым-сыктым.
Я всегда блокирую переключение режимов при работе
МихаилГл
10.01.2024, 18:19
Я всегда блокирую переключение режимов при работе
Если местный режим реализован релейно, то блокировать придётся схемно... Т.е. если в дистанции плк что-то запустил, то должно сработать реле, которое не позволит переключить в местный. Ни разу таких схем не видел.
И да, ключ выбора режима работы тоже физический. При программном конечно можно что угодно сделать... Но тоже есть проблемы...
EVGEN_, осваивайте ST. Как освоите, все остальные языки Вам не нужны (не интересны) станут. Можете ещё на CFC внимание обратить...
Я особо в остальные платформы пока не вникал, но вроде ST и тем более CFC не во всех плк есть. У нас на предприятии в основном ПЛК фирм: SIEMENS, OMRON и Allen Bradley.
МихаилГл
11.01.2024, 05:36
Я особо в остальные платформы пока не вникал, но вроде ST и тем более CFC не во всех плк есть. У нас на предприятии в основном ПЛК фирм: SIEMENS, OMRON и Allen Bradley.
На SIEMENS лучше на ST писать (LD на нем так ужасен из-за разделения строк...), а на Allen Bradley на LD (ST на нем визуально некрасив..., тем более там не совсем LD, а более расширенная производителем система)
Из-за определенных обстоятельств почти месяц не занимался программированием, еле как потихоньку раскачался, уже подзабыл что к чему, начал писать заново эту же программу на ST + CFC через CASE. По началу все гладко пошло, но сейчас застрял на одном моменте. Запуск, аварийный останов, сброс, остановка - прописал, но после остановки никак не сбрасывается триггер SR1, хотя я прописал в программе, в итоге из-за чего после останова, установка снова не запускается. Мужики, подскажите, в чем может быть проблема и в целом как новое оформление программы?
Из-за определенных обстоятельств почти месяц не занимался программированием, еле как потихоньку раскачался, уже подзабыл что к чему, начал писать заново эту же программу на ST + CFC через CASE. По началу все гладко пошло, но сейчас застрял на одном моменте. Запуск, аварийный останов, сброс, остановка - прописал, но после остановки никак не сбрасывается триггер SR1, хотя я прописал в программе, в итоге из-за чего после останова, установка снова не запускается. Мужики, подскажите, в чем может быть проблема и в целом как новое оформление программы?
В шаге 7 что надо делать?
Для нумерации шагов создайте тип данных перечисление (значения имеют тип INT), программа станет более осмысленной.
Пример:
TYPE enState : (
gc_step_0 := 0 , (* Шаг 1 *)
gc_step_1 := 1 , (* Шаг 2 *)
gc_step_2 := 2 , (* Шаг 3 *)
gc_step_3 := 3 , (* Шаг 4 *)
gc_step_4 := 4 , (* Шаг 5 *)
gc_step_5 := 5 , (* Шаг 6 *)
gc_step_6 := 6 (* Шаг 7 *)
);
END_TYPE
Писать условия IF в начале программы, в которых есть "AND step=Х" незачем - у вас есть ниже CASE - перенесите эти IFы в соответствующие подпункты CASE (TONы, которые выполняются по "IN := step=Х" тоже в принципе можно убрать внутрь CASE, но могут быть нюансы)
kondor3000
11.02.2024, 17:14
Никаких выводов не сделали, зачем вам 8 таймеров, если одного за глаза, только время меняйте и запускайте снова, так же по шагам.
Даже пример готовый выкладывал, только кол-во шагов уменьшить осталось и нужные выходы включать.
Я повторно предлагаю вам попробовать SFC, чтобы решать подобные задачи
Можно конечно применить эрзац SFC на ST:
FUNCTION_BLOCK SFC
VAR_INPUT
xInBtnStart, xInBtnStop: BOOL;
InTime: INT;
END_VAR
VAR_OUTPUT
OutState: enState;
xOutError, xOutCtrl, xOutAdd: BOOL;
END_VAR
VAR
Init: BOOL;
NewState: enState := gc_step_0;
tTime: TIME;
fbBtnStart, fbBtnStop: R_TRIG;
fbTON: TON;
END_VAR
(* КОД ВЫПОЛНЯЕМЫЙ ВСЕГДА *)
fbBtnStart(CLK := xInBtnStart);
fbBtnStop(CLK := xInBtnStop);
xOutError := FALSE;
IF NOT Init THEN
Init := TRUE;
NewState := gc_step_0;
ELSE
CASE NewState OF
(* Шаг 1 *)
gc_step_0:
(* ДЕЙСТВИЯ ПРИ ВХОДЕ В ШАГ *)
IF NewState <> OutState THEN
OutState := NewState;
END_IF;
(* ДЕЙСТВИЯ *)
xOutCtrl := xInBtnStart;
(* call sw ctrl timer *)
fbTON(IN := TRUE, PT := T#10s);
(* ПЕРЕХОДЫ *)
IF fbBtnStart.Q AND fbTON.Q THEN NewState := gc_step_1; fbTON(IN := FALSE);
(*
ELSIF УСЛОВИЕ THEN NewState := НОВОЕ СОСТОЯНИЕ;
ELSIF УСЛОВИЕ THEN NewState := НОВОЕ СОСТОЯНИЕ;
*)
END_IF;
(*
(* ДЕЙСТВИЯ ПРИ ВЫХОДЕ ИЗ ШАГА *)
IF NewState <> OutState THEN
END_IF;
*)
(* Шаг 2 *)
gc_step_1:
(* ДЕЙСТВИЯ ПРИ ВХОДЕ В ШАГ *)
IF NewState <> OutState THEN
fbTON.PT := T#30s;
IF InTime > 0 THEN fbTON.PT := REAL_TO_TIME(InTime * 1000.0); END_IF;
END_IF;
(* ДЕЙСТВИЯ *)
OutState := NewState;
xOutCtrl := TRUE;
(* call sw ctrl timer *)
fbTON(IN := TRUE);
(* ПЕРЕХОДЫ *)
IF fbBtnStop.Q THEN NewState := gc_step_0;
ELSIF fbTON.Q THEN NewState := gc_step_2; fbTON(IN := FALSE);
(*
ELSIF УСЛОВИЕ THEN NewState := НОВОЕ СОСТОЯНИЕ;
ELSIF УСЛОВИЕ THEN NewState := НОВОЕ СОСТОЯНИЕ;
*)
END_IF;
(*
(* ДЕЙСТВИЯ ПРИ ВЫХОДЕ ИЗ ШАГА *)
IF NewState <> OutState THEN
END_IF;
*)
(* Шаг 3 *)
gc_step_2:
(* ДЕЙСТВИЯ ПРИ ВХОДЕ В ШАГ *)
IF NewState <> OutState THEN
OutState := NewState;
END_IF;
(* ДЕЙСТВИЯ *)
xOutError := TRUE;
xOutCtrl := FALSE;
(* ПЕРЕХОДЫ *)
IF fbBtnStop.Q THEN NewState := gc_step_0;
(*
ELSIF УСЛОВИЕ THEN NewState := НОВОЕ СОСТОЯНИЕ;
ELSIF УСЛОВИЕ THEN NewState := НОВОЕ СОСТОЯНИЕ;
*)
END_IF;
(*
(* ДЕЙСТВИЯ ПРИ ВЫХОДЕ ИЗ ШАГА *)
IF NewState <> OutState THEN
END_IF;
*)
(* ОШИБКА СОСТОЯНИЯ *)
ELSE
OutState := gc_step_0;
END_CASE;
(* КОД ВЫПОЛНЯЕМЫЙ ВСЕГДА *)
xOutAdd := NewState = gc_step_0 OR gc_step_1;
END_IF;
накой тут init?
ну мало ли
Никаких выводов не сделали, зачем вам 8 таймеров, если одного за глаза, только время меняйте и запускайте снова, так же по шагам.
Даже пример готовый выкладывал, только кол-во шагов уменьшить осталось и нужные выходы включать.
Вы про GetTime? Если да, то я не понимаю как это работает.
73501
В шаге 7 что надо делать?
Шаг 7, это когда все узлы установки нормально запущены, то есть установка полностью в работе.
73503
kondor3000
11.02.2024, 18:07
Вы про GetTime? Если да, то я не понимаю как это работает.
Что не понятного тут? В зависимости от входящего шага State, меняется время для таймера, для каждого шага своё время. Например для шага State=1 время t0=5.
Время в таймере надо задавать в ms, так как время конвертируется PT= UDINT_TO_TIME (CurMinute),
если не умножить на 1000, то вы получите 5ms, и шаги просто пролетят с 1 до 12 за пол секунды.
Умножение на 1000 это перевод времени в секунды, 5*1000=5000ms=5секунд,
а умножение на 60000 перевод в минуты 5*60000=300 000ms=300 секунд=5 минут
Переменная Zad и переключает либо отсчёт в секундах, либо в минутах. Там ведь даже подписано!
Всё что нужно сделать, запустить эмуляцию, нажать Старт и смотреть как работает.
Шаг 7, это когда все узлы установки нормально запущены, то есть установка полностью в работе.
73503
Вы в этой строчке записывате значение во ВХОДНУЮ ПЕРЕМЕННУЮ "ALARM_STOP" (в принципе, не возбраняется)
IF TON8_OUT THEN ALARM_STOP:=TRUE; step:=0;END_IF
чтобы потом здесь
IF START AND SR1_OUT AND AUTO AND step=0 AND TP1_OUT THEN step:=1;END_IF
TP1(IN:=SR1_OUT, PT:=T#20s , Q=>TP1_OUT , ET=> );
SR1(SET1:=START , RESET:=ALARM_STOP , Q1=>SR1_OUT );
сбросить SR1
Но здесь значение ВХОДНОЙ ПЕРЕМЕННОЙ "ALARM_STOP" уже будет иметь то значение, что пришло на этот вход (ALARM_STOP) СНАРУЖИ.
И если это FALSE, то соответственно сброса SR1 не происходит
Тогда ладно.
ТС и так не осознает автомат, а Вы его еще и запутаете кол-вом стейтов - новые, выходные, действия входные/выходные.
Проще нужно.
Конечно, можно повыкидывать лишнее.
Кстати не попадалось подобных реализаций концепции SFC на ST или на Си например?
Вот прям впрямую - нет. А так - в чем проблема?
Ну в основном конечно это реализация входных/выходных действий и таймера шагов. Может кто-то уже занимался этим или исходник библиотеки SFC имел
собсно вопрос - надо входое/выходное в одном цикле с телом (как здесь) делать или в разных
Это наверно больше вопрос удобства - логика выполнения же не меняется от этого.
Мне удобнее, когда все действия шага в одном месте
МихаилГл
12.02.2024, 05:10
Вот смотрю на варианты и всегда вижу почерк автора...
Кто-то (как ТС) выход таймера через => делает, но использует лишнюю переменную.
Кто-то (как и я) через TIMER.Q...
Сколько людей, столько и решений одной задачи. Поэтому надо свое придумывать, или перенимать наиболее понравившуюся манеру написания...
Из-за определенных обстоятельств почти месяц не занимался программированием, еле как потихоньку раскачался, уже подзабыл что к чему, начал писать заново эту же программу на ST + CFC через CASE. По началу все гладко пошло, но сейчас застрял на одном моменте. Запуск, аварийный останов, сброс, остановка - прописал, но после остановки никак не сбрасывается триггер SR1, хотя я прописал в программе, в итоге из-за чего после останова, установка снова не запускается. Мужики, подскажите, в чем может быть проблема и в целом как новое оформление программы?
Набросал вам пример как это может выглядеть на SFC (пару шагов - для примера). Запустите в эмуляции
kondor3000
12.02.2024, 11:15
Человек пытается ST освоить, зря вы к нему с этим SFC пристали, с ним ещё неделю разбираться придётся, хотя на ST всё можно сделать без проблем
Человек пытается ST освоить, зря вы к нему с этим SFC пристали, с ним ещё неделю разбираться придётся, хотя на ST всё можно сделать без проблем
Если бы проблем не было, то наверное уже сделал бы
Мне наоборот кажется, что понять как работает блок на SFC гораздо проще, чем разобраться в аналогичной реализации его на ST
Всё что нужно сделать, запустить эмуляцию, нажать Старт и смотреть как работает.
Спасибо за развернутый ответ! Первым же делом хотел посмотреть как это работает в эмуляции, но при открытии файла вылазит куча ошибок, в том числе и в самой программе.
73522
73523
73524
73525
Вы в этой строчке записывате значение во ВХОДНУЮ ПЕРЕМЕННУЮ "ALARM_STOP" (в принципе, не возбраняется)
IF TON8_OUT THEN ALARM_STOP:=TRUE; step:=0;END_IF
чтобы потом здесь
IF START AND SR1_OUT AND AUTO AND step=0 AND TP1_OUT THEN step:=1;END_IF
TP1(IN:=SR1_OUT, PT:=T#20s , Q=>TP1_OUT , ET=> );
SR1(SET1:=START , RESET:=ALARM_STOP , Q1=>SR1_OUT );
сбросить SR1
Но здесь значение ВХОДНОЙ ПЕРЕМЕННОЙ "ALARM_STOP" уже будет иметь то значение, что пришло на этот вход (ALARM_STOP) СНАРУЖИ.
И если это FALSE, то соответственно сброса SR1 не происходит
Спасибо! Я вас понял.
Сказано - ручной режим кнопок ПУСК/СТОП мимо ПЛК
=> стандартная схема подхвата для каждого из 4-х агрегатов
Cхемы - где?
-Как в схему подхвата имплантированы выходы ПЛК?
-Что будет при жмяканьи ПУСК/СТОП в АВТО? что будет при замыкании выхода ПЛК в МЕСТ?
У меня на "руках" только ТЗ, больше ничего нет.
kondor3000
12.02.2024, 14:52
Спасибо за развернутый ответ! Первым же делом хотел посмотреть как это работает в эмуляции, но при открытии файла вылазит куча ошибок, в том числе и в самой программе.
Офигеть, вы за столько времени, даже примеры на сайте не открывали?
Просто у вас таргеты не все стоят, как вы будете примеры открывать, они все для разных ПЛК сделаны. Поставьте все таргеты один раз и всё. У меня примеры для ПЛК154UM https://owen.ru/product/codesys_v2/service_po иногда для ПЛК154АM или ПЛК110_60_М
То, что биб-ка другой версии, это фигня, всё будет работать. Главное, что бы она вообще была. Библиотеки тоже желательно все поставить сразу.
https://owen.ru/product/codesys_v2/libraries
Если бы проблем не было, то наверное уже сделал бы
Мне наоборот кажется, что понять как работает блок на SFC гораздо проще, чем разобраться в аналогичной реализации его на ST
В принципе как программа должна выглядеть на CFC или FBD представление есть, но как правильно подметил kondor3000 интересен именно язык ST.
Офигеть, вы за столько времени, даже примеры на сайте не открывали?
Просто у вас таргеты не все стоят, как вы будете примеры открывать, они все для разных ПЛК сделаны. Поставьте все таргеты один раз и всё. У меня примеры для ПЛК154UM https://owen.ru/product/codesys_v2/service_po иногда для ПЛК154АM или ПЛК110_60_М
То, что биб-ка другой версии, это фигня, всё будет работать. Главное, что бы она вообще была. Библиотеки тоже желательно все поставить сразу.
https://owen.ru/product/codesys_v2/libraries
Да, точно, с таргетами и библиотеками не заморачивался, установлено по минимуму. А с GetTime разобрался.
В принципе как программа должна выглядеть на CFC или FBD представление есть, но как правильно подметил kondor3000 интересен именно язык ST.
Так-то, есть некоторая разница между CFC и SFC
Так-то, есть некоторая разница между CFC и SFC
Не спорю, просто в SFC не вникал. На CFC погружался в программирование, смотрел уроки, с FBD сталкивался в Owen Logic, а про ST-многие советуют, так как универсальный язык и можно на нем написать что угодно, к тому же можно макросы писать и в Owen Logic на нем.
Мужики, может есть у кого готовые старые проекты в Codesys V2.3, написанные только на языке ST? Хочу посмотреть(изучить) оформление, возможные варианты решения различных задач. Кому не жалко, скиньте сюда или через личку, напишу свою электронную почту.
kondor3000
03.03.2024, 19:59
Мужики, может есть у кого готовые старые проекты в Codesys V2.3, написанные только на языке ST? Хочу посмотреть(изучить) оформление, возможные варианты решения различных задач. Кому не жалко, скиньте сюда или через личку, напишу свою электронную почту.
Думаю, что у вас не совсем правильный подход, решать надо конкретную задачу, до конца, вот и спрашивайте.
Разбирать надо простые примеры, как выложены на сайте.
От чужих проектов, толку будет ноль, потому, что вы не поймёте, как и что сделано и почему так. По своему опыту пишу.
Только на ST не делал - только в связке SFC+ST.
При помощи SFC разделял задачу на процессы:
- инициализация переменных при включении питания
- обработка аналоговых входов (масштабирование, сглаживание)
- работа с панелью оператора (формирование команд, смена режимов, формирование слов состояний для визуализации и прочее)
- валидация параметров, введённых с панели или другого источника
- обработка кнопок и переключателей на щите (формирование команд, смена режимов)
- последовательность пуска управляемого агрегата (барабанный командоаппарат на ST при помощи CASE)
- регуляторы
- сигнализация (включение постоянного, прерывистого звукового сигнала, отключение звуковой сигнализации)
- защита - проверка выхода параметров процесса за допустимые диапазоны в зависимости от текущего состояния управляемого агрегата - формируются сигналы вхождения в предупредительный диапазон, выхода за допустимый и начало отсчёта задержки, завершение отсчёта задержки и аварийного останова агрегата
Сейчас бы ещё учитывал совет о именованных константах для номеров состояний агрегата. А тогда просто нумеровал их с шагом 10, чтобы можно было вставить шаги без изменения нумерации.
Рабочие программы привести не могу, а тестовый пример работы с файлами в ПЛК110[М2] запросто.
Программа в ПЛК содержит переменные, вводимые с панели оператора и буфер обмена с файлами, содержащий все эти переменные.
По команде "записать в файл", переменные копируются в буфер и содержимое буфера сохраняется в файле.
По команде "прочитать из файла", содержимое файла копируются в буфер, но переменные остаются неизменными.
По команде "установить в буфере настройки по умолчанию", в буфер записываются значения "по умолчанию", но переменные остаются неизменными.
По команде "скопировать настройки из промежуточного буфера", содержимое буфера копируется в переменные.
Таким образом, появляется возможность ознакомления с сохранёнными ранее настройками и сравнения их с актуальными.
Добавлю, что к такой структуре программ в CoDeSys пришёл самостоятельно, до этого работал в другой среде разработки и программа была на LD без возможности структурирования единой "простынёй" в ~500-1000 строк.
Сейчас перешёл на другую работу, и для программирования в CODESYS 3.5 во всех наших уроках рекомендуется другой подход к структуре программы - создаются задачи и они вызываются не из основной программы, а каждая отдельно с заданным интервалом через штатный планировщик.
Не могу сказать, какой подход лучше - не встречал анализа.
Вот ещё пример программы SFC+ST+FBD
Задача была - автоматизация работы бака-накопителя ГВС. Автоматическое или ручное управление одним насосом и несколькими задвижками, поддержание уровня в баке при помощи поплавкового датчика уровня с 4 дискретными сигналами.
Была экономия на физических кнопках (а значит и модулях ввода), поэтому с панели оператора были "кнопки" пуск/стоп процесса, сброс и проверка сигнализации, ручные и автоматические режимы насоса и задвижек.
Но структура программы осталась по моему выдуманному принципу
Сначала хотел при включении питания всё закрывать и выключать, но потом отказался от этой идеи, поэтому стадия Init пустая.
Вот ещё пример программы SFC+ST+FBD
Задача была - автоматизация работы бака-накопителя ГВС. Автоматическое или ручное управление одним насосом и несколькими задвижками, поддержание уровня в баке при помощи поплавкового датчика уровня с 4 дискретными сигналами.
Была экономия на физических кнопках (а значит и модулях ввода), поэтому с панели оператора были "кнопки" пуск/стоп процесса, сброс и проверка сигнализации, ручные и автоматические режимы насоса и задвижек.
Но структура программы осталась по моему выдуманному принципу
Сначала хотел при включении питания всё закрывать и выключать, но потом отказался от этой идеи, поэтому стадия Init пустая.
А зачем вам здесь SFC вообще?
Можно было накатать всё в одну простыню ST и всё, или сделать несколько программ (сколько там квадратиков, не считал) и запихать их в одну задачу на выполнение.
Думаю, что у вас не совсем правильный подход, решать надо конкретную задачу, до конца, вот и спрашивайте.
Разбирать надо простые примеры, как выложены на сайте.
От чужих проектов, толку будет ноль, потому, что вы не поймёте, как и что сделано и почему так. По своему опыту пишу.
Я, собственно и не собирался бросать начатое тех.задание.
Посмотрел, стрим Сергея Романова о разборе его программы на ST, что заметил, так он пишет CASE с шагом в 10, то есть 0,10,20,30 и т.д., чтобы в процессе разработки можно было легко внести промеж еще несколько шагов, при надобности. Еще он довольно редко в "IF" использует слово "FALSE" и "TRUE", а вместо этого пишет "NOT" и просто переменную. Например моя запись: IF abc=TRUE AND asd=FALSE THEN bcd:=TRUE;END_IF
И например Сергея запись: IF abc and NOT asd THEN bcd:=TRUE;END_IF Только мне пока не понятно, что это дает и есть ли в этом "полезная" разница. К тому же "IF" он применяет прямо в CASE, чего я не делал.
Вот ещё пример программы SFC+ST+FBD
Задача была - автоматизация работы бака-накопителя ГВС. Автоматическое или ручное управление одним насосом и несколькими задвижками, поддержание уровня в баке при помощи поплавкового датчика уровня с 4 дискретными сигналами.
Была экономия на физических кнопках (а значит и модулях ввода), поэтому с панели оператора были "кнопки" пуск/стоп процесса, сброс и проверка сигнализации, ручные и автоматические режимы насоса и задвижек.
Но структура программы осталась по моему выдуманному принципу
Сначала хотел при включении питания всё закрывать и выключать, но потом отказался от этой идеи, поэтому стадия Init пустая.
Спасибо за программы! Я топлю за ST, так как иногда приходится по мелочи залазить в программы контроллеров на работе и к примеру, что-нибудь откалибровать. Так вот, в какую установку не залезем, везде вся программа написана именно на ST. Будь то, контроллер SIEMENS или Allen Bradley.
Я, собственно и не собирался бросать начатое тех.задание.
Посмотрел, стрим Сергея Романова о разборе его программы на ST, что заметил, так он пишет CASE с шагом в 10, то есть 0,10,20,30 и т.д., чтобы в процессе разработки можно было легко внести промеж еще несколько шагов, при надобности. Еще он довольно редко в "IF" использует слово "FALSE" и "TRUE", а вместо этого пишет "NOT" и просто переменную. Например моя запись: IF abc=TRUE AND asd=FALSE THEN bcd:=TRUE;END_IF
И например Сергея запись: IF abc and NOT asd THEN bcd:=TRUE;END_IF Только мне пока не понятно, что это дает и есть ли в этом "полезная" разница. К тому же "IF" он применяет прямо в CASE, чего я не делал.
Так, на заметку. Запись IF abc=TRUE AND asd=FALSE THEN bcd:=TRUE;END_IF эквивалентна bcd := abc and not asd. Т.е. IF в некоторых случаях можно не использовать.
А полезная разница - меньше букв набирать
А зачем вам здесь SFC вообще?
Можно было накатать всё в одну простыню ST и всё, или сделать несколько программ (сколько там квадратиков, не считал) и запихать их в одну задачу на выполнение.
На форуме нет примеров структурированных программ, все - на едином листе. Спросить совета было не у кого. А самообразование приводит к причудливым решениям )
Исходя из предыдущего опыта не желал получать "простыню", а средствами CoDeSys (SFC) можно было упорядочить код, упростить навигацию по нему.
Работу с периодическими задачами сразу не освоил, а потом за 10 лет было всего четыре проекта в CoDeSys, которые нужно делать срочно - тут не до изысканий новых подходов, когда предыдущая структура устраивает.
По правде, за всё время у меня не возникало желания менять структуру, которую придумал с самого первого проекта. Не видел недостатков, одни достоинства в простой навигации (в дереве объектов подпрограммы, в SFC процессы), в возможности выбирать язык для каждой задачи, простая реализация инициализации при включении питания.
К слову, в OwenLogic уже несколько раз менял стиль и пока не могу определиться "со своим".
kondor3000
04.03.2024, 19:53
Я, собственно и не собирался бросать начатое тех.задание.
Посмотрел, стрим Сергея Романова о разборе его программы на ST, что заметил, так он пишет CASE с шагом в 10, то есть 0,10,20,30 и т.д., чтобы в процессе разработки можно было легко внести промеж еще несколько шагов, при надобности. Еще он довольно редко в "IF" использует слово "FALSE" и "TRUE", а вместо этого пишет "NOT" и просто переменную. Например моя запись: IF abc=TRUE AND asd=FALSE THEN bcd:=TRUE;END_IF
И например Сергея запись: IF abc and NOT asd THEN bcd:=TRUE;END_IF Только мне пока не понятно, что это дает и есть ли в этом "полезная" разница. К тому же "IF" он применяет прямо в CASE, чего я не делал.
Это всё азы, когда начинал, тоже писал b=true, потом подсказали и стал писать просто b или NOT b.
IF это проверка на истинность, он и проверяет, что b=true, (если NOT b проверка, что b=false) поэтому писать b=true это излишне и писать меньше.
IF можно использовать где угодно, в CASE и вне его.
А вот таймеры надо вызывать только вне IF, а в нём только присваивать входы или время.
МихаилГл
05.03.2024, 00:30
Так, на заметку. Запись IF abc=TRUE AND asd=FALSE THEN bcd:=TRUE;END_IF эквивалентна bcd := abc and not asd. Т.е. IF в некоторых случаях можно не использовать.
А полезная разница - меньше букв набирать
Маленько не эквивалентна.
Первая соответствует сигналу set триггера, вторая же сквозное присваивание, там и set и reset. А в первой reset можно вообще по другому условию прописать.
На форуме нет примеров структурированных программ, все - на едином листе. Спросить совета было не у кого. А самообразование приводит к причудливым решениям )
Исходя из предыдущего опыта не желал получать "простыню", а средствами CoDeSys (SFC) можно было упорядочить код, упростить навигацию по нему.
Работу с периодическими задачами сразу не освоил, а потом за 10 лет было всего четыре проекта в CoDeSys, которые нужно делать срочно - тут не до изысканий новых подходов, когда предыдущая структура устраивает.
По правде, за всё время у меня не возникало желания менять структуру, которую придумал с самого первого проекта. Не видел недостатков, одни достоинства в простой навигации (в дереве объектов подпрограммы, в SFC процессы), в возможности выбирать язык для каждой задачи, простая реализация инициализации при включении питания.
К слову, в OwenLogic уже несколько раз менял стиль и пока не могу определиться "со своим".
Ну, будет время, посмотрите при использование задач и отдельных программ - это более гибкое решение
Маленько не эквивалентна.
Первая соответствует сигналу set триггера, вторая же сквозное присваивание, там и set и reset. А в первой reset можно вообще по другому условию прописать.
Ступил, бывает. Спасибо, что заметили
Ну, будет время, посмотрите при использование задач и отдельных программ - это более гибкое решение
Сейчас, после обучения работе в CDS 3.5, хоть понимаю о чём речь. При возможности попробую.
МихаилГл
07.03.2024, 07:35
Просто пропустили
bcd := bcd or ( abc and not asd )
Только для сброса нужно потом где-то после этого условия ставить bcd :=0, главное с условием сброса не ошибиться.
На днях закончил свою первую программу на языке ST в среде Codesys v2.3. Не стал я использовать в программе другие языки, так как хотел изначально, чтобы она у меня была полностью только на ST. Как использовать в моей программе всего 2-3 таймера, я не разобрался, но в итоге мне так получилось нагляднее и проще. Хотелось бы еще поделить на отдельные блоки для лучшего понимания и читабельности программы. Комментарии опустил, в принципе как я обзывал переменные возвращаясь к программе спустя даже неделю, мне не много времени уходило, чтобы вспомнить и разобраться, что и куда.
Еще по поводу ST услышал авторитетное мнение, что он по сути не такой уж и перспективный. Как бы раньше программы на ПЛК писали в основном программисты и им естественно был роднее и ближе ST. Но с развитием ПЛК и появлением других языков, более перспективным может быть тот же FBD, так как на нем можно реализовать так же большинство программ, при чем более наглядных. К тому же вход в него(обучение, освоение) ниже, чем у того же ST, что позволяет большему количеству инженеров писать свои программы для ПЛК.
Интересно, что думают форумчане о написанной программе и перспективах FBD над ST.
https://disk.yandex.ru/d/utKkfkFrt83Bcw
Нет идеальных языков, каждый с недостатком.
Мне в ST не нравится возможность при вызове функционального блока не полностью перечислять параметры. Он, действительно, менее наглядный.
Но у него есть достоинства - естественное описание конечного автомата, легкость копирования и замены переменных (тегов) штатными средствами, компактность при распечатке.
FBD (и производный от него CFC) более нагляден для простых линейных алгоритмов, именно на FBD в проектах предлагают алгоритмы технологи, распечатками из проектов на FBD пользуются операторы при разборе неожиданного поведения системы.
Но при этом - занимает много места при распечатке, реализация циклических и ветвящихся алгоритмов возможна, но теряется наглядность, при необходимости многократного размножения участка кода требуется нетривиальные действия (в CoDeSys: экспорт элемента в текстовый файл xml, размножение объектов самодельным скриптом на python, импорт в CoDeSys).
Нельзя сказать, что один лучше другого. У каждого своя область применения.
Хороший пример этого тезиса - развитие Owen Logic: начинали с FBD, но добавили ST. И это несмотря на усложнение поддержки Owen Logic.
Осваивайте всё.
EVGEN_ я вот так скажу. пишу на FBD и C#, а на ST не могу. Его синтаксис просто убивает :) Но понять суть программы смогу, даже как-то переводил кусочек с Си на ST. то есть с бутылкой разберусь.
Все это дело привычки, понимания синтаксиса и т.д.. И вот чем хорош CodeSys, что можно варьировать языки в пределах одной программы. Потому что одно проще написать или иметь написанное на ST, другое на FBD или даже у вас есть часть кода на LAD, кем-то давно написанный.
kondor3000
06.04.2024, 12:00
Еще по поводу ST услышал авторитетное мнение, что он по сути не такой уж и перспективный. Как бы раньше программы на ПЛК писали в основном программисты и им естественно был роднее и ближе ST.
Интересно, что думают форумчане о написанной программе и перспективах FBD над ST.
https://disk.yandex.ru/d/utKkfkFrt83Bcw
По поводу ST не слушайте никого, вы даже и половины языка не освоили. Когда перейдёте к указателям и структурам, поймёте, что остальные языки полная лажа. Хотя сам использую немного CFC ( или FBD в Лоджике), для наглядности работы программы, на основном листе. Остальное на ST.
По поводу проекта, сделали и хорошо, проекта нет, поэтому и обсуждать нечего. Единственное, не разбили программу на ФБ, как писал.
Как по мне, чем думать над покупкой ненужного китайского частотника, лучше бы занялись работой с ФБ, обменом через биб-ки и далее к массивам, указателям и структурам.
Sergey666
08.04.2024, 10:50
Нет идеальных языков, каждый с недостатком.
А может быть субъективность восприятия индивидуальным юзером?
К примеру:
Мне в ST не нравится возможность при вызове функционального блока не полностью перечислять параметры.
А мне очень нравится не полное перечисление параметров ФБ.
Он, действительно, менее наглядный. Это кто как пишет...вы в книге текст читаете или картинки ищете? А если картинок нет, то книгу такую в печку, так?
Sergey666
08.04.2024, 10:57
Интересно, что думают форумчане о написанной программе и перспективах FBD над ST.
https://disk.yandex.ru/d/utKkfkFrt83Bcw
Предлагаете видосик глянуть и по нему прожект заценить? Вы издеваетесь? В Казахстане тоже ЕГЭ?
Ни каких першпектив у FBD вообще нет, отомрет как класс со временем.
МихаилГл
08.04.2024, 11:28
Предлагаете видосик глянуть и по нему прожект заценить? Вы издеваетесь? В Казахстане тоже ЕГЭ?
Ни каких першпектив у FBD вообще нет, отомрет как класс со временем.
Тем более в нём вообще нет возможности реализовать for ... to. Кроме как на st это не сделать. Вот чем мне ещё нравится Rockwell, так это возможностью сделать for ... to на LD. В результате там код получается с функциональностью ST, и в добавок с визуальными эффектами LD...
Sergey666
08.04.2024, 11:37
Тем более в нём вообще нет возможности реализовать for ... to. Кроме как на st это не сделать. Вот чем мне ещё нравится Rockwell, так это возможностью сделать for ... to на LD. В результате там код получается с функциональностью ST, и в добавок с визуальными эффектами LD...
У роквелла LD c приличным запасом инструментов и мне ни разу не потребовалось организовывать цикл.
МихаилГл
08.04.2024, 13:23
У роквелла LD c приличным запасом инструментов и мне ни разу не потребовалось организовывать цикл.
Возможно вы работали с маленькими проектами, а там, где около 50 однотипных и не только механизмов обвешенных десятком датчиков каждый только циклы спасают. 50 одинаковых подпрограмм в коде лучше заменить одной подпрограммой с входом в неё по циклу.
По поводу проекта, сделали и хорошо, проекта нет, поэтому и обсуждать нечего.
Прилагаю программу Дробильно-сортировочного комплекса и ТЗ
МихаилГл
08.04.2024, 17:15
Прилагаю программу Дробильно-сортировочного комплекса и ТЗ
Ну это скорее демка. Т.к. нет ни контроля скорости, ни контроля заштыбовки, ни ксл, ни ктв и пр. И без электрической принципиальной схемы ЭМ комплекта за такое программистам не стоит браться. Это по ТЗ замечания, код посмотреть пока возможности нет.
Для себя я вывел, что писать и отлаживать удобнее в CFC, а после, уже отлаженое и отработаное - переписать на ST, и уже в виде ST отдавать "в работу".
Т.е. по сути у меня почти для всего есть 2 проекта: "отладочный" на CFC и "рабочий" на ST. ;)
Для примера процедура управлени насосм.
Newcomer
09.04.2024, 09:40
Прилагаю программу Дробильно-сортировочного комплекса и ТЗ
ST явно не твой конек. Уж лучше CFC.
Прилагаю программу Дробильно-сортировочного комплекса и ТЗ
Вы действительно думаете, что кто-то будет вникать в этот код без единого комментария, выискивая соответствия между обозначениями в программе и ТЗ?
Да вы сами через месяц не вспомните что делаете в той или иной строке.
Используйте тип перечисление с осмысленными названиями для нумерации шагов.
Зачем сделаны присваивания выходов ФБ промежуточным переменным вроде
TP1(IN:=TP1_IN , PT:=T#5s , Q=>TP1_Q , ET=>TP1_ET );
чтобы потом написать
ZOOMER:=TP1_Q; ?
так можно сразу написать:
ZOOMER:=TP1.Q;
Аналогично вместо TP1_IN := FALSE; можно сразу писать TP1.IN := FALSE; , опуская потом IN при вызове ФБ TP1
Для себя я вывел, что писать и отлаживать удобнее в CFC, а после, уже отлаженое и отработаное - переписать на ST, и уже в виде ST отдавать "в работу".
Т.е. по сути у меня почти для всего есть 2 проекта: "отладочный" на CFC и "рабочий" на ST. ;)
Для примера процедура управлени насосм.
В принципе нормальное решение. Спасибо за совет
Вы действительно думаете, что кто-то будет вникать в этот код без единого комментария, выискивая соответствия между обозначениями в программе и ТЗ?
Да вы сами через месяц не вспомните что делаете в той или иной строке.
Используйте тип перечисление с осмысленными названиями для нумерации шагов.
По поводу комментарий согласен. Как писал ранее, за комментарий знаю, просто в этой итоговой программе опустил их. Программу начинал с самого начала несколько раз и по началу все комментировал. Ну и как не странно, порой из-за нехватки времени или энергии, после трудового дня, забрасывал все на 1-1,5 недели и потом возвращаясь к ней буквально за 5-10 минут понимал, что куда и откуда без комментов.
По поводу названий шагов можете пример привести? Просто тот же Сергей Романов так же называет шаги 0,1,10,20 и т.д.
Зачем сделаны присваивания выходов ФБ промежуточным переменным вроде
TP1(IN:=TP1_IN , PT:=T#5s , Q=>TP1_Q , ET=>TP1_ET );
чтобы потом написать
ZOOMER:=TP1_Q; ?
так можно сразу написать:
ZOOMER:=TP1.Q;
Аналогично вместо TP1_IN := FALSE; можно сразу писать TP1.IN := FALSE; , опуская потом IN при вызове ФБ TP1
Спасибо, попробую
...
По поводу названий шагов можете пример привести? Просто тот же Сергей Романов так же называет шаги 0,1,10,20 и т.д.
...
Создаёте новый тип данных enStep (на вкладке типы данных) с примерно таким содержимым (имена и числа произвольно):
TYPE enStep : (
gciStopped := 0, (* Остановлен *)
gciRun := 1, (* Запущен *)
gciPause := 10, (* Пауза *)
gciDelay := 30, (* Задержка *)
gciAvar := 31 (* Авария *)
);
END_TYPE
В программе используете например так:
Step: enStep; (* Объявление *)
...
IF ALARM THEN Step:=gciAvar; END_IF
...
IF Step=gciPause AND ...
...
CASE Step OF
gciRun: RED:=TRUE; GREEN:=FALSE; YELLOW:=FALSE; ZOOMER:=FALSE;
...
С типом данных "перечисление" можно работать, как с типом данных "INT"
Создаёте новый тип данных enStep (на вкладке типы данных) с примерно таким содержимым (имена и числа произвольно):
TYPE enStep : (
gciStopped := 0, (* Остановлен *)
gciRun := 1, (* Запущен *)
gciPause := 10, (* Пауза *)
gciDelay := 30, (* Задержка *)
gciAvar := 31 (* Авария *)
);
END_TYPE
В программе используете например так:
Step: enStep; (* Объявление *)
...
IF ALARM THEN Step:=gciAvar; END_IF
...
IF Step=gciPause AND ...
...
CASE Step OF
gciRun: RED:=TRUE; GREEN:=FALSE; YELLOW:=FALSE; ZOOMER:=FALSE;
...
С типом данных "перечисление" можно работать, как с типом данных "INT"
1exan , спасибо! Вроде понял.
Программа уже давненько написана, хотел по управлять через Скаду и продемонстрировать кое-кому. Все нарисовал, перенес с Codesys 2.3 в Codesys 3.5, но заметил проблему, что при длительном нажатии кнопки "Стоп", шаги пролетают, хотя должны отключаться по порядку с выдержкой времени. То, есть если мышкой кликнуть очень быстро, не задерживая палец на нажатии, то все ок). Не хочу вспоминать и разбираться в программе, можно поломать, то что работает. В общем как я понял, надо воткнуть R-Trig к кнопке "Стоп" и сделать это в скаде через скрипт. Но тут другое, Codesys 3.5 передает Word, а мне в скрипте надо как-то из него вытащить нужный бит, не пойму как. Например, в редакторе мнемосхем это делается просто и понятно, а как это сделать в списке активных каналов?
kondor3000
04.12.2024, 08:54
Программа уже давненько написана, хотел по управлять через Скаду и продемонстрировать кое-кому. Все нарисовал, перенес с Codesys 2.3 в Codesys 3.5, но заметил проблему, что при длительном нажатии кнопки "Стоп", шаги пролетают, хотя должны отключаться по порядку с выдержкой времени. То, есть если мышкой кликнуть очень быстро, не задерживая палец на нажатии, то все ок). Не хочу вспоминать и разбираться в программе, можно поломать, то что работает. В общем как я понял, надо воткнуть R-Trig к кнопке "Стоп" и сделать это в скаде через скрипт. Но тут другое, Codesys 3.5 передает Word, а мне в скрипте надо как-то из него вытащить нужный бит, не пойму как. Например, в редакторе мнемосхем это делается просто и понятно, а как это сделать в списке активных каналов?
Ерунду пишите, вы из скады можете обратиться прямо к нужному биту, надо только посчитать номер бита. Типа 0х 4
А триггер можно поставить в программе ПЛК после принятия бита.
Мало того, у вас в соотнесении прописаны именно биты (непонятно зачем), а обращаетесь вы из скады к маске.
Powered by vBulletin® Version 4.2.3 Copyright © 2025 vBulletin Solutions, Inc. All rights reserved. Перевод: zCarot