PDA

Просмотр полной версии : Цикл WHILE



EugeneMoor
14.08.2024, 20:07
Добрый день.

Столкнулся с проблемой.

Не работает цикл While в коде (но работал в режиме эмуляции).

Используется ПЛК 200-01-CS.

Речь идет про подобные куски кода:
https://sun9-76.userapi.com/impg/YNMTN0mKyjtAWaR2o9T-z-qu1xMKA8IrdB9ptw/h0aMkezRwSc.jpg?size=818x643&quality=96&sign=9f43d189c9a3785cd923fa7436262628&type=album

Суть следующая: приходит оператор, устанавливает несколько точек нагрева с удержанием в определенный промежуток времени при достижении уставки.

Значения, заданные оператором, с помощью оператора case и переменной изменения индекса этого самого case, все время хранятся в одной переменной, что позволяет корректно выполняться программе.

Если углубляться в работу, то установил оператор 2 уставки и задал время поддержания для каждой:
200 градусов 30 секунд
100 градусов 20 секунд
300 градусов 10 секунд

ПИД регулятор доводит температуру до 200, в течении 30 секунд поддерживает ее, после чего отключается.
Температура падает до 100. Как только значение текущей температуры <= 100, то запускается очередной таймер, но уже на 20 секунд.
После чего, температура вновь начинает расти до 300 градусов и держится 10 секунд.

И как раз таки, когда оператор указал температуру на понижение, то этот while позволяет мне удерживать цикл и не идти дальше...

Не могу решить проблему, потратил уже невероятно много времени.

