А какой тип имеет переменная в условии?
Вид для печати
Приведите полный текст функционального блока. Иначе гадать будем бесконечно
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 (см. скрин)!? Этот бесконечный цикл вообще не должен был даже начать выполняться.
В общем, пока прикрутил костыль, попробую загрузить потестировать. Но ощущение неполноценности остаётся >_<
Вложение 86526
Бесконечный цикл будет только в одном случае: когда Remaining > 0 и ни в одной итерации не выполняется условие (Number_Flowers_Gate[i] > 0 AND Gate_ON[i] = TRUE). Намбе флаверсы ваши приходят извне, за сим наши полномочия всё, ищите дальше сами
У вас при запуске срабатывает триггер R_TRIG_Switch_To_r6(I := Switch_Flowers_Set = FALSE); // Момент переключения стрелки на робот 6
Соответственно, выполняется это
и далееКод:// В момент переключения стрелки на робот 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;
Т.е., Corr_Total ваш равен не нулю, а 11Код:IF Switch_Flowers_Set = FALSE
THEN
Corr_Total := Corr_To_r6_Total;
ELSE
Corr_Total := Corr_To_r7_Total;
END_IF;
Господа, доброго времени! Подтолкните в правильном направлении, есть сетевой бит который записывает мастер панель ип320, его нужно сбрасывать в ПР200 по условию
На скрине сброс 3 бита (можно любой из 16) в регистре по условию Вложение 86537 бит должен быть один в регистре.
Только ИП320 сама биты не может ставить, можно только руками.
Вложение 86538
Целочисленные логические в ST пока не завезли, но можно так (сброс бита номер 0):
Код:function ResetBit: udint;
var_input
I : udint;
R : bool;
end_var
if R then I.0 := FALSE; end_if
ResetBit := I;
end_function
Мне кажется, можно сделать более универсальное решение, в смысле, чтобы было возможно писать любое значения выбранного бита(не только сбрасывать в "0"), короче, я это вижу примерно как-то так:
Вложение 86554
Вложение 86555
Вложение 86556
Т.к. одной командой, обычно, не ограничивается, то обрабатываю сразу всё слово управления от вышестоящей системы или панели.
Сразу принял, что от вышестоящей системы поступают только импульсные команды - действующие только один машинный цикл. Поэтому пришлось разработать макросы, обрабатывающие одиночные (записать моточасы) и парные переключающие (включить и выключить режим) команды.
На рисунке - выделение команд из принятого слова управления и фрагмент макроса (ФБ), выделяющего отдельные биты. Видно, что сразу после выделения бит всё принятое слово управления обнуляется целиком. Там ещё присутствует ограничение в получении команд на время инициализации при включении питания.
Вложение 86558
Вложение 86559
На рисунке обработка одиночной команды - записать значения моточасов - применение на холсте и содержимое макроса обработчика от двух источников (т.к. для ПР205 команда может быть получена и от панели и от встроенной панели)
это незаконченный проект и содержит небольшую недоработку - к выходу макроса Cmd_HMI_SCR_ нужно подключить переменную от встроенной панели для её автоматического сброса после обработки
Вложение 86560
Вложение 86561
Всем человеческое спасибо за ответы! Задача решена, но возникла другая)
Необходимо откалибровать аналоговые входа ПР200 по сопротивлению. Мастер юстировки предлагает свои значения сопротивлений, я не имея таких диапазонов сопротивления задал те, которыми располагал. В итоге юстирования получил сообщение "коэффициенты не рассчитаны" (что то подобное), подскажите, что мог упустить/сделать не так?
Вы сами ответили на свой вопрос.
Нужен источник эталонных сопротивлений, например магазин сопротивлений. https://docs.owen.ru/product/pr200/8...1#topic-108313
Тоесть, нужны именно те номиналы что запрашивает мастер юстировки?
Проблема вероятно не сама возникла, а Вы её сами создали на ровном месте, мне так кажется, мне почему-то ни разу не приходилось калибровать ПР200, хотя их было не меньше десятка, короче, наверно гораздо дешевле купить новое ПР200 чем приборы для калибровки, мне так кажется и больше туда не лезьте, так поступают обычно новички когда у них что-то не получается, не знаю зачем, у меня даже не хватает фантазии, наверно чтобы найти приключений на свою задницу!
Здравствуйте
Попал в руки ПР114-220-8Д4А, на нем начал изучение ПР.
Вопрос: подключился к ОЛ, во вкладке Прибор > Настройки прибора > Входы > Дискретные (только). Аналоговых входов нет. Подскажите, пожалуйста, в чем причина, ведь согласно маркировке прибора, рассчитывал увидеть 4 аналоговых входа?
Спасибо
Хорошо, вижу на холсте, в свойствах входа указал 0-10, подаю на вход 0-10, со входа подаю значение на "сравнение", но не вижу значения входа. Где ошибаюсь?
Вложение 86571
0-10 указали, а максимум по умолчанию 1, сделайте 10.
У вас эмуляция включена, то есть вам надо на входе задать вручную от 0 до 10. Эмуляция на скрине Вложение 86573
Для онлайн работы запишите проект в ПР, включите онлайн отладку, тогда можно будет подавать на вход 0-10
и видеть сколько пришло на вход.
Спасибо большое!
Доброе время суток, подскажите как реализовать поочерёдное включение насоса т.е накачал давление первый насос, для следующей сработки надо чтоб второй качал и так по очереди, делаю на ПР205. Заранее спасибо..
Почитайте пока здесь https://owen.ru/forum/showthread.php?t=41447
В простейшем случае так
Вложение 86751
Спасибо большое, Респект за понятный ответ)
Когда-то я делал так
https://www.cyberforum.ru/blogs/534277/6108.html
Это всего лишь пример для статьи на основе реальной программы. Должен работать.
Сейчас в совершенно другом стиле оформляю, проверяю больше (для ПР205 нужно ещё проверять разряд батарейки - хранение часов реального времени и параметров настройки - при разряде формирую сигнализацию).
Ещё проверял бы на сверхдлительную работу - "утечку в трубопроводе".
Сейчас изменил подход к программированию, если сможете понять моё изложение, то попробуйте делать так
https://www.cyberforum.ru/blogs/534277/10475.html
Там смысл разделения системы из двух насосов на три подсистемы (общая часть, насос 1, насос 2) и раздельной обработки ошибок для каждой из подсистем.
Т.к. от меня требуют визуализации на панели оператора, то для каждой подсистемы поддерживаю регистр с флагами состояния.
А также, поддерживаю возможность получения команд для каждой подсистемы от панели оператора (вкл/откл насос, ручн/авт и прочие).
Сама программа в этом примере содержит ошибку - отсутствует ротация, но это несущественно для пояснения подхода.
В случае аварии одного из насосов разве не разумно сделать чтобы на замену включался исправный насос, я так понимаю, Вы об этом не думали?!
Короче, здесь нечто подобное делали, вам подойдёт без какой либо доработки, в смысле, макрос переключения, правая часть на холсте:
https://owen.ru/forum/showthread.php...l=1#post424807
Вложение 86756
Для включения насосов по очереди можно использовать один из входов.
На второй, незадействованный вход можно подавать сигнал аварии насосов, тогда будет включаться исправный(резервный) насос, всё!
Примерно как то так:
Вложение 86760
Вложение 86759
А так, под ваше ТЗ, без включения резерва, этот проект подходит:
Вложение 86757
Вложение 86758
И, мне кажется, Вам ликбез какой-то нужно пройти, в смысле, это вроде простейшие элементы, проще некуда, как же Вы собираетесь что-то сделать не имея самых элементарных знаний в этой области, боюсь как бы Вы чего не натворили!
А что если нам написать универсальный ФБ на все случаи жизни (ротация насосов)?
С одновременным управлением с разных мест, с лёгким масштабированием (по числу насосов) и т.д.
Например для ПР200 и с ликбезом.
Уже давно этим занимаюсь, пока тут 10 версия последняя.
4-8 насосов___ https://owen.ru/forum/showthread.php...l=1#post426052
А тут 11 версия
5 насосов ___ https://owen.ru/forum/showthread.php...l=1#post471291
А началось всё с каскадов
Каскад из 4 котлов__до 3 версии___ https://owen.ru/forum/showthread.php...l=1#post418393
Каскадное управл. 8 котлами___ до 7 версии__ https://owen.ru/forum/showthread.php?t=38608#7
Для идеальной реализации не хватает возможностей ST в Лоджике.
Хотя при желании количество насосов и аварий можно менять вручную, хоть 32.
Люди добрые, подскажите.Пытаюсь поэксперементировать с ПИД регулятором в ПР 200. Аналоговый вход настроил 0-10ВВложение 86762_ перемычку в ПР выставил в режим 0-10В_подключаю контрольное напряжение3 вольта а там 0 Вложение 86763. Может ещё что то необходимо добавить в программу что бы ПРка увидила входной сигнал? До этого работал с 4-20ма и там все сразу можно было наблюдать изминения величины на входе:confused: