Подскажите, а работают ли в st функции PUTBIT и EXTRACT? И не планируется ли добавить логические операции с целыми числами? (пр. 5 AND 3 = 1; 5 OR 3 = 7)
Вид для печати
Подскажите, а работают ли в st функции PUTBIT и EXTRACT? И не планируется ли добавить логические операции с целыми числами? (пр. 5 AND 3 = 1; 5 OR 3 = 7)
Констант еще нехватает.
Попробовал. Не вариант. case не работает с переменными.
Хотелось состояниям автомата дать осмысленные названия, а не просто числа.
Не, именованые константы/перечисления - очень удобны для таких вещей.
Например, если бы мне надо было вставить в код выше состояние "Прыжок на месте" - то не пришлось бы перенумеровывать все состояния ниже внутри кода, достаточно поправить константы.
Жаль что в OL это не поддержано (хотя бы константы)
предлагалось вообще не воспринимать цифры, а вдумчиво вчитываться в коммент к кейсу
чем это предложение отличается от простой переменной? Константа удобна тем что запись в неё вызовет скорее всего ошибку компилятора, а так её спокойно заменяет обычная переменная, где это возможно в зависимости от среды разработки
Не. Не надо играться с магическими числами. Лучше константы. И ещё и для границ массивов.
Перечисления, структуры и константы удобны в больших программах, когда в разных блоках нужно использовать унифицированные значения. В Лоджике же блоки на ST - это, все-таки локальные самодостаточные макросы. Не думаю, что ST в Лоджике перерастет во что-то большее - для этого, думаю, надо заново всю среду разработки переписывать
программа может быть несложной, но из полсотни шагов. И ни какое комментирование, особенно на пнр, не заменит автоматическую перенумерацию которая пофакту будет при использовании констант/перечислений. Особенно при куче ветвлений.
Добрый день!
Подскажите пожалуйста, почему при изменении переменной udisel оператор if не переключает выходы?
Необходимо что бы выход Start кратковременно менял значение при изменении udisel для работы Rise_fall.
//область кода
xOut1 := 0;
xOut2 := 0;
xOut3 := 0;
Start := false ;
if (udiSel >= 0) or (udiSel <= 1) then
xOut1 := IN0_0;
xOut2 := IN0_1max;
xOut3 := D0_1;
Start := true ;
ELSIF udiSel >= 2 THEN
Start := false ;
ELSIF (udiSel >= 2) or (udiSel <=7) then
xOut1 := IN0_1max;
xOut2 := IN2_7max;
xOut3 := D2_7;
Start := true ;
ELSIF udiSel >= 8 THEN
Start := false ;
end_if
end_function_block
udiSel >= 0 захватывает весь диапазон значений udiSel
наверно хотели написать что-то типа (udiSel >= 0) AND (udiSel <= 1) ?
попробуйте CASE - наверное будет проще
Answer | Phind Instant Model
В вашем коде есть несколько моментов, которые могут привести к тому, что оператор if не переключает выходы так, как вы ожидаете. Давайте разберемся с ними подробнее:
Проблема с логикой условий
Ваш код содержит несколько блоков ELSIF, каждый из которых проверяет различные диапазоны значений udiSel. Однако, последовательность этих условий и их формулировка могут приводить к непредвиденному поведению. В частности, если udiSel находится в диапазоне от 2 до 7 включительно, то выполняется только первый блок ELSIF, который устанавливает Start в true, но не обновляет значения xOut1, xOut2, и xOut3. Это происходит потому, что после выполнения первого условия, остальные условия не проверяются из-за использования ключевого слова ELSIF.
Чтобы исправить это, вам нужно либо объединить условия, чтобы они корректно перекрывались, либо использовать отдельные операторы if для каждого условия, чтобы каждое из них могло быть проверено независимо.
Использование OR вместо >=
Вы используете оператор or (or) для проверки диапазонов значений udiSel. Это может привести к тому, что одно из условий будет истинным даже если udiSel находится вне этого диапазона. Например, (udiSel >= 0) or (udiSel <= 1) будет истинным для любого значения udiSel, поскольку хотя бы одно из условий всегда выполняется. Возможно, вы хотели использовать оператор and (and), чтобы оба условия должны выполняться одновременно.
Рекомендации по исправлению
Пересмотрите логику условий: Убедитесь, что условия корректно перекрывают все возможные значения udiSel и что нет случайных истинностей из-за неправильного использования операторов or или and.
Используйте отдельные операторы if для каждого блока: Это позволит каждому блоку условий быть проверенным независимо, избегая проблем с перекрытием.
Проверьте логику установки Start: Убедитесь, что установка Start в false соответствует вашим требованиям и не мешает правильной работе системы.
Пример исправленного кода:так ответила бездушная машина, вдруг угадалаКод:xOut1 := 0;
xOut2 := 0;
xOut3 := 0;
Start := false;
if (udiSel >= 0) and (udiSel <= 1) then
begin
xOut1 := IN0_0;
xOut2 := IN0_1max;
xOut3 := D0_1;
Start := true;
end
else if udiSel >= 2 and udiSel < 8 then
begin
xOut1 := IN0_1max;
xOut2 := IN2_7max;
xOut3 := D2_7;
Start := true;
end
else if udiSel >= 8 then
begin
Start := false;
end;
А можно поинтересоваться, как вы именно хотите моргать переменной Start? При каждом изменении udiSel взвести на один цикл или сбросить на один цикл?
И да, у вас тут несколько ошибок
1. if (udiSel >= 0) or (udiSel <= 1) then - сразу отбрасывает все остальные сравнения, наверное, вы хотели if (udiSel = 0) or (udiSel = 1)
2. ELSIF udiSel >= 2 THEN - отбрасывает следующее сравнение, вероятно здесь вы пытались моргнуть
3. ELSIF (udiSel >= 2) or (udiSel <=7) then - отбрасывает следующее сравнение, тут, наверное ELSIF (udiSel >= 2) and (udiSel <=7)
4. ELSIF udiSel >= 8 THEN - как бы лишний, потому что вначале вы уже сбросили переменную Start
Да, мне нужно при каждом изменении значения udiSel, на один цикл изменять выход Start. Спасибо за поправки
С поправками выше, стало работать, переключает. Но как кратковременно менять значение выхода Start (bool) в цикле программы? При переключении выходов должен сбросится регулятор подключенный к данным выходам.
Какие еще есть варианты отключить выход на короткий промежуток времени при смене значения на входе? Возможно ли после каждого оператора If поставить условие отключения выхода, к примеру на 1 мс?
Моргнуть при изменении этапа, кратковременно выключить выход (сбросить Start).
Вообще, всё делается гораздо проще на шаговом автомате CASE, тут есть несколько примеров, везде где есть шаги или переключения режимов, только в вашем случае без таймера шагов https://owen.ru/forum/showthread.php...=9&p=429061#81
При использовании кода:
f udiSel<> udiSel_ then
Start:=false;
udiSel_:=udiSel;
else Start:=True;
end_if
Происходит сброс выхода при каждом изменении переменной udiSel. Case и If у меня дают одинаковые результаты. Как сделать сброс после этапа выполнения? Переменная udiSel меняется от 2 до 7, при этом сброс выхода делать не нужно, так как происходит регулирование в заданном диапазоне.
//область кода
xOut1 := 0;
xOut2 := 0;
xOut3 := 0;
Start := false;
CASE udiSel OF
0..1:
xOut1 := IN0_0;
xOut2 := IN0_1max;
xOut3 := D0_1;
2..7:
xOut1 := IN0_1max;
xOut2 := IN2_7max;
xOut3 := D2_7;
8..14:
xOut1 := IN2_7max;
xOut2 := IN8_14max;
xOut3 := D8_14;
END_CASE
if udiSel <> udiSel_ then
Start := false;
udiSel_:= udiSel;
else Start := True;
end_if
END_FUNCTION_BLOCK
Вложение 77972
Селектор работает, но выход не сбрасывается.
//область кода
xOut1 := 0;
xOut2 := 0;
xOut3 := 0;
//Start := false;
if (udiSel >= 0) and (udiSel <= 1) then
xOut1 := IN0_0;
xOut2 := IN0_1max;
xOut3 := D0_1;
end_if
if (udiSel<>udiSel_) and ((udiSel=0) or (udiSel=1)) then
Start := false;
udiSel_:= udiSel;
else Start := True;
udiSel_:= udiSel;
end_if
if (udiSel >= 2) and (udiSel <= 7) then
xOut1 := IN0_1max;
xOut2 := IN2_7max;
xOut3 := D2_7;
end_if
if (udiSel<>udiSel_) and ((udiSel=2) or (udiSel=7)) then
Start := false;
udiSel_:= udiSel;
else Start := True;
udiSel_:= udiSel;
end_if
if (udiSel >= 8) and (udiSel <= 14) then
xOut1 := IN2_7max;
xOut2 := IN8_14max ;
xOut3 := D2_7;
end_if
if (udiSel<>udiSel_) and ((udiSel=8) or (udiSel=14)) then
Start := false;
udiSel_:= udiSel;
else Start := True;
udiSel_:= udiSel;
end_if
end_function_block
[QUOTE=Александр_004;443640]Селектор работает, но выход не сбрасывается.
А если так
Код:var
flag : udint;
end_var
xOut1 := 0;
xOut2 := 0;
xOut3 := 0;
Start := false;
case udiSel of
0, 1:
xOut1 := IN0_0;
xOut2 := IN0_1max;
xOut3 := D0_1;
Start := true;
flag := 0;
2..7:
if flag = 1 then
xOut1 := IN0_1max;
xOut2 := IN2_7max;
xOut3 := D2_7;
Start := true;
else
flag := 1;
end_if
8..14:
if flag = 2 then
xOut1 := IN2_7max;
xOut2 := IN8_14max;
xOut3 := D8_14;
Start := true;
else
flag := 2;
end_if
end_case
end_function_block
Спасибо за помощь! Оба варианта работают
Добрый день! Как можно в OwenLogic взять текущее состояние отсчета времени в таймере TON, красным оно идет и визуално видно, но в выходах его нет?
Зачем вы в несколько тем пишите? Уже ответил вам тут https://owen.ru/forum/showthread.php...648#post444648
подумал, что не туда написа:oл
Добрый день!
Делаю проект на ПР205. Возникла потребность вывести на экранчик ПРки давление от вакуумметра в "научном" формате.
Для вычисления мантиссы и десятичного порядка решил написать ФБ на ST. Логичнее использовать функцию, но функция на ST в OWENLogic имеет только один выход, а нужно три.
Код ФБ на картинке (булевская fbstart не используется).
Вложение 78546
Ошибок не выдает, симуляция запускается. Но в режиме симуляции у ФБ не отображаются никакие значения - ни у выходов, ни у входов. Если к входу ФБ floatNum подключить отдельную входную переменную (регистр Modbus), то в симуляции OwenLogic не позволяет ввести значение этой переменной.
А все выходные переменные блока, если их добавить в окно просмотра, показывают нули.
Вложение 78543
Для проверки добавил в проект штатный ФБ "Счетчик прямого счета" из библиотеки Owen - та же картина.
Вложение 78544
С чем может быть связано такое поведение?
P.S.: Среда OWENLogic 2.7.354.0.
Здравствуйте! нигде не могу найти информацию, В OL есть возможность писать в функциональный блок(Write to FB), я написал ФБ на ST, но не могу обращаться к нему с помощью этой функции, то есть она вообще не появляется в списке ФБ, хотя на холст я его добавил, подскажите с помощью этой функции вообще возможно обратиться к блоку написанному на ST или я что то делаю не так?Вложение 78809
я хотел создать массив, для того чтобы не плодить кучу переменных, в каждый элемент которого я бы вводил время стадии, то есть для каждой стадии свой элемент массива в PT таймера, но используя write to fb , мой функциональный блок не появляется в списке, и поэтому у меня вопрос могу ли я вообще использовать write to fb, для фб на ст?