Программированием недавно начала заниматься, поэтому за код не осуждайте(

Была задача, нужно было сделать, начал разбираться в программирование - дошел до этого.

Прикладываю частичную демонстрацию работу:
https://vk.com/video/@eugenemoor99?z=video463512182_456239879%2Fln-YcvDFfJGEeCjXzXveH%2Fpl_463512182_-2
https://vk.com/video/@eugenemoor99?z=video463512182_456239878%2Fln-9l5uDz8XoAqgPEsrtK%2Fpl_463512182_-2

Буду рад любой помощи. Возможно кто-то сможет помочь за оплату. Прикладываю проект в том числе...

МихаилГл
14.08.2024, 20:45
Не нравится мне вайл... Может переделать на то что внутри на иф зэн, а то что снаружи на элсэ...?

kondor3000
14.08.2024, 22:23
Думаю удерживать автомат CASE на данном шаге, с помощью WHILE, это плохая идея. Автомат и так будет стоять на данном шаге, пока вы не сделаете управление шагом +1. Точнее программа будет работать, а шаг стоять.
Вот тут вам и надо думать. Предусмотреть все условия перехода. А WHILE вообще все выкинуть.

МихаилГл
15.08.2024, 04:36
Думаю удерживать автомат CASE на данном шаге, с помощью WHILE, это плохая идея. Автомат и так будет стоять на данном шаге, пока вы не сделаете управление шагом +1. Точнее программа будет работать, а шаг стоять.
Вот тут вам и надо думать. Предусмотреть все условия перехода. А WHILE вообще все выкинуть.

У ТС шаг прибавляется перед case... Это условие надо тоже внутрь IF ... THEN ... ELSE перемещать. А во-вторых, программа сильно громадная, ее надо сворачивать в условие FOR, реально ее в 5 раз уменьшить. Очень много лишних операций, вернее даже однотипных.

PS Например так (писалось в блокноте, надо проверять):

IF tempReached = TRUE and not bit_x THEN
bit_x:= TRUE; //бит, чтобы обрабатывать только один раз, после надо его снова сделать ложью
flagOne:=false;
holdingTimer(IN := FALSE, PT := T#0S);
//currentTempIndex := currentTempIndex + 1; - это тут не надо
currentTempIndex := 1; //как раз для первого опроса сойдет
end_if
t_ix:= t[currentTempIndex];//Массив температур
IF t_ix > 0 and currentTempIndex <= 10 THEN
IF t_ix < xAi6 THEN
integral := 0.0;
previousError := 0.0;
xAo1 := 0;
timerPID(IN := FALSE);
mainflag:=true;
else
mainflag:=false;
tempReached:=false;
targetTemp := t_ix;
holdingTime := TimeForCalibration;
tempReached:=FALSE;
currentTempIndex := currentTempIndex + 1;
END_IF
elsif currentTempIndex > 10
timerPID(IN := FALSE, PT := T#0s);
TimeHeat(IN := FALSE, PT := T#0s);
//holdingTimer(IN := FALSE, PT := T#0s);
Calibration:=false;
xAo1:=0;
integral := 0.0;
previousError := 0.0;
//currentTempIndex:=1;
MassiveForCalibration:=1;
mainflag:=false;
bit_x:= FALSE;////////////////////////////
end_if

EugeneMoor
15.08.2024, 07:22
Спасибо! Сегодня попробую

Cs-Cs
15.08.2024, 09:22
1. Я позволю себе напомнить то, что в ПЛК программа выполняется так:
* Получает все входы
* Выполняет код программы
* Выдаёт то, что получилось, на выходы
То есть, WHILE в ПЛК прокрутится СРАЗУ и ЦЕЛИКОМ за один цикл работы ПЛК. Без промежуточных итераций.
Он не будет, как в СИ, крутиться постоянно.

2. Я тут вижу таймер timerPID. Он вызывается с IN = FALSE, но тогда, когда его надо остановить.
А где он вызывается для того, чтобы он РАБОТАЛ?
Может быть поможет подзаголовок 7 моей статьи: https://cs-cs.net/funkciya-fun-i-funkcionalniy-blok-fb-codesys-owenlogic#7__fb_ton_tof_tp_blink

Sergey666
15.08.2024, 11:22
Добрый день.

Столкнулся с проблемой.

Не работает цикл While в коде
Программированием недавно начала заниматься, поэтому за код не осуждайте(


Забудьте вообще про циклы, это для опытных, тем более путь решения задачи через CASE выбран правильно, но с организацией цикла получилась полная каша.
При организации конечного автомата управление указателем производится из Стэйта, а на сначала, как у вас, повторяю у вас полный не рабочий говнокод. Учится и осваивать надо поступательно, а не все сразу.

EugeneMoor
15.08.2024, 12:18
Всем спасибо. Я справился. Сделал:)

if flagOne = true then
HoldingTimer (IN := TRUE, PT := holdingTime); // Запуск таймера поддержания
IF HoldingTimer.ET > T#90S THEN
CollectionTimer(IN := TRUE, PT := T#1S);
if CollectionTimer.Q = true then
targetMassive[Index] := xAi7;
Index := Index + 1;
CollectionTimer(IN := FALSE);
end_if
end_if
if HoldingTimer.Q = true THEN
tempReached := TRUE;
massiveReacher:=true;
currentTempIndex := currentTempIndex + 1;
end_if
end_if

IF tempReached = TRUE THEN
CASE currentTempIndex OF
2: IF t2 > 0 THEN
IF (T2<xAi6) THEN
integral := 0.0;
previousError := 0.0;
xAo1 := 0;
// Остановка таймера PID
timerPID(IN := FALSE);
mainflag:=true;
holdingTimer(IN := FALSE);
holdingTime := TimeForCalibration;
elsif (xAi6 <= T2) or (xAi6 <= targetTemp) then
targetTemp := t2;
holdingTimer(IN := FALSE);
holdingTime := TimeForCalibration;
flagOne:=false;
mainflag:=false;
tempReached:=FALSE;
end_if
END_IF

Cs-Cs
15.08.2024, 12:28
Во! Прям по моей статье: и циклы, которые работают не так, как в компьютерах, и вызовы таймеров в условиях. Были!
Молодец, здорово! Поздравляю!

Валенок
15.08.2024, 16:38
Во! Прям по моей статье: и циклы, которые работают не так, как в компьютерах, и вызовы таймеров в условиях. Были!
Молодец, здорово! Поздравляю!
С чем? 20 переменных на 40 строк одного блока? Юзать автомат а менять его где-то в бубенях (см.пост#7)?
С IF'ом вложенным в IF вложенным в CASE вложенным в IF? Глубина вложения не ограничена, чо.


Я справился. Сделал:)
Сделал. Как-то работает. Даихусим. Зачем только было показывать?

EugeneMoor
18.08.2024, 13:35
Все в порядке, я учусь, все приходит с опытом. Я вообще студент, и я проектировщик)