Добрый день!
Имеется задача написать программу для ПР на установку мойки КЕГ по заданной циклограмме (во вложении)
Сначала попробовал написать на основе логистических функций, но понял что будет очень громоздко.
Перерыл форум нашёл похожий проект https://owen.ru/forum/showthread.php...l=1#post106727 , но к сожалению файлы уже не доступны и связи с авторами нет.
Суть работы установки: по нажатию кнопки "ПУСК" (I1) происходит запуск цикла из последовательных 40 шагов, у каждого шага своё время на которое должны открываются заданные клапана соответствующие выходам (Q1-Q8)
В теории понимаю, что нужно использовать макросы ПЗУ, так же нашёл на форуме https://owen.ru/forum/showthread.php...l=1#post322919, но не хватает тяма адаптировать их под свой проект.
Буду очень признателен за помощь.
photo_2026-04-16_08-25-11.jpg
то есть вы даже не потрудилсь таблицу перевести в нормальный вид и предлагаете разбирать в мятой бумажке?
то есть вы для себя поставили задачу так - найти чьёто готовое, отрихтовать малось под себя и готово?Перерыл форум нашёл похожий проект https://owen.ru/forum/showthread.php...l=1#post106727 , но к сожалению файлы уже не доступны и связи с авторами нет.
и установка по мойке кег - это коммерция, это даже не ленивый студент, который может встретить понимание
и в чём проблема?по нажатию кнопки "ПУСК" (I1) происходит запуск цикла из последовательных 40 шагов, у каждого шага своё время на которое должны открываются заданные клапана соответствующие выходам (Q1-Q8)
вы не сделали ни единого куска кода?
На 40 шагов, лучше использовать язык ST, тут пример на 6 режимов по 0+12 шагов, или Шаговик - можно сделать и 40 шагов.
И ещё помочь, это не значит сделать за вас, так что делайте сами и спрашивайте, что не понятно.
Простой шаговый автомат, новый TON с паузой_____ https://owen.ru/forum/showthread.php...39&page=43#424
Прогр. управление 6 нагрузками 6 реж. 12 шагов _ФБ_фунции_____https://owen.ru/forum/showthread.php...39&page=11#105
Последний раз редактировалось kondor3000; 20.04.2026 в 09:54.
Добрый день!
Можете использовать подобные конструкции :
FUNCTION_BLOCK STE_P
VAR_INPUT
U : BOOL; // Сигнал запуска / импульс
Res : BOOL; // Сброс
END_VAR
VAR_OUTPUT
Q : UDINT; // Текущее значение счётчика
I1, I2, I3, I4: BOOL; // Выходы таймеров
En_d : BOOL; // Флаг завершения (CounterValue = 5)
END_VAR
VAR
CounterValue : UDINT := 0;
// Фронты
FTrig, FTriga, FTrigb, FTrigc, FTrigd : BOOL;
// Таймеры
TP1, TP2, TP3, TP4 : SYS.TP;
FT1, FT2, FT3, FT4 : SYS.FTRIG;
END_VAR
// Сброс счётчика и состояний
IF Res THEN
CounterValue := 0;
FTrig := FALSE;
FTriga := FALSE;
FTrigb := FALSE;
FTrigc := FALSE;
FTrigd := FALSE;
En_d := FALSE;
END_IF;
// Шаг 1: Приход импульса U (фронт) — установка счётчика в 1
IF U AND NOT FTrig THEN
FTrig := TRUE;
IF NOT Res THEN
CounterValue := 1;
END_IF;
END_IF;
// Сброс фронта U после отпускания
IF NOT U THEN
FTrig := FALSE;
END_IF;
// Таймер TP1: активен при U и счётчике = 1
TP1(I := (CounterValue = 1), T := T#3s, Q => I1);
// Фиксируем завершение TP1
FT1(I := TP1.Q);
IF FT1.Q THEN
FTriga := TRUE; // Готов к шагу 2
END_IF;
// Шаг 2: после TP1.Q и если счётчик = 1 → увеличиваем до 2
IF FTriga AND (CounterValue = 1) THEN
CounterValue := 2;
FTriga := FALSE; // Сброс флага, чтобы не повторить
END_IF;
// Таймер TP2: активен при счётчике = 2
TP2(I := (CounterValue = 2), T := T#4s, Q => I2);
// Фиксируем завершение TP2
FT2(I := TP2.Q);
IF FT2.Q THEN
FTrigb := TRUE;
END_IF;
// Шаг 3: переход к 3
IF FTrigb AND (CounterValue = 2) THEN
CounterValue := 3;
FTrigb := FALSE;
END_IF;
// Таймер TP3: при счётчике = 3
TP3(I := (CounterValue = 3), T := T#5s, Q => I3);
FT3(I := TP3.Q);
IF FT3.Q THEN
FTrigc := TRUE;
END_IF;
// Шаг 4: переход к 4
IF FTrigc AND (CounterValue = 3) THEN
CounterValue := 4;
FTrigc := FALSE;
END_IF;
// Таймер TP4: при счётчике = 4
TP4(I := (CounterValue = 4), T := T#6s, Q => I4);
FT4(I := TP4.Q);
IF FT4.Q THEN
FTrigd := TRUE;
END_IF;
// Шаг 5: переход к 5
IF FTrigd AND (CounterValue = 4) THEN
CounterValue := 5;
FTrigd := FALSE;
END_IF;
// Выход Q — текущее значение счётчика
Q := CounterValue;
// Сигнал завершения
IF CounterValue = 5 THEN
En_d := TRUE;
ELSE
En_d := FALSE;
END_IF;
END_FUNCTION_BLOCK
А с выхода Q udint зная номер шага через CASE можно как угодно
Не очень
1. Если у нас таймеры не работают одновременно, то можно использовать только 1 таймер
2. Конструкция
это вы реализовали в целом детектор переднего фронта (RTRIG)Код:// Шаг 1: Приход импульса U (фронт) — установка счётчика в 1 IF U AND NOT FTrig THEN FTrig := TRUE; IF NOT Res THEN CounterValue := 1; END_IF; END_IF; // Сброс фронта U после отпускания IF NOT U THEN FTrig := FALSE; END_IF;
да и эта часть масло маслено
3. После прихода сигнала сброс (RES), таймеры ТП продолжат отсчет и запустив алгоритм заново можно очень удивитьсяКод:// Фиксируем завершение TP1 FT1(I := TP1.Q); IF FT1.Q THEN FTriga := TRUE; // Готов к шагу 2 END_IF; // Шаг 2: после TP1.Q и если счётчик = 1 → увеличиваем до 2 IF FTriga AND (CounterValue = 1) THEN CounterValue := 2; FTriga := FALSE; // Сброс флага, чтобы не повторить END_IF;
В последнем Лоджике массивы завезли, так что можно так сделать
Код:function_block Control var_input StepIn : udint; //текущий шаг (нужен для реализации энергонезависимости) Start : bool; //кнопка запуска (НО) Stop : bool; //кнопка останова (НЗ) arTm : array[1..40] of udint; //массив уставок таймера StepNum : udint := 40; //задание количества шагов end_var var_output StepOut : udint; //текущий шаг Inwork : bool; //флаг работы Done : bool; //флаг окончания работы end_var var TmConst : udint := 1000; //множитель для уставки таймера (1000 - сек, 60000 - мин) TmStep : SYS.TON; //таймер bTm : bool; //флаг окончания отсчета таймера bSt : SYS.RTRIG; //защита от залипания кнопки Start (можно и без неe) end_var //проверка корректности задания StepNum if StepNum > 40 then StepNum := 40; end_if //обработка нажатия кнопки Start bSt(I := Start and (StepNum > 0)); //остановка или запуск программы if not Stop or (StepNum = 0) then StepIn := 0; Done := false; elsif bSt.Q then StepIn := 1; Done := false; end_if //определение уставки таймера if StepIn > 0 then TmStep.T := udint_to_time(arTm[StepIn] * TmConst); end_if //управление таймером TmStep(I := not bTm and (StepIn > 0), Q => bTm); //управление шагами if bTm then StepIn := StepIn + 1; if StepIn > StepNum then StepIn := 0; Done := true; end_if end_if Inwork := StepIn > 0; StepOut := StepIn; end_function_block