Вход

Просмотр полной версии : ПР205 Код на ST не выполняется циклически



Niy
09.09.2026, 09:12
Добрый день, вкратце алгоритм работы кода: если флаг выполнения шага не активна, то поднимаются необходимые выхода, запускается таймер на время, как достигли заданного значения - отключаем выхода, деактивируем флаг выполнения данного шага, поднимаем шаг выполнения следующего шага. И так циклически( вроде, должна работать) Но , почему-то первый цикл проходить нормально, а потом какая чихарда. Особо не пинайте, после Kotlin что-то трудновато программирование ПЛК :)




var_input
start : bool;
tPause:udint := 2000;
end_var

var_output
relay1 : bool;
relay2 : bool;
relay3 : bool;
relay4 : bool;
relay5 : bool;
relay6 : bool;
vklR:udint:=16;

end_var

var
step0:bool:=false;
step1:bool:=true;
step2:bool:=true;
step3:bool:=true;
step4:bool:=true;
step5:bool:=true;
step6:bool:=true;
step7:bool:=true;

TON_1:SYS.TON;
TonTime: TIME;
qOut:bool;
t_50s:udint := 5000;
t_1s:udint := 4000;

end_var

if start then
relay6:=true;

// шаг0 пауза ------------------------------------------------
if not step0 then
TonTime := UDINT_TO_TIME( tPause);
TON_1(I := true, T := TonTime, Q => qOut);
if qOut =true then
TON_1(I:=false);
step0:=true; //больше не выполняем этот шаг
step1:=false; //доступ к следующему шагу
end_if
end_if


// шаг1 --- кл2,17(реле1) кл3,7(реле2) ,кл6(реле5) открыты на 50 сек
If not step1 then
vklR:=1; //для наблюдения(временно)
relay1:=true; //вкл реле
relay2:=true;
relay5:=true;
TonTime := UDINT_TO_TIME( t_1s);
TON_1(I := true, T := TonTime, Q => qOut); //запускаем таймер

if qOut =true then //если достигли значения
vklR:=0;
relay1:=false; //отключаем
relay2:=false;
relay5:=false;
step1:=true; //больше не выполняем этот шаг
step2:=false; // доступ к следующему шагу
TON_1(I:=false);
end_if
end_if


// шаг2 пауза ------------------------------------------------
if not step2 then
vklR:=2;
TonTime := UDINT_TO_TIME( tPause);
TON_1(I := true, T := TonTime, Q => qOut);
if qOut =true then
vklR:=0;
TON_1(I:=false);
step2:=true; //больше не выполняем этот шаг
step3:=false; //доступ к следующему шагу
end_if
end_if


// шаг3 --- кл3,7(реле2) кл4,8 (реле3) открыты на 1 сек
If not step3 then
vklR:=3;
relay2:=true;
relay3:=true;
TonTime := UDINT_TO_TIME( t_1s);
TON_1(I := true, T := TonTime, Q => qOut);

if qOut =true then
vklR:=0;
relay2:=false;
relay3:=false;
TON_1(I:=false);
step3:=true; //больше не выполняем этот шаг
step4:=false; //доступ к следующему шагу
end_if

end_if



// шаг4 пауза ------------------------------------------------
if not step4 then
vklR:=4;
TonTime := UDINT_TO_TIME( tPause);
TON_1(I := true, T := TonTime, Q => qOut);
if qOut =true then
vklR:=0;
TON_1(I:=false);
step4:=true; //больше не выполняем этот шаг
step5:=false; //доступ к следующему шагу
end_if
end_if



// шаг5 --- кл2,17(реле1) кл4,8(реле3) кл5(реле4) открыты на 50 сек
If not step5 then
vklR:=5;
relay1:=true;
relay3:=true;
relay4:=true;
TonTime := UDINT_TO_TIME( t_1s);
TON_1(I := true, T := TonTime, Q => qOut);

if qOut =true then
vklR:=0;
relay1:=false;
relay3:=false;
relay4:=false;
TON_1(I:=false);
step3:=true; //больше не выполняем этот шаг
step6:=false; //доступ к следующему шагу
end_if

end_if

// шаг6 пауза ------------------------------------------------
if not step6 then
vklR:=6;
TonTime := UDINT_TO_TIME( tPause);
TON_1(I := true, T := TonTime, Q => qOut);
if qOut =true then
vklR:=0;
TON_1(I:=false);
step6:=true; //больше не выполняем этот шаг
step7:=false; //доступ к следующему шагу
end_if
end_if


// шаг7 --- кл3,7 (реле2) кл4,8 (реле3) открыты на 1 сек
If not step7 then
vklR:=7;
relay2:=true;
relay3:=true;
TonTime := UDINT_TO_TIME( t_1s);
TON_1(I := true, T := TonTime, Q => qOut);
if qOut =true then
vklR:=0;
relay2:=false;
relay3:=false;
TON_1(I:=false);
step7:=true; //сброс остальных шагов(активируются по цепочке после 1-го шага)
step0:=false;
end_if
end_if


//-------------------------------------------------------------

else
relay1:=false;
relay2:=false;
relay3:=false;
relay4:=false;
relay5:=false;
relay6:=false;
end_if




https://disk.yandex.ru/i/DNqtPfPeE-CApA

Khedron
09.09.2026, 10:07
У вас один и тот же таймер TON_1 завернут в разные IF с разными уставками времени. В одном шаге запустили с одной уставкой, перешли в другой шаг а TON_1 уже работает с предыдущей, потому что не дотикал и вы его не сбрасывали.
Либо делайте разные таймеры под каждый шаг, либо выносите общий таймер наружу и пере-сбрасывайте его перед использованием.
Лучше переделайте код под CASE с конечным автоматом, если есть возможность. И нагляднее и проще контролировать.

Niy
09.09.2026, 10:24
Спасибо за ответ, нашел ошибку, код рабочий. в шаге 5 написал step3:=true; , вместо step5:=true; Не могу удалить сообщение.

kondor3000
09.09.2026, 10:31
Спасибо за ответ, нашел ошибку, код рабочий. в шаге 5 написал step3:=true; , вместо step5:=true; Не могу удалить сообщение.

Примеры, как делать шаговый автомат на 1 таймере
Простой шаговый автомат, новый TON с паузой и вых. времени_____ https://owen.ru/forum/showthread.php?t=38239&page=43#424
Прогр. управление 6 нагрузками 6 реж. 12 шагов _ФБ_фунции_____https://owen.ru/forum/showthread.php?t=38239&page=11#105

Niy
09.09.2026, 11:27
Khedron перешли в другой шаг а TON_1 уже работает с предыдущей, потому что не дотикал и вы его не сбрасывали.


Почему не сбрасываю? Я же при каждом переходе на следующий сбрасываю таймер строчкой TON_1(I:=false);, конечно, на всякий случай можно еще добавить TON_1(Т:=Т#0ms);