Приведите полный текст функционального блока. Иначе гадать будем бесконечно
function_block Self_healing // Самовосстановление микса
var_input
Sens_Output_r6: BOOL; // Датчик на выход к роботу 6
Sens_Output_r7: BOOL; // Датчик на выход к роботу 7
Switch_Flowers_Set: BOOL; // Стрелка горшков выпуска на 6-й и 7-й роботы (0=выпуск на 6-й робот, 1=выпуск на 7-й робот)
//
Number_Flowers_Gate1: UDINT; // Задание количества цветков
Number_Flowers_Gate2: UDINT; // Задание количества цветков
Number_Flowers_Gate3: UDINT; // Задание количества цветков
Number_Flowers_Gate4: UDINT; // Задание количества цветков
Number_Flowers_Gate5: UDINT; // Задание количества цветков
//
Gate1_ON: BOOL; // Включение выхода в соответствии с включением робота
Gate2_ON: BOOL; // Включение выхода в соответствии с включением робота
Gate3_ON: BOOL; // Включение выхода в соответствии с включением робота
Gate4_ON: BOOL; // Включение выхода в соответствии с включением робота
Gate5_ON: BOOL; // Включение выхода в соответствии с включением робота
// Задержки на выключение подсчёта цветов на выход роботов
TOF_Time_Switch_To_r6: UDINT; // Время задержки выключения подсчёта цветов на робота 6
TOF_Time_Switch_To_r7: UDINT; // Время задержки выключения подсчёта цветов на робота 7
end_var
var_output
Corr_Flower_1 : REAL; // Корректировка, выход 1
Corr_Flower_2 : REAL; // Корректировка, выход 2
Corr_Flower_3 : REAL; // Корректировка, выход 3
Corr_Flower_4 : REAL; // Корректировка, выход 4
Corr_Flower_5 : REAL; // Корректировка, выход 5
end_var
var
Counter_Output_r6 : UDINT; // Количество уехавших цветов на робот 6
Counter_Output_r7 : UDINT; // Количество уехавших цветов на робот 7
Corr_To_r6_Total : REAL; // Корректировка на робот 6, общая
Corr_To_r7_Total : REAL; // Корректировка на робот 6, общая
Corr_Total : REAL; // Корректировка на робот, общая
//Corr_To_r6_Array : Array [1..5] OF REAL; // Массив корректировок по линиям, на робот 6
//Corr_To_r7_Array : Array [1..5] OF REAL; // Массив корректировок по линиям, на робот 7
Corr_Array : Array [1..5] OF REAL; // Массив корректировок по линиям, на робот 7
Remaining : REAL;
i : UDINT;
// Фронт цветков на выпуск
R_TRIG_Sensor_Flowers_r6: SYS.RTRIG; // Датчик на выход к роботу 6
R_TRIG_Sensor_Flowers_r7: SYS.RTRIG; // Датчик на выход к роботу 7
// Задержки на выключение подсчёта цветов на выход роботов
TOF_Switch_To_r6: SYS.TOF; // Время задержки выключения подсчёта цветов на робота 6
TOF_Switch_To_r7: SYS.TOF; // Время задержки выключения подсчёта цветов на робота 7
R_TRIG_Switch_To_r6: SYS.RTRIG; // Момент переключения стрелки на робот 6
R_TRIG_Switch_To_r7: SYS.RTRIG; // Момент переключения стрелки на робот 7
Number_Flowers_Gate: ARRAY [1..5] OF UDINT; // Задание количества цветков
Gate_ON: ARRAY [1..5] OF BOOL; // Включение выхода в соответствии с включением робота
end_var
// Работа в массив данных
Number_Flowers_Gate[1] := Number_Flowers_Gate1;
Number_Flowers_Gate[2] := Number_Flowers_Gate2;
Number_Flowers_Gate[3] := Number_Flowers_Gate3;
Number_Flowers_Gate[4] := Number_Flowers_Gate4;
Number_Flowers_Gate[5] := Number_Flowers_Gate5;
//
Gate_ON[1] := Gate1_ON;
Gate_ON[2] := Gate2_ON;
Gate_ON[3] := Gate3_ON;
Gate_ON[4] := Gate4_ON;
Gate_ON[5] := Gate5_ON;
// Задержки включения и выключения стрелки
TOF_Switch_To_r6 (I := Switch_Flowers_Set = FALSE, T := udint_to_time(TOF_Time_Switch_To_r6)); // Время задержки выключения подсчёта цветов на робота 6
TOF_Switch_To_r7 (I := Switch_Flowers_Set = TRUE, T := udint_to_time(TOF_Time_Switch_To_r7)); // Время задержки выключения подсчёта цветов на робота 7
// Момент переключения стрелки на роботах
R_TRIG_Switch_To_r6(I := Switch_Flowers_Set = FALSE); // Момент переключения стрелки на робот 6
R_TRIG_Switch_To_r7(I := Switch_Flowers_Set = TRUE); // Момент переключения стрелки на робот 7
// Датчик на выход к роботу 6
R_TRIG_Sensor_Flowers_r6(I := Sens_Output_r6);
// Датчик на выход к роботу 7
R_TRIG_Sensor_Flowers_r7(I := Sens_Output_r7);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Подсчёт прошедших цветков на робот 6
IF R_TRIG_Sensor_Flowers_r6.Q = TRUE AND TOF_Switch_To_r6.Q = TRUE
THEN
Counter_Output_r6 := Counter_Output_r6 + 1;
END_IF;
// В момент переключения стрелки на робот 6
IF R_TRIG_Switch_To_r6.Q = TRUE
THEN
// Подсчёт корретировки (общее количество)
Corr_To_r6_Total := udint_to_real(11) - udint_to_real(Counter_Output_r6);
// Сброс подсчитанных цветов
Counter_Output_r6 := 0;
END_IF;
// Подсчёт прошедших цветков на робот 7
IF R_TRIG_Sensor_Flowers_r7.Q = TRUE AND TOF_Switch_To_r7.Q = TRUE
THEN
Counter_Output_r7 := Counter_Output_r7 + 1;
END_IF;
// В момент переключения стрелки на робот 7
IF R_TRIG_Switch_To_r6.Q = TRUE
THEN
// Подсчёт корретировки (общее количество)
Corr_To_r7_Total := udint_to_real(11) - udint_to_real(Counter_Output_r7);
// Сброс подсчитанных цветов
Counter_Output_r7 := 0;
END_IF;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
IF Switch_Flowers_Set = FALSE
THEN
Corr_Total := Corr_To_r6_Total;
ELSE
Corr_Total := Corr_To_r7_Total;
END_IF;
// // --- Положительная корректировка ---
IF Corr_Total > 0 THEN
// Обнуляем массив корректировок
FOR i := 1 TO 5 DO
Corr_Array[i] := 0;
END_FOR;
Remaining := Corr_Total;
WHILE Remaining > 0 DO
FOR i := 1 TO 5 DO
IF (Remaining > 0) AND (Number_Flowers_Gate[i] > 0 AND Gate_ON[i] = TRUE)
THEN
Corr_Array[i] := Corr_Array[i] + 1;
Remaining := Remaining - 1;
END_IF;
END_FOR;
END_WHILE;
END_IF;
// --- Отрицательная корректировка ---
IF Corr_Total < 0 THEN
// Обнуляем массив корректировок
FOR i := 1 TO 5 DO
Corr_Array[i] := 0;
END_FOR;
Remaining := ABS(Corr_Total);
i := 5; // начинаем с конца
WHILE Remaining > 0 DO
IF (i >= 1) THEN
IF (Number_Flowers_Gate[i] > 0 AND Gate_ON[i] = TRUE) THEN
Corr_Array[i] := Corr_Array[i] - 1;
Remaining := Remaining - 1;
ELSE
i := i - 1;
END_IF;
// Если текущая линия получила всё возможное убавление, идём дальше
IF (i >= 1) AND (ABS(Corr_Array[i]) >= udint_to_real(Number_Flowers_Gate[i])) THEN
i := i - 1;
END_IF;
ELSE
EXIT;
END_IF;
END_WHILE;
END_IF;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Corr_Flower_1 := Corr_Array[1]; // Корректировка, выход 1
Corr_Flower_2 := Corr_Array[2]; // Корректировка, выход 2
Corr_Flower_3 := Corr_Array[3]; // Корректировка, выход 3
Corr_Flower_4 := Corr_Array[4]; // Корректировка, выход 4
Corr_Flower_5 := Corr_Array[5]; // Корректировка, выход 5
end_function_block
Мне просто не понятно, почему выполняется та часть операнда IF, если условие не выполняется.
Разве ПР не должен пропускать те строки, которые идут после THEN если условие не выполнилось?
Вот проблема
Если Number_Flowers_Gate[i] равен нулю (а он изначально равен нулю) или Gate_ON[i] выключен (а он выключен) у нас тупо не выполняется операция Remaining := Remaining - 1; и получаем бесконечный цикл.Код:WHILE Remaining > 0 DO FOR i := 1 TO 5 DO IF (Remaining > 0) AND (Number_Flowers_Gate[i] > 0 AND Gate_ON[i] = TRUE) THEN Corr_Array[i] := Corr_Array[i] + 1; Remaining := Remaining - 1; END_IF; END_FOR; END_WHILE;
При запуске ПР в первом цикле действительно всё нули.
Но он же не должен был смотреть всё что между THEN и END_IF (см. скрин)!? Этот бесконечный цикл вообще не должен был даже начать выполняться.
В общем, пока прикрутил костыль, попробую загрузить потестировать. Но ощущение неполноценности остаётся >_<
Снимок.JPG